diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 1077222db55..db94b74948f 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: - node-version: [18.x, 20.x] + node-version: [20.x, 22.x] steps: - name: Checkout diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 5fe7cffe4c7..fa7cd35db68 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 22 cache: 'npm' registry-url: 'https://registry.npmjs.org' - run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e125ead772..b85ee771af2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,11 +3,23 @@ All notable changes for each version of this project will be documented in this file. ## 19.2.0 + ### General - `IgxCarousel` - Removed deprecated property `keyboardSupport`. - `IgxSlide` - **Deprecation** - `tabIndex` has been deprecated and will be removed in a future version. +- `IgxGrid`, `IgxHierarchicalGrid`, `IgxTreeGrid` + - A column's `minWidth` and `maxWidth` constrain the user-specified `width` so that it cannot go outside their bounds. + - In SSR mode grid with height 100% or with no height will render on the server with % size and with no data. The grid will show either the empty grid template or the loading indicator (if isLoading is true). + - In SSR mode grid with width 100% or with no width will render on the server with % size and with all columns. +- `IgxHierarchicalGrid` + - Introduced a new advanced filtering capability that enables top-level records to be dynamically refined based on the attributes or data of their associated child records. + - Added a new `schema` input property that can be used to pass collection of `EntityType` objects. This property is required for remote data scenarios. +- `IgxQueryBuilderComponent`, `IgxAdvancedFilteringDialogComponent` + - Added support for entities with hierarchical structure. +- `EntityType` + - A new optional property called `childEntities` has been introduced that can be used to create nested entities. ## 19.1.1 ### New Features @@ -25,7 +37,7 @@ All notable changes for each version of this project will be documented in this - Introduced a new `expanded` input property, enabling dynamic control over the banner's state. The banner can now be programmatically set to expanded (visible) or collapsed (hidden) both initially and at runtime. Animations will trigger during runtime updates — the **open animation** plays when `expanded` is set to `true`, and the **close animation** plays when set to `false`. However, no animations will trigger when the property is set initially. - The banner's event lifecycle (`opening`, `opened`, `closing`, `closed`) only triggers through **user interactions** (e.g., clicking to open/close). Programmatic updates using the `expanded` property will not fire any events. - If the `expanded` property changes during an ongoing animation, the current animation will **stop** and the opposite animation will begin from the **point where the previous animation left off**. For instance, if the open animation (10 seconds) is interrupted at 6 seconds and `expanded` is set to `false`, the close animation (5 seconds) will start from its 3rd second. -- `IgxQueryBuilder` has new design that comes with updated appearance and new functionality +- `IgxQueryBuilder` has a new design that comes with an updated appearance and new functionality - `IgxQueryBuilderComponent` - Introduced the ability to create nested queries by specifying IN/NOT IN operators. - Introduced the ability to reposition condition chips by dragging or using `Arrow Up/Down`. diff --git a/angular.json b/angular.json index 7229dd38073..2ea33070c81 100644 --- a/angular.json +++ b/angular.json @@ -399,7 +399,6 @@ ] }, "server": "projects/bundle-test/src/main.server.ts", - "prerender": true, "ssr": { "entry": "projects/bundle-test/server.ts" } diff --git a/package-lock.json b/package-lock.json index 796dc39712a..f6d891967a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,46 +9,46 @@ "version": "0.0.0", "hasInstallScript": true, "dependencies": { - "@angular/animations": "^19.1.6", - "@angular/common": "^19.1.6", - "@angular/compiler": "^19.1.6", - "@angular/core": "^19.1.6", - "@angular/elements": "^19.1.6", - "@angular/forms": "^19.1.6", - "@angular/platform-browser": "^19.1.6", - "@angular/platform-browser-dynamic": "^19.1.6", - "@angular/platform-server": "^19.1.6", - "@angular/router": "^19.1.6", - "@angular/ssr": "^19.1.7", + "@angular/animations": "^19.2.3", + "@angular/common": "^19.2.3", + "@angular/compiler": "^19.2.3", + "@angular/core": "^19.2.3", + "@angular/elements": "^19.2.3", + "@angular/forms": "^19.2.3", + "@angular/platform-browser": "^19.2.3", + "@angular/platform-browser-dynamic": "^19.2.3", + "@angular/platform-server": "^19.2.3", + "@angular/router": "^19.2.3", + "@angular/ssr": "^19.2.4", "@igniteui/material-icons-extended": "^3.1.0", - "@lit-labs/ssr-dom-shim": "^1.2.1", + "@lit-labs/ssr-dom-shim": "^1.3.0", "@types/source-map": "0.5.2", "express": "^4.21.1", "fflate": "^0.8.1", - "igniteui-theming": "^17.0.0", + "igniteui-theming": "^17.2.0", "igniteui-trial-watermark": "^3.0.2", "lodash-es": "^4.17.21", - "rxjs": "^7.8.0", + "rxjs": "^7.8.2", "tslib": "^2.3.0", "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^19.1.7", - "@angular-devkit/schematics": "^19.1.7", - "@angular-eslint/builder": "^19.1.0", - "@angular-eslint/eslint-plugin": "^19.1.0", - "@angular-eslint/eslint-plugin-template": "^19.1.0", - "@angular-eslint/schematics": "^19.1.0", - "@angular-eslint/template-parser": "^19.1.0", - "@angular/cli": "^19.1.7", - "@angular/compiler-cli": "^19.1.6", - "@angular/language-service": "^19.1.6", + "@angular-devkit/build-angular": "^19.2.4", + "@angular-devkit/schematics": "^19.2.4", + "@angular-eslint/builder": "^19.3.0", + "@angular-eslint/eslint-plugin": "^19.3.0", + "@angular-eslint/eslint-plugin-template": "^19.3.0", + "@angular-eslint/schematics": "^19.3.0", + "@angular-eslint/template-parser": "^19.3.0", + "@angular/cli": "^19.2.4", + "@angular/compiler-cli": "^19.2.3", + "@angular/language-service": "^19.2.3", "@angularclass/hmr": "^3.0.0", "@microsoft/signalr": "^7.0.12", "@types/estree": "^1.0.0", "@types/express": "^5.0.0", "@types/hammerjs": "^2.0.46", - "@types/jasmine": "^5.1.6", + "@types/jasmine": "^5.1.7", "@types/jasminewd2": "^2.0.10", "@types/node": "^20.17.6", "@types/sass-true": "^6.0.2", @@ -69,9 +69,9 @@ "hammer-simulator": "0.0.1", "hammerjs": "^2.0.8", "ig-typedoc-theme": "^6.0.0", - "igniteui-dockmanager": "^1.16.0", + "igniteui-dockmanager": "^1.16.1", "igniteui-sassdoc-theme": "^1.2.3", - "igniteui-webcomponents": "5.2.0", + "igniteui-webcomponents": "5.3.0", "jasmine": "^5.6.0", "jasmine-core": "^5.6.0", "karma": "^6.4.4", @@ -82,11 +82,11 @@ "karma-parallel": "^0.3.1", "karma-spec-reporter": "^0.0.36", "lit-html": "^3.2.1", - "ng-packagr": "^19.1.2", + "ng-packagr": "^19.2.0", "postcss": "^8.5.1", "postcss-scss": "^4.0.6", "prettier": "^3.3.3", - "puppeteer": "^24.2.1", + "puppeteer": "^24.4.0", "sass-embedded": "^1.83.4", "sass-true": "^8.1.0", "sassdoc": "^2.7.4", @@ -122,13 +122,13 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1901.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1901.7.tgz", - "integrity": "sha512-qltyebfbej7joIKZVH8EFfrVDrkw0p9N9ja3A0XeU1sl2vlepHNAQdVm0Os8Vy2XjjyHvT5bXWE3G3/221qEKw==", + "version": "0.1902.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1902.4.tgz", + "integrity": "sha512-YTLiJ7uVItZTAxRuSgASP0M5qILESWH8xGmfR+YWR1JiJem09DWEOpWeLdha1BFzUui5L+6j1btzh4FUHJOtAg==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.1.7", + "@angular-devkit/core": "19.2.4", "rxjs": "7.8.1" }, "engines": { @@ -137,29 +137,39 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular-devkit/architect/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/@angular-devkit/build-angular": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.1.7.tgz", - "integrity": "sha512-CMl3D5cpXoY0WuvdYtuOU2TetCwqxNsYM2jpuGG/kuuTEASAOI1cs9OhGwny1A/63bB8eyL33eLe82ON2Oemow==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.2.4.tgz", + "integrity": "sha512-OO8jlLY1SKUbcx3xx4LhbHcecAE9CnMrvIGMOgeKflDI7W57kYUI1lg86k/+Xm76/H2XlbsHdwLKOfFAupfl7g==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1901.7", - "@angular-devkit/build-webpack": "0.1901.7", - "@angular-devkit/core": "19.1.7", - "@angular/build": "19.1.7", - "@babel/core": "7.26.0", - "@babel/generator": "7.26.3", + "@angular-devkit/architect": "0.1902.4", + "@angular-devkit/build-webpack": "0.1902.4", + "@angular-devkit/core": "19.2.4", + "@angular/build": "19.2.4", + "@babel/core": "7.26.10", + "@babel/generator": "7.26.10", "@babel/helper-annotate-as-pure": "7.25.9", "@babel/helper-split-export-declaration": "7.24.7", - "@babel/plugin-transform-async-generator-functions": "7.25.9", + "@babel/plugin-transform-async-generator-functions": "7.26.8", "@babel/plugin-transform-async-to-generator": "7.25.9", - "@babel/plugin-transform-runtime": "7.25.9", - "@babel/preset-env": "7.26.0", - "@babel/runtime": "7.26.0", + "@babel/plugin-transform-runtime": "7.26.10", + "@babel/preset-env": "7.26.9", + "@babel/runtime": "7.26.10", "@discoveryjs/json-ext": "0.6.3", - "@ngtools/webpack": "19.1.7", + "@ngtools/webpack": "19.2.4", "@vitejs/plugin-basic-ssl": "1.2.0", "ansi-colors": "4.1.3", "autoprefixer": "10.4.20", @@ -167,13 +177,13 @@ "browserslist": "^4.21.5", "copy-webpack-plugin": "12.0.2", "css-loader": "7.1.2", - "esbuild-wasm": "0.24.2", + "esbuild-wasm": "0.25.1", "fast-glob": "3.3.3", "http-proxy-middleware": "3.0.3", "istanbul-lib-instrument": "6.0.3", "jsonc-parser": "3.3.1", "karma-source-map-support": "1.4.0", - "less": "4.2.1", + "less": "4.2.2", "less-loader": "12.2.0", "license-webpack-plugin": "4.0.2", "loader-utils": "3.3.1", @@ -182,19 +192,19 @@ "ora": "5.4.1", "picomatch": "4.0.2", "piscina": "4.8.0", - "postcss": "8.4.49", + "postcss": "8.5.2", "postcss-loader": "8.1.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.1", - "sass": "1.83.1", - "sass-loader": "16.0.4", - "semver": "7.6.3", + "sass": "1.85.0", + "sass-loader": "16.0.5", + "semver": "7.7.1", "source-map-loader": "5.0.0", "source-map-support": "0.5.21", - "terser": "5.37.0", + "terser": "5.39.0", "tree-kill": "1.2.2", "tslib": "2.8.1", - "webpack": "5.97.1", + "webpack": "5.98.0", "webpack-dev-middleware": "7.4.2", "webpack-dev-server": "5.2.0", "webpack-merge": "6.0.1", @@ -206,23 +216,23 @@ "yarn": ">= 1.13.0" }, "optionalDependencies": { - "esbuild": "0.24.2" + "esbuild": "0.25.1" }, "peerDependencies": { - "@angular/compiler-cli": "^19.0.0", - "@angular/localize": "^19.0.0", - "@angular/platform-server": "^19.0.0", - "@angular/service-worker": "^19.0.0", - "@angular/ssr": "^19.1.7", - "@web/test-runner": "^0.19.0", + "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0", + "@angular/localize": "^19.0.0 || ^19.2.0-next.0", + "@angular/platform-server": "^19.0.0 || ^19.2.0-next.0", + "@angular/service-worker": "^19.0.0 || ^19.2.0-next.0", + "@angular/ssr": "^19.2.4", + "@web/test-runner": "^0.20.0", "browser-sync": "^3.0.2", "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", "karma": "^6.3.0", - "ng-packagr": "^19.0.0", + "ng-packagr": "^19.0.0 || ^19.2.0-next.0", "protractor": "^7.0.0", "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", - "typescript": ">=5.5 <5.8" + "typescript": ">=5.5 <5.9" }, "peerDependenciesMeta": { "@angular/localize": { @@ -263,10 +273,58 @@ } } }, + "node_modules/@angular-devkit/build-angular/node_modules/@babel/core": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/@angular-devkit/build-angular/node_modules/postcss": { - "version": "8.4.49", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", - "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz", + "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==", "dev": true, "funding": [ { @@ -284,7 +342,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", + "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -292,14 +350,24 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/@angular-devkit/build-angular/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1901.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1901.7.tgz", - "integrity": "sha512-g7xPN7unBnqP9HsgFvEV1DIhNYmVwmWR9ZiSP0xJq+EjpjWlz2vmgru4a5WKwGeuLsP8vg7RKV0kCH3bunOmFA==", + "version": "0.1902.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1902.4.tgz", + "integrity": "sha512-TWZsnPMR2JvrQapO7kg4YbUgrKxu74TCYOZZrGfIA7CCIthykflWevMPGZmrTAh3mXX414P31XmoBQViXUe7iQ==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.1901.7", + "@angular-devkit/architect": "0.1902.4", "rxjs": "7.8.1" }, "engines": { @@ -312,10 +380,20 @@ "webpack-dev-server": "^5.0.2" } }, + "node_modules/@angular-devkit/build-webpack/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/@angular-devkit/core": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.1.7.tgz", - "integrity": "sha512-q0I6L9KTqyQ7D5M8H+fWLT+yjapvMNb7SRdfU6GzmexO66Dpo83q4HDzuDKIPDF29Yl0ELs9ICJqe9yUXh6yDQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.4.tgz", + "integrity": "sha512-dL6AmCQsKh+CFVvO/jxX8qZpamVwt9r4iIo7fYcAI2+mTSDGxxBGWbS+onIfdPFuRp2HgKa+AT6WiHmRqu63AA==", "dev": true, "license": "MIT", "dependencies": { @@ -340,14 +418,24 @@ } } }, + "node_modules/@angular-devkit/core/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/@angular-devkit/schematics": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.1.7.tgz", - "integrity": "sha512-AP6FvhMybCYs3gs+vzEAzSU1K//AFT3SVTRFv+C3WMO5dLeAHeGzM8I2dxD5EHQQtqIE/8apP6CxGrnpA5YlFg==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.4.tgz", + "integrity": "sha512-WaFe95ncm1A+QTlUHxQcFyGKIn67xgqGX7WCj8R0QlKOS0hLKx97SG4p19uwHlww0lmAcwk/QJP6G6sPL/CJ9w==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.1.7", + "@angular-devkit/core": "19.2.4", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "5.4.1", @@ -359,10 +447,20 @@ "yarn": ">= 1.13.0" } }, + "node_modules/@angular-devkit/schematics/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/@angular-eslint/builder": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-19.1.0.tgz", - "integrity": "sha512-LWdQMTES/7GySlpTNFJn3k33ZGmjjWlHI/+IHV7B3xHQ9hj4MPK4ACmE/PNOAIQ9LwQm7sKS+3cTMxOZQ/cvSg==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-19.3.0.tgz", + "integrity": "sha512-j9xNrzZJq29ONSG6EaeQHve0Squkm6u6Dm8fZgWP7crTFOrtLXn7Wxgxuyl9eddpbWY1Ov1gjFuwBVnxIdyAqg==", "dev": true, "license": "MIT", "dependencies": { @@ -375,21 +473,21 @@ } }, "node_modules/@angular-eslint/bundled-angular-compiler": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-19.1.0.tgz", - "integrity": "sha512-HUJyukRvnh8Z9lIdxdblBRuBaPYEVv4iAYZMw3d+dn4rrM27Nt5oh3/zkwYrrPkt36tZdeXdDWrOuz9jgjVN5w==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-19.3.0.tgz", + "integrity": "sha512-63Zci4pvnUR1iSkikFlNbShF1tO5HOarYd8fvNfmOZwFfZ/1T3j3bCy9YbE+aM5SYrWqPaPP/OcwZ3wJ8WNvqA==", "dev": true, "license": "MIT" }, "node_modules/@angular-eslint/eslint-plugin": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-19.1.0.tgz", - "integrity": "sha512-TDO0+Ry+oNkxnaLHogKp1k2aey6IkJef5d7hathE4UFT6owjRizltWaRoX6bGw7Qu1yagVLL8L2Se8SddxSPAQ==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-19.3.0.tgz", + "integrity": "sha512-nBLslLI20KnVbqlfNW7GcnI9R6cYCvRGjOE2QYhzxM316ciAQ62tvQuXP9ZVnRBLSKDAVnMeC0eTq9O4ysrxrQ==", "dev": true, "license": "MIT", "dependencies": { - "@angular-eslint/bundled-angular-compiler": "19.1.0", - "@angular-eslint/utils": "19.1.0" + "@angular-eslint/bundled-angular-compiler": "19.3.0", + "@angular-eslint/utils": "19.3.0" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", @@ -398,14 +496,14 @@ } }, "node_modules/@angular-eslint/eslint-plugin-template": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-19.1.0.tgz", - "integrity": "sha512-bIUizkCY40mnU8oAO1tLV7uN2H/cHf1evLlhpqlb9JYwc5dT2moiEhNDo61OtOgkJmDGNuThAeO9Xk9hGQc7nA==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-19.3.0.tgz", + "integrity": "sha512-WyouppTpOYut+wvv13wlqqZ8EHoDrCZxNfGKuEUYK1BPmQlTB8EIZfQH4iR1rFVS28Rw+XRIiXo1x3oC0SOfnA==", "dev": true, "license": "MIT", "dependencies": { - "@angular-eslint/bundled-angular-compiler": "19.1.0", - "@angular-eslint/utils": "19.1.0", + "@angular-eslint/bundled-angular-compiler": "19.3.0", + "@angular-eslint/utils": "19.3.0", "aria-query": "5.3.2", "axobject-query": "4.1.0" }, @@ -417,16 +515,16 @@ } }, "node_modules/@angular-eslint/schematics": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-19.1.0.tgz", - "integrity": "sha512-6S1FjmM7rZxc0u0W0KjqWYOkFQ0q89IGyjPkdUt1a8NwRnWg3VoXp4WYfeuZOjda/FEYuBS/E6rckLAMp0h6Aw==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-19.3.0.tgz", + "integrity": "sha512-Wl5sFQ4t84LUb8mJ2iVfhYFhtF55IugXu7rRhPHtgIu9Ty5s1v3HGUx4LKv51m2kWhPPeFOTmjeBv1APzFlmnQ==", "dev": true, "license": "MIT", "dependencies": { "@angular-devkit/core": ">= 19.0.0 < 20.0.0", "@angular-devkit/schematics": ">= 19.0.0 < 20.0.0", - "@angular-eslint/eslint-plugin": "19.1.0", - "@angular-eslint/eslint-plugin-template": "19.1.0", + "@angular-eslint/eslint-plugin": "19.3.0", + "@angular-eslint/eslint-plugin-template": "19.3.0", "ignore": "7.0.3", "semver": "7.7.1", "strip-json-comments": "3.1.1" @@ -442,27 +540,14 @@ "node": ">= 4" } }, - "node_modules/@angular-eslint/schematics/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@angular-eslint/template-parser": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-19.1.0.tgz", - "integrity": "sha512-wbMi7adlC+uYqZo7NHNBShpNhFJRZsXLqihqvFpAUt1Ei6uDX8HR6MyMEDZ9tUnlqtPVW5nmbedPyLVG7HkjAA==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-19.3.0.tgz", + "integrity": "sha512-VxMNgsHXMWbbmZeBuBX5i8pzsSSEaoACVpaE+j8Muk60Am4Mxc0PytJm4n3znBSvI3B7Kq2+vStSRYPkOER4lA==", "dev": true, "license": "MIT", "dependencies": { - "@angular-eslint/bundled-angular-compiler": "19.1.0", + "@angular-eslint/bundled-angular-compiler": "19.3.0", "eslint-scope": "^8.0.2" }, "peerDependencies": { @@ -471,13 +556,13 @@ } }, "node_modules/@angular-eslint/utils": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-19.1.0.tgz", - "integrity": "sha512-mcb7hPMH/u6wwUwvsewrmgb9y9NWN6ZacvpUvKlTOxF/jOtTdsu0XfV4YB43sp2A8NWzYzX0Str4c8K1xSmuBQ==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-19.3.0.tgz", + "integrity": "sha512-ovvbQh96FIJfepHqLCMdKFkPXr3EbcvYc9kMj9hZyIxs/9/VxwPH7x25mMs4VsL6rXVgH2FgG5kR38UZlcTNNw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-eslint/bundled-angular-compiler": "19.1.0" + "@angular-eslint/bundled-angular-compiler": "19.3.0" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", @@ -486,9 +571,9 @@ } }, "node_modules/@angular/animations": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.1.6.tgz", - "integrity": "sha512-iacosz3fygp0AyT57+suVpLChl10xS5RBje09TfQIKHTUY0LWkMspgaK9gwtlflpIhjedPV0UmgRIKhhFcQM1A==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.2.3.tgz", + "integrity": "sha512-HQexOmwEJFX3sHLspOCi7dVOdPW5Ad4jH6tJsf+zABkF0GjgIVf4jewe1uE5ZLKgoflr9f9vpcpy39IWl00kWw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -497,41 +582,41 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "19.1.6" + "@angular/core": "19.2.3" } }, "node_modules/@angular/build": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.1.7.tgz", - "integrity": "sha512-22SjHZDTk91JHU5aFVDU2n+xkPolDosRVfsK4zs+RRXQs30LYPH9KCLiUWCYjFbRj7oYvw7sbrs94szo7dWYvw==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.2.4.tgz", + "integrity": "sha512-poCXvmwKri3snWa9zVJ2sW7wyJatZjkwnH6GUBdJrM2dXRQ+LYLk/oXqEjlSRBYNna7P1ZcKNqBbzu0/SnnngA==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1901.7", - "@angular-devkit/core": "19.1.7", - "@babel/core": "7.26.0", + "@angular-devkit/architect": "0.1902.4", + "@babel/core": "7.26.10", "@babel/helper-annotate-as-pure": "7.25.9", "@babel/helper-split-export-declaration": "7.24.7", "@babel/plugin-syntax-import-attributes": "7.26.0", - "@inquirer/confirm": "5.1.1", + "@inquirer/confirm": "5.1.6", "@vitejs/plugin-basic-ssl": "1.2.0", "beasties": "0.2.0", "browserslist": "^4.23.0", - "esbuild": "0.24.2", + "esbuild": "0.25.1", "fast-glob": "3.3.3", "https-proxy-agent": "7.0.6", "istanbul-lib-instrument": "6.0.3", "listr2": "8.2.5", "magic-string": "0.30.17", - "mrmime": "2.0.0", + "mrmime": "2.0.1", "parse5-html-rewriting-stream": "7.0.0", "picomatch": "4.0.2", "piscina": "4.8.0", - "rollup": "4.30.1", - "sass": "1.83.1", - "semver": "7.6.3", - "vite": "6.0.11", + "rollup": "4.34.8", + "sass": "1.85.0", + "semver": "7.7.1", + "source-map-support": "0.5.21", + "vite": "6.2.0", "watchpack": "2.4.2" }, "engines": { @@ -540,20 +625,21 @@ "yarn": ">= 1.13.0" }, "optionalDependencies": { - "lmdb": "3.2.2" + "lmdb": "3.2.6" }, "peerDependencies": { - "@angular/compiler": "^19.0.0", - "@angular/compiler-cli": "^19.0.0", - "@angular/localize": "^19.0.0", - "@angular/platform-server": "^19.0.0", - "@angular/service-worker": "^19.0.0", - "@angular/ssr": "^19.1.7", + "@angular/compiler": "^19.0.0 || ^19.2.0-next.0", + "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0", + "@angular/localize": "^19.0.0 || ^19.2.0-next.0", + "@angular/platform-server": "^19.0.0 || ^19.2.0-next.0", + "@angular/service-worker": "^19.0.0 || ^19.2.0-next.0", + "@angular/ssr": "^19.2.4", + "karma": "^6.4.0", "less": "^4.2.0", - "ng-packagr": "^19.0.0", + "ng-packagr": "^19.0.0 || ^19.2.0-next.0", "postcss": "^8.4.0", "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", - "typescript": ">=5.5 <5.8" + "typescript": ">=5.5 <5.9" }, "peerDependenciesMeta": { "@angular/localize": { @@ -568,6 +654,9 @@ "@angular/ssr": { "optional": true }, + "karma": { + "optional": true + }, "less": { "optional": true }, @@ -582,16 +671,64 @@ } } }, + "node_modules/@angular/build/node_modules/@babel/core": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@angular/build/node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@angular/build/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/@angular/build/node_modules/vite": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz", - "integrity": "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz", + "integrity": "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.24.2", - "postcss": "^8.4.49", - "rollup": "^4.23.0" + "esbuild": "^0.25.0", + "postcss": "^8.5.3", + "rollup": "^4.30.1" }, "bin": { "vite": "bin/vite.js" @@ -655,27 +792,27 @@ } }, "node_modules/@angular/cli": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.1.7.tgz", - "integrity": "sha512-qVEy0R4QKQ2QAGfpj2mPVxRxgOVst+rIgZBtLwf/mrbN9YyzJUaBKvaVslUpOqkvoW9mX5myf0iZkT5NykrIoA==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.2.4.tgz", + "integrity": "sha512-YmZYrxdGBwSZsrnpS6vr9gQ8+PrZHzwyYW/3jU2NRAMtl0ZlipDyfpLIDgrfqYPeumzr7+SKtJYVvlsMnjkN4g==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.1901.7", - "@angular-devkit/core": "19.1.7", - "@angular-devkit/schematics": "19.1.7", - "@inquirer/prompts": "7.2.1", + "@angular-devkit/architect": "0.1902.4", + "@angular-devkit/core": "19.2.4", + "@angular-devkit/schematics": "19.2.4", + "@inquirer/prompts": "7.3.2", "@listr2/prompt-adapter-inquirer": "2.0.18", - "@schematics/angular": "19.1.7", + "@schematics/angular": "19.2.4", "@yarnpkg/lockfile": "1.1.0", "ini": "5.0.0", "jsonc-parser": "3.3.1", "listr2": "8.2.5", - "npm-package-arg": "12.0.1", + "npm-package-arg": "12.0.2", "npm-pick-manifest": "10.0.0", "pacote": "20.0.0", "resolve": "1.22.10", - "semver": "7.6.3", + "semver": "7.7.1", "symbol-observable": "4.0.0", "yargs": "17.7.2" }, @@ -689,9 +826,9 @@ } }, "node_modules/@angular/common": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.1.6.tgz", - "integrity": "sha512-FkuejwbxsOLhcyOgDM/7YEYvMG3tuyOvr+831VzPwMwYp5QO9AUYtn4ffGf698JccbA+Ocw3BAdhPU6i+YZC1A==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.2.3.tgz", + "integrity": "sha512-cYOMRXFb6Sjtg9BI3bE/Ave+xU234jQmHYj7hBxr3MiqRSVJL4niy10KiA/Jiz6y76V5QfZfS+0aE65VuoqAvg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -700,38 +837,30 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "19.1.6", + "@angular/core": "19.2.3", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.1.6.tgz", - "integrity": "sha512-Tl2PFEtnU8UgSqtEKG827xDUGZrErhR6S1JICeV1kbRCYmwQA4hhG25tzi+ifSAOPW7eJiyzP2LWIvOuZkq3Vw==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.2.3.tgz", + "integrity": "sha512-TL/JIU7vzSWD+IrMq2PAiHZi7IUFSRhdHo8q6/WuZ8SQmbuXCK2pJvHZpTtUdLswdPeD/UVhkhTAhQzEyEdZVg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, "engines": { "node": "^18.19.1 || ^20.11.1 || >=22.0.0" - }, - "peerDependencies": { - "@angular/core": "19.1.6" - }, - "peerDependenciesMeta": { - "@angular/core": { - "optional": true - } } }, "node_modules/@angular/compiler-cli": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.1.6.tgz", - "integrity": "sha512-rTpHC/tfLBj+5a3X+BA/4s2w5T/cHT6x3RgO8CYy7003Musn0/BiqjfE6VCIllQgLaOQRhCcf51T6Kerkzv8Dw==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.2.3.tgz", + "integrity": "sha512-ePh/7A6eEDAyfVn8QgLcAvrxhXBAf6mTqB/3+HwQeXLaka1gtN6xvZ6cjLEegP4s6kcYGhdfdLwzCcy0kjsY5g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "7.26.0", + "@babel/core": "7.26.9", "@jridgewell/sourcemap-codec": "^1.4.14", "chokidar": "^4.0.0", "convert-source-map": "^1.5.1", @@ -749,14 +878,14 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/compiler": "19.1.6", - "typescript": ">=5.5 <5.8" + "@angular/compiler": "19.2.3", + "typescript": ">=5.5 <5.9" } }, "node_modules/@angular/core": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.1.6.tgz", - "integrity": "sha512-FD167URT+apxjzj9sG/MzffW5G6YyQiPQ6nrrIoYi9jeY3LYurybuOgvcXrU8PT4Z3+CKMq9k/ZnmrlHU72BpA==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.2.3.tgz", + "integrity": "sha512-uNDbQBDWdAfL8JhgG2l9eTEbikovZ+SthLUKERyR4fL7AVGSx85LjNySRuq4WAL4eiD1cRN1UUgu8o+WKqF/ow==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -770,9 +899,9 @@ } }, "node_modules/@angular/elements": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/elements/-/elements-19.1.6.tgz", - "integrity": "sha512-w91zaktvx/5AWPVUrbVJ29brX2O+4otnnlHZimahd2S1f6VVDv5K5pTRte1Mij+MDqjw8GBX/ok0+tc5B3yqKA==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/elements/-/elements-19.2.3.tgz", + "integrity": "sha512-ua0d79r3z5xc4a8k0eHN9Y1acsIOIYXzCaRnqfainBmXZ5CecBUhG1uoJ3xcpxNV5PxQugZLkqZrEvXqAqLhbA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -781,14 +910,14 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "19.1.6", + "@angular/core": "19.2.3", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/forms": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.1.6.tgz", - "integrity": "sha512-uu/76KAwCAcDuhD67Vv78UvOC/tiprtFXOgqNCj0LK8vyFcvPsunb3nF/PtfF9rSHyslXAqxZhME+Ha2tU6Lpw==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.2.3.tgz", + "integrity": "sha512-JEgNKiZd3taYBg9lsMvoana5cv1QGke8xkuryc9zesHPJjhw9QHllmDPOW2HyUuwPqXZ/YkHiuCMOk+4qPjsAw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -797,16 +926,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "19.1.6", - "@angular/core": "19.1.6", - "@angular/platform-browser": "19.1.6", + "@angular/common": "19.2.3", + "@angular/core": "19.2.3", + "@angular/platform-browser": "19.2.3", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/language-service": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-19.1.6.tgz", - "integrity": "sha512-YIvCQRt+EFUKmms8M9K0ULDxAkCQSJqmnx4lGDJDHNK13U/C6r0d3/WMrrSDuSjax4zGSJf5xiRPpQlzPPsphA==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-19.2.3.tgz", + "integrity": "sha512-qq54VhRTk8jxnqXN6Q4wK1W7ewSkD0kdhii0Sif25gbkNvfDfqd1PjtnojelG81sN8XhBeMBcDhtbmEQX4nqHg==", "dev": true, "license": "MIT", "engines": { @@ -814,9 +943,9 @@ } }, "node_modules/@angular/platform-browser": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.1.6.tgz", - "integrity": "sha512-sfWU+gMpqQ6GYtE3tAfDktftC01NgtqAOKfeCQ/KY2rxRTIxYahenW0Licuzgmd+8AZtmncoZaYX0Fd/5XMqzQ==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.2.3.tgz", + "integrity": "sha512-bz5mvUkCS8SxaMInjPgi/2dD7vpWkZePQesvr/bBRNQbYSE4cGTbovXcVl3X5hIxs5JoC6Het0lS2IxDq7j6qg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -825,9 +954,9 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/animations": "19.1.6", - "@angular/common": "19.1.6", - "@angular/core": "19.1.6" + "@angular/animations": "19.2.3", + "@angular/common": "19.2.3", + "@angular/core": "19.2.3" }, "peerDependenciesMeta": { "@angular/animations": { @@ -836,9 +965,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.1.6.tgz", - "integrity": "sha512-QedjG7/ctPtzgJ3LcWv4yMcSivKlwcZ8ge8zPe7eu9Ft6mDZZat65gJEjDuvevJoeNbo2dQODFDiyPJNmnNA9A==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.2.3.tgz", + "integrity": "sha512-PHmmtdGxSfe9HL8xR4g3PspnEaPqTEOGyzNviAHugfkZCgXCdSbYs36d3i0nPwhExMAeuIVXbbJyouDn2kyeOw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -847,16 +976,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "19.1.6", - "@angular/compiler": "19.1.6", - "@angular/core": "19.1.6", - "@angular/platform-browser": "19.1.6" + "@angular/common": "19.2.3", + "@angular/compiler": "19.2.3", + "@angular/core": "19.2.3", + "@angular/platform-browser": "19.2.3" } }, "node_modules/@angular/platform-server": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-19.1.6.tgz", - "integrity": "sha512-yCFkByyHDtxXZaaaRV+268WN8s45ie+R5bcJ9oPKYE3Td0f/7iTRUatDfTI8h7/xbYK4nRgGZmxuiREpjt6y6Q==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-19.2.3.tgz", + "integrity": "sha512-04Wv3N1+We3E0+TcZP4x1KtHSiSx2cNrQVuC0FGftfvAZiSr8DtYye6ji7zxTGGRg5uKBwVAUvTEAbT56FNm8Q==", "license": "MIT", "dependencies": { "tslib": "^2.3.0", @@ -866,17 +995,17 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/animations": "19.1.6", - "@angular/common": "19.1.6", - "@angular/compiler": "19.1.6", - "@angular/core": "19.1.6", - "@angular/platform-browser": "19.1.6" + "@angular/common": "19.2.3", + "@angular/compiler": "19.2.3", + "@angular/core": "19.2.3", + "@angular/platform-browser": "19.2.3", + "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/router": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.1.6.tgz", - "integrity": "sha512-TEfw3W5jVodVDMD4krhXGog1THZN3x1yoh2oZmCv3lXg22+pVC6Cp+x3vVExq0mS+g3/6uZwy/3qAYdlzqYjTg==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.2.3.tgz", + "integrity": "sha512-yYVMT7CceKqE+fBXxkhkAqEQUEdY/BHtLQr1vP9rEnAf30vwKghDEresugfegY6Ch4IGKTBtDG/QGmxWszgUAQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -885,25 +1014,25 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "19.1.6", - "@angular/core": "19.1.6", - "@angular/platform-browser": "19.1.6", + "@angular/common": "19.2.3", + "@angular/core": "19.2.3", + "@angular/platform-browser": "19.2.3", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/ssr": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-19.1.7.tgz", - "integrity": "sha512-MNjjSWNv1K0E1K/U/pRgFo54n/1qyaFcYGYKSbnpwAGjtiCiHLudL3Dycke3mHTmcPFX61DniX1MdJtLhhFsVA==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-19.2.4.tgz", + "integrity": "sha512-3yG8YkCyMRt+z3ZICLJvq1GMmBGtNEWGnR/FyOrJ+VAT5WSgUbDA4MsTjUPdHlVbtg52J+NcXq+sw8GOXJwY+g==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { - "@angular/common": "^19.0.0", - "@angular/core": "^19.0.0", - "@angular/platform-server": "^19.0.0", - "@angular/router": "^19.0.0" + "@angular/common": "^19.0.0 || ^19.2.0-next.0", + "@angular/core": "^19.0.0 || ^19.2.0-next.0", + "@angular/platform-server": "^19.0.0 || ^19.2.0-next.0", + "@angular/router": "^19.0.0 || ^19.2.0-next.0" }, "peerDependenciesMeta": { "@angular/platform-server": { @@ -933,9 +1062,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", - "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", "dev": true, "license": "MIT", "engines": { @@ -943,22 +1072,22 @@ } }, "node_modules/@babel/core": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", - "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", + "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.0", - "@babel/generator": "^7.26.0", - "@babel/helper-compilation-targets": "^7.25.9", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.9", + "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.0", - "@babel/parser": "^7.26.0", - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.26.0", + "@babel/helpers": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.9", + "@babel/types": "^7.26.9", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -989,14 +1118,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", - "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz", + "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.3", - "@babel/types": "^7.26.3", + "@babel/parser": "^7.26.10", + "@babel/types": "^7.26.10", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -1010,6 +1139,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.25.9" }, @@ -1017,27 +1147,14 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz", - "integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", - "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.9", + "@babel/compat-data": "^7.26.5", "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -1058,17 +1175,18 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", - "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.26.9.tgz", + "integrity": "sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-member-expression-to-functions": "^7.25.9", "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-replace-supers": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/traverse": "^7.25.9", + "@babel/traverse": "^7.26.9", "semver": "^6.3.1" }, "engines": { @@ -1083,18 +1201,20 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz", - "integrity": "sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", - "regexpu-core": "^6.1.1", + "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "engines": { @@ -1109,15 +1229,17 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", - "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz", + "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -1134,6 +1256,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" @@ -1179,6 +1302,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.25.9" }, @@ -1187,10 +1311,11 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", - "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -1200,6 +1325,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-wrap-function": "^7.25.9", @@ -1213,14 +1339,15 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", - "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-member-expression-to-functions": "^7.25.9", "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/traverse": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1229,24 +1356,12 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz", - "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" @@ -1303,6 +1418,7 @@ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.25.9", "@babel/traverse": "^7.25.9", @@ -1313,27 +1429,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", - "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", + "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.0" + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.5.tgz", - "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", + "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.5" + "@babel/types": "^7.26.10" }, "bin": { "parser": "bin/babel-parser.js" @@ -1347,6 +1463,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/traverse": "^7.25.9" @@ -1363,6 +1480,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1378,6 +1496,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1393,6 +1512,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", @@ -1410,6 +1530,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/traverse": "^7.25.9" @@ -1426,6 +1547,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" }, @@ -1438,6 +1560,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1453,6 +1576,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1468,6 +1592,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1484,6 +1609,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1495,14 +1621,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", - "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz", + "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-remap-async-to-generator": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/traverse": "^7.26.8" }, "engines": { "node": ">=6.9.0" @@ -1516,6 +1643,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", @@ -1529,12 +1657,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", - "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", + "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1548,6 +1677,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1563,6 +1693,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -1579,6 +1710,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -1595,6 +1727,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-compilation-targets": "^7.25.9", @@ -1615,6 +1748,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/template": "^7.25.9" @@ -1631,6 +1765,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1646,6 +1781,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -1662,6 +1798,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1677,6 +1814,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -1693,6 +1831,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1704,12 +1843,12 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz", - "integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { @@ -1724,6 +1863,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1735,12 +1875,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", - "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.26.9.tgz", + "integrity": "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { @@ -1755,6 +1896,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", @@ -1772,6 +1914,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1787,6 +1930,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1802,6 +1946,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1817,6 +1962,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1832,6 +1978,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -1844,14 +1991,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz", - "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==", + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-simple-access": "^7.25.9" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1865,6 +2012,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", @@ -1883,6 +2031,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -1899,6 +2048,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -1915,6 +2065,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1926,12 +2077,13 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", - "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", + "version": "7.26.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz", + "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1945,6 +2097,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1960,6 +2113,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", @@ -1977,6 +2131,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-replace-supers": "^7.25.9" @@ -1993,6 +2148,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -2008,6 +2164,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" @@ -2024,6 +2181,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -2039,6 +2197,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -2055,6 +2214,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-create-class-features-plugin": "^7.25.9", @@ -2072,6 +2232,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -2087,6 +2248,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" @@ -2103,6 +2265,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -2119,6 +2282,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -2130,15 +2294,16 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", - "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.10.tgz", + "integrity": "sha512-NWaL2qG6HRpONTnj4JvDU6th4jYeZOJgu3QhmFTCihib0ermtOJqktA5BduGm3suhhVe9EMP9c9+mfJ/I9slqw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-corejs3": "^0.11.0", "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, @@ -2154,6 +2319,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -2163,6 +2329,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -2178,6 +2345,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" @@ -2194,6 +2362,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -2205,12 +2374,13 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", - "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz", + "integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -2220,12 +2390,13 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", - "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.26.7.tgz", + "integrity": "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -2239,6 +2410,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -2254,6 +2426,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -2270,6 +2443,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -2286,6 +2460,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" @@ -2298,14 +2473,15 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", - "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz", + "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.26.0", - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", + "@babel/compat-data": "^7.26.8", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-validator-option": "^7.25.9", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", @@ -2317,9 +2493,9 @@ "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.25.9", - "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.26.8", "@babel/plugin-transform-async-to-generator": "^7.25.9", - "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.26.5", "@babel/plugin-transform-block-scoping": "^7.25.9", "@babel/plugin-transform-class-properties": "^7.25.9", "@babel/plugin-transform-class-static-block": "^7.26.0", @@ -2330,21 +2506,21 @@ "@babel/plugin-transform-duplicate-keys": "^7.25.9", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", "@babel/plugin-transform-dynamic-import": "^7.25.9", - "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.26.3", "@babel/plugin-transform-export-namespace-from": "^7.25.9", - "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.26.9", "@babel/plugin-transform-function-name": "^7.25.9", "@babel/plugin-transform-json-strings": "^7.25.9", "@babel/plugin-transform-literals": "^7.25.9", "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", "@babel/plugin-transform-member-expression-literals": "^7.25.9", "@babel/plugin-transform-modules-amd": "^7.25.9", - "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.26.3", "@babel/plugin-transform-modules-systemjs": "^7.25.9", "@babel/plugin-transform-modules-umd": "^7.25.9", "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", "@babel/plugin-transform-new-target": "^7.25.9", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6", "@babel/plugin-transform-numeric-separator": "^7.25.9", "@babel/plugin-transform-object-rest-spread": "^7.25.9", "@babel/plugin-transform-object-super": "^7.25.9", @@ -2360,17 +2536,17 @@ "@babel/plugin-transform-shorthand-properties": "^7.25.9", "@babel/plugin-transform-spread": "^7.25.9", "@babel/plugin-transform-sticky-regex": "^7.25.9", - "@babel/plugin-transform-template-literals": "^7.25.9", - "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.26.8", + "@babel/plugin-transform-typeof-symbol": "^7.26.7", "@babel/plugin-transform-unicode-escapes": "^7.25.9", "@babel/plugin-transform-unicode-property-regex": "^7.25.9", "@babel/plugin-transform-unicode-regex": "^7.25.9", "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-corejs3": "^0.11.0", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.38.1", + "core-js-compat": "^3.40.0", "semver": "^6.3.1" }, "engines": { @@ -2385,6 +2561,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -2394,6 +2571,7 @@ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", @@ -2404,10 +2582,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", - "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", + "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", "dev": true, + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2416,32 +2595,32 @@ } }, "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", - "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.10.tgz", + "integrity": "sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/generator": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/template": "^7.25.9", - "@babel/types": "^7.25.9", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.10", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2450,9 +2629,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz", - "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", + "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2611,9 +2790,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", - "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", + "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", "cpu": [ "ppc64" ], @@ -2628,9 +2807,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", - "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", + "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", "cpu": [ "arm" ], @@ -2645,9 +2824,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", - "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", + "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", "cpu": [ "arm64" ], @@ -2662,9 +2841,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", - "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", + "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", "cpu": [ "x64" ], @@ -2679,9 +2858,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", - "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", + "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", "cpu": [ "arm64" ], @@ -2696,9 +2875,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", - "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", + "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", "cpu": [ "x64" ], @@ -2713,9 +2892,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", - "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", + "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", "cpu": [ "arm64" ], @@ -2730,9 +2909,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", - "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", + "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", "cpu": [ "x64" ], @@ -2747,9 +2926,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", - "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", + "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", "cpu": [ "arm" ], @@ -2764,9 +2943,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", - "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", + "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", "cpu": [ "arm64" ], @@ -2781,9 +2960,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", - "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", + "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", "cpu": [ "ia32" ], @@ -2798,9 +2977,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", - "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", + "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", "cpu": [ "loong64" ], @@ -2815,9 +2994,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", - "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", + "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", "cpu": [ "mips64el" ], @@ -2832,9 +3011,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", - "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", + "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", "cpu": [ "ppc64" ], @@ -2849,9 +3028,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", - "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", + "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", "cpu": [ "riscv64" ], @@ -2866,9 +3045,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", - "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", + "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", "cpu": [ "s390x" ], @@ -2883,9 +3062,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", - "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", + "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", "cpu": [ "x64" ], @@ -2900,9 +3079,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", - "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", + "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", "cpu": [ "arm64" ], @@ -2917,9 +3096,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", - "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", + "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", "cpu": [ "x64" ], @@ -2934,9 +3113,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", - "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", + "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", "cpu": [ "arm64" ], @@ -2951,9 +3130,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", - "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", + "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", "cpu": [ "x64" ], @@ -2968,9 +3147,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", - "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", + "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", "cpu": [ "x64" ], @@ -2985,9 +3164,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", - "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", + "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", "cpu": [ "arm64" ], @@ -3002,9 +3181,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", - "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", + "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", "cpu": [ "ia32" ], @@ -3019,9 +3198,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", - "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", + "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", "cpu": [ "x64" ], @@ -3344,15 +3523,15 @@ "license": "MIT" }, "node_modules/@inquirer/checkbox": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.6.tgz", - "integrity": "sha512-PgP35JfmGjHU0LSXOyRew0zHuA9N6OJwOlos1fZ20b7j8ISeAdib3L+n0jIxBtX958UeEpte6xhG/gxJ5iUqMw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.4.tgz", + "integrity": "sha512-d30576EZdApjAMceijXA5jDzRQHT/MygbC+J8I7EqA6f/FRpYxlRtRJbHF8gHeWYeSdOuTEJqonn7QLB1ELezA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.4", - "@inquirer/figures": "^1.0.9", - "@inquirer/type": "^3.0.2", + "@inquirer/core": "^10.1.9", + "@inquirer/figures": "^1.0.11", + "@inquirer/type": "^3.0.5", "ansi-escapes": "^4.3.2", "yoctocolors-cjs": "^2.1.2" }, @@ -3361,44 +3540,61 @@ }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/confirm": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.1.tgz", - "integrity": "sha512-vVLSbGci+IKQvDOtzpPTCOiEJCNidHcAq9JYVoWTW0svb5FiwSLotkM+JXNXejfjnzVYV9n0DTBythl9+XgTxg==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.6.tgz", + "integrity": "sha512-6ZXYK3M1XmaVBZX6FCfChgtponnL0R6I7k8Nu+kaoNkT828FVZTcca1MqmWQipaW2oNREQl5AaPCUOOCVNdRMw==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.2", - "@inquirer/type": "^3.0.2" + "@inquirer/core": "^10.1.7", + "@inquirer/type": "^3.0.4" }, "engines": { "node": ">=18" }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/core": { - "version": "10.1.4", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.4.tgz", - "integrity": "sha512-5y4/PUJVnRb4bwWY67KLdebWOhOc7xj5IP2J80oWXa64mVag24rwQ1VAdnj7/eDY/odhguW0zQ1Mp1pj6fO/2w==", + "version": "10.1.9", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.9.tgz", + "integrity": "sha512-sXhVB8n20NYkUBfDYgizGHlpRVaCRjtuzNZA6xpALIUbkgfd2Hjz+DfEN6+h1BRnuxw0/P4jCIMjMsEOAMwAJw==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/figures": "^1.0.9", - "@inquirer/type": "^3.0.2", + "@inquirer/figures": "^1.0.11", + "@inquirer/type": "^3.0.5", "ansi-escapes": "^4.3.2", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", - "strip-ansi": "^6.0.1", "wrap-ansi": "^6.2.0", "yoctocolors-cjs": "^2.1.2" }, "engines": { "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/core/node_modules/signal-exit": { @@ -3415,14 +3611,14 @@ } }, "node_modules/@inquirer/editor": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.3.tgz", - "integrity": "sha512-S9KnIOJuTZpb9upeRSBBhoDZv7aSV3pG9TECrBj0f+ZsFwccz886hzKBrChGrXMJwd4NKY+pOA9Vy72uqnd6Eg==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.9.tgz", + "integrity": "sha512-8HjOppAxO7O4wV1ETUlJFg6NDjp/W2NP5FB9ZPAcinAlNT4ZIWOLe2pUVwmmPRSV0NMdI5r/+lflN55AwZOKSw==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.4", - "@inquirer/type": "^3.0.2", + "@inquirer/core": "^10.1.9", + "@inquirer/type": "^3.0.5", "external-editor": "^3.1.0" }, "engines": { @@ -3430,17 +3626,22 @@ }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/expand": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.6.tgz", - "integrity": "sha512-TRTfi1mv1GeIZGyi9PQmvAaH65ZlG4/FACq6wSzs7Vvf1z5dnNWsAAXBjWMHt76l+1hUY8teIqJFrWBk5N6gsg==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.11.tgz", + "integrity": "sha512-OZSUW4hFMW2TYvX/Sv+NnOZgO8CHT2TU1roUCUIF2T+wfw60XFRRp9MRUPCT06cRnKL+aemt2YmTWwt7rOrNEA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.4", - "@inquirer/type": "^3.0.2", + "@inquirer/core": "^10.1.9", + "@inquirer/type": "^3.0.5", "yoctocolors-cjs": "^2.1.2" }, "engines": { @@ -3448,12 +3649,17 @@ }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/figures": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.9.tgz", - "integrity": "sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.11.tgz", + "integrity": "sha512-eOg92lvrn/aRUqbxRyvpEWnrvRuTYRifixHkYVpJiygTgVSBIHDqLh0SrMQXkafvULg3ck11V7xvR+zcgvpHFw==", "dev": true, "license": "MIT", "engines": { @@ -3461,48 +3667,58 @@ } }, "node_modules/@inquirer/input": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.3.tgz", - "integrity": "sha512-zeo++6f7hxaEe7OjtMzdGZPHiawsfmCZxWB9X1NpmYgbeoyerIbWemvlBxxl+sQIlHC0WuSAG19ibMq3gbhaqQ==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.8.tgz", + "integrity": "sha512-WXJI16oOZ3/LiENCAxe8joniNp8MQxF6Wi5V+EBbVA0ZIOpFcL4I9e7f7cXse0HJeIPCWO8Lcgnk98juItCi7Q==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.4", - "@inquirer/type": "^3.0.2" + "@inquirer/core": "^10.1.9", + "@inquirer/type": "^3.0.5" }, "engines": { "node": ">=18" }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/number": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.6.tgz", - "integrity": "sha512-xO07lftUHk1rs1gR0KbqB+LJPhkUNkyzV/KhH+937hdkMazmAYHLm1OIrNKpPelppeV1FgWrgFDjdUD8mM+XUg==", + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.11.tgz", + "integrity": "sha512-pQK68CsKOgwvU2eA53AG/4npRTH2pvs/pZ2bFvzpBhrznh8Mcwt19c+nMO7LHRr3Vreu1KPhNBF3vQAKrjIulw==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.4", - "@inquirer/type": "^3.0.2" + "@inquirer/core": "^10.1.9", + "@inquirer/type": "^3.0.5" }, "engines": { "node": ">=18" }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/password": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.6.tgz", - "integrity": "sha512-QLF0HmMpHZPPMp10WGXh6F+ZPvzWE7LX6rNoccdktv/Rov0B+0f+eyXkAcgqy5cH9V+WSpbLxu2lo3ysEVK91w==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.11.tgz", + "integrity": "sha512-dH6zLdv+HEv1nBs96Case6eppkRggMe8LoOTl30+Gq5Wf27AO/vHFgStTVz4aoevLdNXqwE23++IXGw4eiOXTg==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.4", - "@inquirer/type": "^3.0.2", + "@inquirer/core": "^10.1.9", + "@inquirer/type": "^3.0.5", "ansi-escapes": "^4.3.2" }, "engines": { @@ -3510,42 +3726,52 @@ }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/prompts": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.2.1.tgz", - "integrity": "sha512-v2JSGri6/HXSfoGIwuKEn8sNCQK6nsB2BNpy2lSX6QH9bsECrMv93QHnj5+f+1ZWpF/VNioIV2B/PDox8EvGuQ==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.3.2.tgz", + "integrity": "sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/checkbox": "^4.0.4", - "@inquirer/confirm": "^5.1.1", - "@inquirer/editor": "^4.2.1", - "@inquirer/expand": "^4.0.4", - "@inquirer/input": "^4.1.1", - "@inquirer/number": "^3.0.4", - "@inquirer/password": "^4.0.4", - "@inquirer/rawlist": "^4.0.4", - "@inquirer/search": "^3.0.4", - "@inquirer/select": "^4.0.4" + "@inquirer/checkbox": "^4.1.2", + "@inquirer/confirm": "^5.1.6", + "@inquirer/editor": "^4.2.7", + "@inquirer/expand": "^4.0.9", + "@inquirer/input": "^4.1.6", + "@inquirer/number": "^3.0.9", + "@inquirer/password": "^4.0.9", + "@inquirer/rawlist": "^4.0.9", + "@inquirer/search": "^3.0.9", + "@inquirer/select": "^4.0.9" }, "engines": { "node": ">=18" }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/rawlist": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.6.tgz", - "integrity": "sha512-QoE4s1SsIPx27FO4L1b1mUjVcoHm1pWE/oCmm4z/Hl+V1Aw5IXl8FYYzGmfXaBT0l/sWr49XmNSiq7kg3Kd/Lg==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.11.tgz", + "integrity": "sha512-uAYtTx0IF/PqUAvsRrF3xvnxJV516wmR6YVONOmCWJbbt87HcDHLfL9wmBQFbNJRv5kCjdYKrZcavDkH3sVJPg==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.4", - "@inquirer/type": "^3.0.2", + "@inquirer/core": "^10.1.9", + "@inquirer/type": "^3.0.5", "yoctocolors-cjs": "^2.1.2" }, "engines": { @@ -3553,18 +3779,23 @@ }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/search": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.6.tgz", - "integrity": "sha512-eFZ2hiAq0bZcFPuFFBmZEtXU1EarHLigE+ENCtpO+37NHCl4+Yokq1P/d09kUblObaikwfo97w+0FtG/EXl5Ng==", + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.11.tgz", + "integrity": "sha512-9CWQT0ikYcg6Ls3TOa7jljsD7PgjcsYEM0bYE+Gkz+uoW9u8eaJCRHJKkucpRE5+xKtaaDbrND+nPDoxzjYyew==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.4", - "@inquirer/figures": "^1.0.9", - "@inquirer/type": "^3.0.2", + "@inquirer/core": "^10.1.9", + "@inquirer/figures": "^1.0.11", + "@inquirer/type": "^3.0.5", "yoctocolors-cjs": "^2.1.2" }, "engines": { @@ -3572,18 +3803,23 @@ }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/select": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.6.tgz", - "integrity": "sha512-yANzIiNZ8fhMm4NORm+a74+KFYHmf7BZphSOBovIzYPVLquseTGEkU5l2UTnBOf5k0VLmTgPighNDLE9QtbViQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.1.0.tgz", + "integrity": "sha512-z0a2fmgTSRN+YBuiK1ROfJ2Nvrpij5lVN3gPDkQGhavdvIVGHGW29LwYZfM/j42Ai2hUghTI/uoBuTbrJk42bA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.4", - "@inquirer/figures": "^1.0.9", - "@inquirer/type": "^3.0.2", + "@inquirer/core": "^10.1.9", + "@inquirer/figures": "^1.0.11", + "@inquirer/type": "^3.0.5", "ansi-escapes": "^4.3.2", "yoctocolors-cjs": "^2.1.2" }, @@ -3592,12 +3828,17 @@ }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@inquirer/type": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.2.tgz", - "integrity": "sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.5.tgz", + "integrity": "sha512-ZJpeIYYueOz/i/ONzrfof8g89kNdO2hjGuvULROo3O8rlB2CRtSseE5KeirnyE4t/thAn/EwvS/vuQeJCn+NZg==", "dev": true, "license": "MIT", "engines": { @@ -3605,6 +3846,11 @@ }, "peerDependencies": { "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@isaacs/cliui": { @@ -3814,9 +4060,9 @@ } }, "node_modules/@jsonjoy.com/json-pack": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", - "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.2.0.tgz", + "integrity": "sha512-io1zEbbYcElht3tdlqEOFxZ0dMTYrHz9iMf0gqn1pPjZFTCgM5R4R5IMA20Chb2UPYYsxjzs8CgZ7Nb5n2K2rA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3897,18 +4143,19 @@ } }, "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", - "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz", + "integrity": "sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==", "license": "BSD-3-Clause" }, "node_modules/@lit-labs/virtualizer": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@lit-labs/virtualizer/-/virtualizer-2.0.13.tgz", - "integrity": "sha512-OKojbIFohfrRpWd3OxcVSc2nyTd0jx10ZSQobuOW9H9jYkad02OJ1uFvV/sHJey8hoh95FIO4d43h+Ry/G4nGw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@lit-labs/virtualizer/-/virtualizer-2.1.0.tgz", + "integrity": "sha512-I79sNaalK9rD6FWO/AoxBMnA6jjNBrQu7F6lzz8W/GkQLcqveMWK3IrJAilso+XeFFn7BvlxBv6FqZaoMt+Qkg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "lit": "^3.1.0", + "lit": "^3.2.0", "tslib": "^2.0.3" } }, @@ -3917,30 +4164,33 @@ "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@lit-labs/ssr-dom-shim": "^1.2.0" } }, "node_modules/@lit-labs/virtualizer/node_modules/lit": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.1.4.tgz", - "integrity": "sha512-q6qKnKXHy2g1kjBaNfcoLlgbI3+aSOZ9Q4tiGa9bGYXq5RBXxkVTqTIVmP2VWMp29L4GyvCFm8ZQ2o56eUAMyA==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz", + "integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@lit/reactive-element": "^2.0.4", - "lit-element": "^4.0.4", - "lit-html": "^3.1.2" + "lit-element": "^4.1.0", + "lit-html": "^3.2.0" } }, "node_modules/@lit-labs/virtualizer/node_modules/lit-element": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.0.6.tgz", - "integrity": "sha512-U4sdJ3CSQip7sLGZ/uJskO5hGiqtlpxndsLr6mt3IQIjheg93UKYeGQjWMRql1s/cXNOaRrCzC2FQwjIwSUqkg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.1.tgz", + "integrity": "sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@lit-labs/ssr-dom-shim": "^1.2.0", "@lit/reactive-element": "^2.0.4", - "lit-html": "^3.1.2" + "lit-html": "^3.2.0" } }, "node_modules/@lit/context": { @@ -3962,9 +4212,9 @@ } }, "node_modules/@lmdb/lmdb-darwin-arm64": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.2.2.tgz", - "integrity": "sha512-WBSJT9Z7DTol5viq+DZD2TapeWOw7mlwXxiSBHgAzqVwsaVb0h/ekMD9iu/jDD8MUA20tO9N0WEdnT06fsUp+g==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.2.6.tgz", + "integrity": "sha512-yF/ih9EJJZc72psFQbwnn8mExIWfTnzWJg+N02hnpXtDPETYLmQswIMBn7+V88lfCaFrMozJsUvcEQIkEPU0Gg==", "cpu": [ "arm64" ], @@ -3976,9 +4226,9 @@ ] }, "node_modules/@lmdb/lmdb-darwin-x64": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.2.2.tgz", - "integrity": "sha512-4S13kUtR7c/j/MzkTIBJCXv52hQ41LG2ukeaqw4Eng9K0pNKLFjo1sDSz96/yKhwykxrWDb13ddJ/ZqD3rAhUA==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.2.6.tgz", + "integrity": "sha512-5BbCumsFLbCi586Bb1lTWQFkekdQUw8/t8cy++Uq251cl3hbDIGEwD9HAwh8H6IS2F6QA9KdKmO136LmipRNkg==", "cpu": [ "x64" ], @@ -3990,9 +4240,9 @@ ] }, "node_modules/@lmdb/lmdb-linux-arm": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.2.2.tgz", - "integrity": "sha512-uW31JmfuPAaLUYW7NsEU8gzwgDAzpGPwjvkxnKlcWd8iDutoPKDJi8Wk9lFmPEZRxVSB0j1/wDQ7N2qliR9UFA==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.2.6.tgz", + "integrity": "sha512-+6XgLpMb7HBoWxXj+bLbiiB4s0mRRcDPElnRS3LpWRzdYSe+gFk5MT/4RrVNqd2MESUDmb53NUXw1+BP69bjiQ==", "cpu": [ "arm" ], @@ -4004,9 +4254,9 @@ ] }, "node_modules/@lmdb/lmdb-linux-arm64": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.2.2.tgz", - "integrity": "sha512-4hdgZtWI1idQlWRp+eleWXD9KLvObgboRaVoBj2POdPEYvsKANllvMW0El8tEQwtw74yB9NT6P8ENBB5UJf5+g==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.2.6.tgz", + "integrity": "sha512-l5VmJamJ3nyMmeD1ANBQCQqy7do1ESaJQfKPSm2IG9/ADZryptTyCj8N6QaYgIWewqNUrcbdMkJajRQAt5Qjfg==", "cpu": [ "arm64" ], @@ -4018,9 +4268,9 @@ ] }, "node_modules/@lmdb/lmdb-linux-x64": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.2.2.tgz", - "integrity": "sha512-A0zjf4a2vM4B4GAx78ncuOTZ8Ka1DbTaG1Axf1e00Sa7f5coqlWiLg1PX7Gxvyibc2YqtqB+8tg1KKrE8guZVw==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.2.6.tgz", + "integrity": "sha512-nDYT8qN9si5+onHYYaI4DiauDMx24OAiuZAUsEqrDy+ja/3EbpXPX/VAkMV8AEaQhy3xc4dRC+KcYIvOFefJ4Q==", "cpu": [ "x64" ], @@ -4032,9 +4282,9 @@ ] }, "node_modules/@lmdb/lmdb-win32-x64": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.2.2.tgz", - "integrity": "sha512-Y0qoSCAja+xZE7QQ0LCHoYAuyI1n9ZqukQJa8lv9X3yCvWahFF7OYHAgVH1ejp43XWstj3U89/PAAzcowgF/uQ==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.2.6.tgz", + "integrity": "sha512-XlqVtILonQnG+9fH2N3Aytria7P/1fwDgDhl29rde96uH2sLB8CHORIf2PfuLVzFQJ7Uqp8py9AYwr3ZUCFfWg==", "cpu": [ "x64" ], @@ -4431,9 +4681,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.1.7.tgz", - "integrity": "sha512-U39LVqHWj+GtKzBA3+AseHZgLPlL5YE/iRkZJ4PHQVrgW9LtyMzPuUmnW+e0XQwPFHq9xQxaoj3w8gApj4/MIg==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.2.4.tgz", + "integrity": "sha512-I2vG9Yb0W/PR5+quBmSUk6uGa4xN/YvfJk+30bFDB/CpJlTQEo+3AOFCDYcDOxrbtjON80VdFYPypQ5ztbpdYw==", "dev": true, "license": "MIT", "engines": { @@ -4442,8 +4692,8 @@ "yarn": ">= 1.13.0" }, "peerDependencies": { - "@angular/compiler-cli": "^19.0.0", - "typescript": ">=5.5 <5.8", + "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0", + "typescript": ">=5.5 <5.9", "webpack": "^5.54.0" } }, @@ -5042,9 +5292,9 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.7.1.tgz", - "integrity": "sha512-MK7rtm8JjaxPN7Mf1JdZIZKPD2Z+W7osvrC1vjpvfOX1K0awDIHYbNi89f7eotp7eMUn2shWnt03HwVbriXtKQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.8.0.tgz", + "integrity": "sha512-yTwt2KWRmCQAfhvbCRjebaSX8pV1//I0Y3g+A7f/eS7gf0l4eRJoUCvcYdVtboeU4CTOZQuqYbZNS8aBYb8ROQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -5052,7 +5302,7 @@ "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.5.0", - "semver": "^7.7.0", + "semver": "^7.7.1", "tar-fs": "^3.0.8", "yargs": "^17.7.2" }, @@ -5081,19 +5331,6 @@ } } }, - "node_modules/@puppeteer/browsers/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@rollup/plugin-json": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", @@ -5137,9 +5374,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", - "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", + "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", "cpu": [ "arm" ], @@ -5151,9 +5388,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz", - "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", + "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", "cpu": [ "arm64" ], @@ -5165,9 +5402,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz", - "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", + "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", "cpu": [ "arm64" ], @@ -5179,9 +5416,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz", - "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", + "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", "cpu": [ "x64" ], @@ -5193,9 +5430,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz", - "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", + "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", "cpu": [ "arm64" ], @@ -5207,9 +5444,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz", - "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", + "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", "cpu": [ "x64" ], @@ -5221,9 +5458,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz", - "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", + "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", "cpu": [ "arm" ], @@ -5235,9 +5472,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz", - "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", + "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", "cpu": [ "arm" ], @@ -5249,9 +5486,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz", - "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", + "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", "cpu": [ "arm64" ], @@ -5263,9 +5500,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz", - "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", + "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", "cpu": [ "arm64" ], @@ -5277,9 +5514,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz", - "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", + "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", "cpu": [ "loong64" ], @@ -5291,9 +5528,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz", - "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", + "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", "cpu": [ "ppc64" ], @@ -5305,9 +5542,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz", - "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", + "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", "cpu": [ "riscv64" ], @@ -5319,9 +5556,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz", - "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", + "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", "cpu": [ "s390x" ], @@ -5333,9 +5570,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz", - "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", + "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", "cpu": [ "x64" ], @@ -5347,9 +5584,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz", - "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", + "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", "cpu": [ "x64" ], @@ -5361,9 +5598,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz", - "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", + "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", "cpu": [ "arm64" ], @@ -5375,9 +5612,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz", - "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", + "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", "cpu": [ "ia32" ], @@ -5389,9 +5626,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz", - "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", + "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", "cpu": [ "x64" ], @@ -5422,14 +5659,14 @@ } }, "node_modules/@schematics/angular": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.1.7.tgz", - "integrity": "sha512-BB8yMGmYDZzSb8Nu+Ln0TKyeoS3++f9STCYw30NwM3IViHxJJYxu/zowzwSa9TjftIzdCpbOaPxGS0vU9UOUDQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.2.4.tgz", + "integrity": "sha512-P7fphIPbqHHYRVRPiFl7RAHYPYhINGSUYOXrcThVBBsgKQBX18oNdUWvhZA6ylwK/9T21XB20VyLjNy0d78H1Q==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.1.7", - "@angular-devkit/schematics": "19.1.7", + "@angular-devkit/core": "19.2.4", + "@angular-devkit/schematics": "19.2.4", "jsonc-parser": "3.3.1" }, "engines": { @@ -5992,9 +6229,9 @@ } }, "node_modules/@types/jasmine": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.6.tgz", - "integrity": "sha512-JDwKwipGFDwf021BtRTuluYe1aMDNimtO72ygPrVXnZSC8Df2V22AHeIgGa84tbF4SLkRvN+dJnlV8aMwQjkVw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.7.tgz", + "integrity": "sha512-DVOfk9FaClQfNFpSfaML15jjB5cjffDMvjtph525sroR5BEAW2uKnTOYUTqTFuZFjNvH0T5XMIydvIctnUKufw==", "dev": true, "license": "MIT" }, @@ -6133,9 +6370,9 @@ "dev": true }, "node_modules/@types/ws": { - "version": "8.5.14", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz", - "integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw==", "dev": true, "license": "MIT", "dependencies": { @@ -7121,13 +7358,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.12", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", - "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz", + "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.3", + "@babel/helper-define-polyfill-provider": "^0.6.4", "semver": "^6.3.1" }, "peerDependencies": { @@ -7139,30 +7377,33 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", - "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", + "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2", - "core-js-compat": "^3.38.0" + "@babel/helper-define-polyfill-provider": "^0.6.3", + "core-js-compat": "^3.40.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", - "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz", + "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.3" + "@babel/helper-define-polyfill-provider": "^0.6.4" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -7241,14 +7482,14 @@ } }, "node_modules/bare-os": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.4.0.tgz", - "integrity": "sha512-9Ous7UlnKbe3fMi7Y+qh0DwAup6A1JkYgPnjvMDNOlmnxNRQvQ/7Nst+OnUQKzk0iAT0m9BisbDVp9gCv8+ETA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.0.tgz", + "integrity": "sha512-BUrFS5TqSBdA0LwHop4OjPJwisqxGy6JsWVqV6qaFoe965qqtaKfDzHY5T2YA1gUL0ZeeQeA+4BBc1FJTcHiPw==", "dev": true, "license": "Apache-2.0", "optional": true, "engines": { - "bare": ">=1.6.0" + "bare": ">=1.14.0" } }, "node_modules/bare-path": { @@ -7578,9 +7819,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "dev": true, "funding": [ { @@ -7598,9 +7839,9 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { @@ -7920,9 +8161,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001677", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", - "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", + "version": "1.0.30001706", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001706.tgz", + "integrity": "sha512-3ZczoTApMAZwPKYWmwVbQMFpXBDds3/0VciVoUwPUbldlYyVLmRVuRs/PcUZtHpbLRpzzDvrvnFuREsGt6lUug==", "dev": true, "funding": [ { @@ -8026,9 +8267,9 @@ } }, "node_modules/chromium-bidi": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-1.3.0.tgz", - "integrity": "sha512-G3x1bkST13kmbL7+dT/oRkNH/7C4UqG+0YQpmySrzXspyOhYgDNc6lhSGpj3cuexvH25WTENhTYq2Tt9JRXtbw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-2.1.2.tgz", + "integrity": "sha512-vtRWBK2uImo5/W2oG6/cDkkHSm+2t6VHgnj+Rcwhb0pP74OoUb4GipyRX/T/y39gYQPhioP0DPShn+A7P6CHNw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -8848,12 +9089,13 @@ "hasInstallScript": true }, "node_modules/core-js-compat": { - "version": "3.39.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", - "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz", + "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==", "dev": true, + "license": "MIT", "dependencies": { - "browserslist": "^4.24.2" + "browserslist": "^4.24.4" }, "funding": { "type": "opencollective", @@ -9378,9 +9620,9 @@ "license": "MIT" }, "node_modules/devtools-protocol": { - "version": "0.0.1402036", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1402036.tgz", - "integrity": "sha512-JwAYQgEvm3yD45CHB+RmF5kMbWtXBaOGwuxa87sZogHcLCv8c/IqnThaoQ1y60d7pXWjSKWQphPEc+1rAScVdg==", + "version": "0.0.1413902", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1413902.tgz", + "integrity": "sha512-yRtvFD8Oyk7C9Os3GmnFZLu53yAfsnyw1s+mLmHHUK0GQEc9zthHWvS1r67Zqzm5t7v56PILHIVZ7kmFMaL2yQ==", "dev": true, "license": "BSD-3-Clause" }, @@ -9578,9 +9820,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.5.50", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz", - "integrity": "sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==", + "version": "1.5.120", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.120.tgz", + "integrity": "sha512-oTUp3gfX1gZI+xfD2djr2rzQdHCwHzPQrrK0CD7WpTdF0nPdQ/INcRVjWgLdCT4a9W3jFObR9DAfsuyFQnI8CQ==", "dev": true, "license": "ISC" }, @@ -9833,9 +10075,9 @@ "dev": true }, "node_modules/esbuild": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", - "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", + "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -9846,37 +10088,37 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.24.2", - "@esbuild/android-arm": "0.24.2", - "@esbuild/android-arm64": "0.24.2", - "@esbuild/android-x64": "0.24.2", - "@esbuild/darwin-arm64": "0.24.2", - "@esbuild/darwin-x64": "0.24.2", - "@esbuild/freebsd-arm64": "0.24.2", - "@esbuild/freebsd-x64": "0.24.2", - "@esbuild/linux-arm": "0.24.2", - "@esbuild/linux-arm64": "0.24.2", - "@esbuild/linux-ia32": "0.24.2", - "@esbuild/linux-loong64": "0.24.2", - "@esbuild/linux-mips64el": "0.24.2", - "@esbuild/linux-ppc64": "0.24.2", - "@esbuild/linux-riscv64": "0.24.2", - "@esbuild/linux-s390x": "0.24.2", - "@esbuild/linux-x64": "0.24.2", - "@esbuild/netbsd-arm64": "0.24.2", - "@esbuild/netbsd-x64": "0.24.2", - "@esbuild/openbsd-arm64": "0.24.2", - "@esbuild/openbsd-x64": "0.24.2", - "@esbuild/sunos-x64": "0.24.2", - "@esbuild/win32-arm64": "0.24.2", - "@esbuild/win32-ia32": "0.24.2", - "@esbuild/win32-x64": "0.24.2" + "@esbuild/aix-ppc64": "0.25.1", + "@esbuild/android-arm": "0.25.1", + "@esbuild/android-arm64": "0.25.1", + "@esbuild/android-x64": "0.25.1", + "@esbuild/darwin-arm64": "0.25.1", + "@esbuild/darwin-x64": "0.25.1", + "@esbuild/freebsd-arm64": "0.25.1", + "@esbuild/freebsd-x64": "0.25.1", + "@esbuild/linux-arm": "0.25.1", + "@esbuild/linux-arm64": "0.25.1", + "@esbuild/linux-ia32": "0.25.1", + "@esbuild/linux-loong64": "0.25.1", + "@esbuild/linux-mips64el": "0.25.1", + "@esbuild/linux-ppc64": "0.25.1", + "@esbuild/linux-riscv64": "0.25.1", + "@esbuild/linux-s390x": "0.25.1", + "@esbuild/linux-x64": "0.25.1", + "@esbuild/netbsd-arm64": "0.25.1", + "@esbuild/netbsd-x64": "0.25.1", + "@esbuild/openbsd-arm64": "0.25.1", + "@esbuild/openbsd-x64": "0.25.1", + "@esbuild/sunos-x64": "0.25.1", + "@esbuild/win32-arm64": "0.25.1", + "@esbuild/win32-ia32": "0.25.1", + "@esbuild/win32-x64": "0.25.1" } }, "node_modules/esbuild-wasm": { - "version": "0.24.2", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.24.2.tgz", - "integrity": "sha512-03/7Z1gD+ohDnScFztvI4XddTAbKVmMEzCvvkBpQdWKEXJ+73dTyeNrmdxP1Q0zpDMFjzUJwtK4rLjqwiHbzkw==", + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.1.tgz", + "integrity": "sha512-dZxPeDHcDIQ6ilml/NzYxnPbNkoVsHSFH3JGLSobttc5qYYgExMo8lh2XcB+w+AfiqykVDGK5PWanGB0gWaAWw==", "dev": true, "license": "MIT", "bin": { @@ -12486,9 +12728,9 @@ } }, "node_modules/igniteui-dockmanager": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/igniteui-dockmanager/-/igniteui-dockmanager-1.16.0.tgz", - "integrity": "sha512-MJj9UvqVUu6wx5mSr4xUnfFbZU9z0isUjIx5MJJt6XEQY+d7KYHyGCq4X7ahUBWAWd8KM3++KnDEA7/qJ4qNIg==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/igniteui-dockmanager/-/igniteui-dockmanager-1.16.1.tgz", + "integrity": "sha512-4sZUTe7kaN5D25wbGDcUOR+m2bseP4LjCZWCKz6h7osbUqdXRPCeXdh2MA9OVUimYXBCaeDVtENLbBAqRXpAiQ==", "dev": true, "license": "SEE LICENSE IN LICENSE", "dependencies": { @@ -12518,9 +12760,9 @@ } }, "node_modules/igniteui-theming": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/igniteui-theming/-/igniteui-theming-17.0.0.tgz", - "integrity": "sha512-ktxEk5Xgq2k1Lv+A54W+MtFtlo4Jdtg2L59Pk9zJGx56upjzxuqSHJXdbnTCnbPZmx4xPYxdWkpVKylk47GPQA==", + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/igniteui-theming/-/igniteui-theming-17.2.0.tgz", + "integrity": "sha512-i2zMlims6zjWd8aWJsimtDtgqRe9O2i7aH/85wf+Es5x2aSkGZsE2/OLrDb0GMXt2ISIsvjVnb1P46hZYiH+BQ==", "license": "MIT", "peerDependencies": { "sass": "^1.69.5" @@ -12535,14 +12777,14 @@ } }, "node_modules/igniteui-webcomponents": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/igniteui-webcomponents/-/igniteui-webcomponents-5.2.0.tgz", - "integrity": "sha512-VFvWW1ceonjkLLUcXm2T7CKLfm1e77SmXE2nf4RgeIqFoVIF2W0t+PhKw4zMOfq2iJxSpnbBhMbfRna0wGWLvA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/igniteui-webcomponents/-/igniteui-webcomponents-5.3.0.tgz", + "integrity": "sha512-K5PPwfT2ECp/W3+mNapt1HW6PRIQK7DkehK4SbsCc513LwTzBL1gfHYax0Hk3eiPJP2M/8ANBJ3yDZdRy6YzXQ==", "dev": true, "license": "SEE LICENSE IN LICENSE", "dependencies": { "@floating-ui/dom": "^1.6.0", - "@lit-labs/virtualizer": "^2.0.10", + "@lit-labs/virtualizer": "^2.1.0", "@lit/context": "^1.1.0", "lit": "^3.2.0" }, @@ -13550,6 +13792,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -13564,6 +13807,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -13573,6 +13817,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -14156,9 +14401,9 @@ } }, "node_modules/less": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/less/-/less-4.2.1.tgz", - "integrity": "sha512-CasaJidTIhWmjcqv0Uj5vccMI7pJgfD9lMkKtlnTHAdJdYK/7l8pM9tumLyJ0zhbD4KJLo/YvTj+xznQd5NBhg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/less/-/less-4.2.2.tgz", + "integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -14471,9 +14716,9 @@ } }, "node_modules/lmdb": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.2.2.tgz", - "integrity": "sha512-LriG93la4PbmPMwI7Hbv8W+0ncLK7549w4sbZSi4QGDjnnxnmNMgxUkaQTEMzH8TpwsfFvgEjpLX7V8B/I9e3g==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.2.6.tgz", + "integrity": "sha512-SuHqzPl7mYStna8WRotY8XX/EUZBjjv3QyKIByeCLFfC9uXT/OIHByEcA07PzbMfQAM0KYJtLgtpMRlIe5dErQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -14489,12 +14734,12 @@ "download-lmdb-prebuilds": "bin/download-prebuilds.js" }, "optionalDependencies": { - "@lmdb/lmdb-darwin-arm64": "3.2.2", - "@lmdb/lmdb-darwin-x64": "3.2.2", - "@lmdb/lmdb-linux-arm": "3.2.2", - "@lmdb/lmdb-linux-arm64": "3.2.2", - "@lmdb/lmdb-linux-x64": "3.2.2", - "@lmdb/lmdb-win32-x64": "3.2.2" + "@lmdb/lmdb-darwin-arm64": "3.2.6", + "@lmdb/lmdb-darwin-x64": "3.2.6", + "@lmdb/lmdb-linux-arm": "3.2.6", + "@lmdb/lmdb-linux-arm64": "3.2.6", + "@lmdb/lmdb-linux-x64": "3.2.6", + "@lmdb/lmdb-win32-x64": "3.2.6" } }, "node_modules/loader-runner": { @@ -14669,7 +14914,8 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.defaults": { "version": "4.2.0", @@ -15397,7 +15643,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", @@ -15743,9 +15990,9 @@ } }, "node_modules/mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "dev": true, "license": "MIT", "engines": { @@ -15923,9 +16170,9 @@ } }, "node_modules/ng-packagr": { - "version": "19.1.2", - "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-19.1.2.tgz", - "integrity": "sha512-h8YDp6YdPwAwbl7rs0lJE7vVugobY6m+JogS0hQ7P+52RmslPT8kRCgdvGLIS1JySwPrDFQkPh2PLBaSjwcRqQ==", + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-19.2.0.tgz", + "integrity": "sha512-bDyB9tmXMCL/4IhKcX84zGQlQrZhPhdCaomdJocz6EN57cZWdTP7SGhrswzpdGJY+y89855detet27oJLgR3IQ==", "dev": true, "license": "MIT", "dependencies": { @@ -15938,7 +16185,7 @@ "commander": "^13.0.0", "convert-source-map": "^2.0.0", "dependency-graph": "^1.0.0", - "esbuild": "^0.24.0", + "esbuild": "^0.25.0", "fast-glob": "^3.3.2", "find-cache-dir": "^3.3.2", "injection-js": "^2.4.0", @@ -15963,7 +16210,7 @@ "@angular/compiler-cli": "^19.0.0 || ^19.1.0-next.0 || ^19.2.0-next.0", "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", "tslib": "^2.3.0", - "typescript": ">=5.5 <5.8" + "typescript": ">=5.5 <5.9" }, "peerDependenciesMeta": { "tailwindcss": { @@ -16247,9 +16494,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true, "license": "MIT" }, @@ -16352,9 +16599,9 @@ } }, "node_modules/npm-package-arg": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.1.tgz", - "integrity": "sha512-aDxjFfPV3Liw0WOBWlyZLMBqtbgbg03rmGvHDJa2Ttv7tIz+1oB5qWec4psCDFZcZi9b5XdGkPdQiJxOPzvQRQ==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz", + "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==", "dev": true, "license": "ISC", "dependencies": { @@ -16928,9 +17175,9 @@ } }, "node_modules/pac-proxy-agent": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz", - "integrity": "sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", "dev": true, "license": "MIT", "dependencies": { @@ -17425,9 +17672,9 @@ } }, "node_modules/postcss": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", - "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "dev": true, "funding": [ { @@ -17872,18 +18119,18 @@ } }, "node_modules/puppeteer": { - "version": "24.2.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.2.1.tgz", - "integrity": "sha512-Euno62ou0cd0dTkOYTNioSOsFF4VpSnz4ldD38hi9ov9xCNtr8DbhmoJRUx+V9OuPgecueZbKOohRrnrhkbg3Q==", + "version": "24.4.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.4.0.tgz", + "integrity": "sha512-E4JhJzjS8AAI+6N/b+Utwarhz6zWl3+MR725fal+s3UlOlX2eWdsvYYU+Q5bXMjs9eZEGkNQroLkn7j11s2k1Q==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.7.1", - "chromium-bidi": "1.3.0", + "@puppeteer/browsers": "2.8.0", + "chromium-bidi": "2.1.2", "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1402036", - "puppeteer-core": "24.2.1", + "devtools-protocol": "0.0.1413902", + "puppeteer-core": "24.4.0", "typed-query-selector": "^2.12.0" }, "bin": { @@ -17894,18 +18141,18 @@ } }, "node_modules/puppeteer-core": { - "version": "24.2.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.2.1.tgz", - "integrity": "sha512-bCypUh3WXzETafv1TCFAjIUnI8BiQ/d+XvEfEXDLcIMm9CAvROqnBmbt79yBjwasoDZsgfXnUmIJU7Y27AalVQ==", + "version": "24.4.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.4.0.tgz", + "integrity": "sha512-eFw66gCnWo0X8Hyf9KxxJtms7a61NJVMiSaWfItsFPzFBsjsWdmcNlBdsA1WVwln6neoHhsG+uTVesKmTREn/g==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.7.1", - "chromium-bidi": "1.3.0", + "@puppeteer/browsers": "2.8.0", + "chromium-bidi": "2.1.2", "debug": "^4.4.0", - "devtools-protocol": "0.0.1402036", + "devtools-protocol": "0.0.1413902", "typed-query-selector": "^2.12.0", - "ws": "^8.18.0" + "ws": "^8.18.1" }, "engines": { "node": ">=18" @@ -17930,9 +18177,9 @@ } }, "node_modules/puppeteer-core/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", "dev": true, "license": "MIT", "engines": { @@ -18143,13 +18390,15 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regenerate-unicode-properties": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "dev": true, + "license": "MIT", "dependencies": { "regenerate": "^1.4.2" }, @@ -18161,13 +18410,15 @@ "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regenerator-transform": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.4" } @@ -18179,15 +18430,16 @@ "dev": true }, "node_modules/regexpu-core": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.1.1.tgz", - "integrity": "sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "dev": true, + "license": "MIT", "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.0", "regjsgen": "^0.8.0", - "regjsparser": "^0.11.0", + "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -18223,13 +18475,15 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regjsparser": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.2.tgz", - "integrity": "sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "jsesc": "~3.0.2" }, @@ -18522,9 +18776,9 @@ } }, "node_modules/rollup": { - "version": "4.30.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz", - "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", + "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", "dev": true, "license": "MIT", "dependencies": { @@ -18538,25 +18792,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.30.1", - "@rollup/rollup-android-arm64": "4.30.1", - "@rollup/rollup-darwin-arm64": "4.30.1", - "@rollup/rollup-darwin-x64": "4.30.1", - "@rollup/rollup-freebsd-arm64": "4.30.1", - "@rollup/rollup-freebsd-x64": "4.30.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.30.1", - "@rollup/rollup-linux-arm-musleabihf": "4.30.1", - "@rollup/rollup-linux-arm64-gnu": "4.30.1", - "@rollup/rollup-linux-arm64-musl": "4.30.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.30.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1", - "@rollup/rollup-linux-riscv64-gnu": "4.30.1", - "@rollup/rollup-linux-s390x-gnu": "4.30.1", - "@rollup/rollup-linux-x64-gnu": "4.30.1", - "@rollup/rollup-linux-x64-musl": "4.30.1", - "@rollup/rollup-win32-arm64-msvc": "4.30.1", - "@rollup/rollup-win32-ia32-msvc": "4.30.1", - "@rollup/rollup-win32-x64-msvc": "4.30.1", + "@rollup/rollup-android-arm-eabi": "4.34.8", + "@rollup/rollup-android-arm64": "4.34.8", + "@rollup/rollup-darwin-arm64": "4.34.8", + "@rollup/rollup-darwin-x64": "4.34.8", + "@rollup/rollup-freebsd-arm64": "4.34.8", + "@rollup/rollup-freebsd-x64": "4.34.8", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", + "@rollup/rollup-linux-arm-musleabihf": "4.34.8", + "@rollup/rollup-linux-arm64-gnu": "4.34.8", + "@rollup/rollup-linux-arm64-musl": "4.34.8", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", + "@rollup/rollup-linux-riscv64-gnu": "4.34.8", + "@rollup/rollup-linux-s390x-gnu": "4.34.8", + "@rollup/rollup-linux-x64-gnu": "4.34.8", + "@rollup/rollup-linux-x64-musl": "4.34.8", + "@rollup/rollup-win32-arm64-msvc": "4.34.8", + "@rollup/rollup-win32-ia32-msvc": "4.34.8", + "@rollup/rollup-win32-x64-msvc": "4.34.8", "fsevents": "~2.3.2" } }, @@ -18597,9 +18851,10 @@ } }, "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } @@ -18696,9 +18951,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sass": { - "version": "1.83.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.1.tgz", - "integrity": "sha512-EVJbDaEs4Rr3F0glJzFSOvtg2/oy2V/YrGFPqPY24UqcLDWcI9ZY5sN+qyO3c/QCZwzgfirvhXvINiJCE/OLcA==", + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.85.0.tgz", + "integrity": "sha512-3ToiC1xZ1Y8aU7+CkgCI/tqyuPXEmYGJXO7H4uqp0xkLXUqp88rQQ4j1HmP37xSJLbCJPaIiv+cT1y+grssrww==", "license": "MIT", "dependencies": { "chokidar": "^4.0.0", @@ -19178,9 +19433,9 @@ } }, "node_modules/sass-loader": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.4.tgz", - "integrity": "sha512-LavLbgbBGUt3wCiYzhuLLu65+fWXaXLmq7YxivLhEqmiupCFZ5sKUAipK3do6V80YSU0jvSxNhEdT13IXNr3rg==", + "version": "16.0.5", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.5.tgz", + "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==", "dev": true, "license": "MIT", "dependencies": { @@ -19683,10 +19938,11 @@ "optional": true }, "node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -19694,7 +19950,7 @@ "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 10.13.0" }, "funding": { "type": "opencollective", @@ -19749,9 +20005,9 @@ } }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, "license": "ISC", "bin": { @@ -21235,9 +21491,9 @@ } }, "node_modules/terser": { - "version": "5.37.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", - "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -21254,16 +21510,17 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.20", + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.26.0" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" @@ -21287,55 +21544,6 @@ } } }, - "node_modules/terser-webpack-plugin/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -21929,6 +22137,7 @@ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -21938,6 +22147,7 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, + "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -21951,6 +22161,7 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -21960,6 +22171,7 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -22558,15 +22770,15 @@ } }, "node_modules/vite": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz", - "integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.3.tgz", + "integrity": "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "esbuild": "^0.24.2", - "postcss": "^8.5.1", + "esbuild": "^0.25.0", + "postcss": "^8.5.3", "rollup": "^4.30.1" }, "bin": { @@ -22687,9 +22899,9 @@ "dev": true }, "node_modules/webpack": { - "version": "5.97.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", - "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", + "version": "5.98.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz", + "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", "dev": true, "license": "MIT", "dependencies": { @@ -22711,9 +22923,9 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", + "schema-utils": "^4.3.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", + "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, @@ -22933,9 +23145,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", "dev": true, "license": "MIT", "engines": { @@ -22999,31 +23211,6 @@ } } }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -23052,30 +23239,6 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "node_modules/webpack/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", diff --git a/package.json b/package.json index 3d284c001b2..f73e2620f3a 100644 --- a/package.json +++ b/package.json @@ -58,46 +58,46 @@ }, "private": true, "dependencies": { - "@angular/animations": "^19.1.6", - "@angular/common": "^19.1.6", - "@angular/compiler": "^19.1.6", - "@angular/core": "^19.1.6", - "@angular/elements": "^19.1.6", - "@angular/forms": "^19.1.6", - "@angular/platform-browser": "^19.1.6", - "@angular/platform-browser-dynamic": "^19.1.6", - "@angular/platform-server": "^19.1.6", - "@angular/router": "^19.1.6", - "@angular/ssr": "^19.1.7", + "@angular/animations": "^19.2.3", + "@angular/common": "^19.2.3", + "@angular/compiler": "^19.2.3", + "@angular/core": "^19.2.3", + "@angular/elements": "^19.2.3", + "@angular/forms": "^19.2.3", + "@angular/platform-browser": "^19.2.3", + "@angular/platform-browser-dynamic": "^19.2.3", + "@angular/platform-server": "^19.2.3", + "@angular/router": "^19.2.3", + "@angular/ssr": "^19.2.4", "@igniteui/material-icons-extended": "^3.1.0", - "@lit-labs/ssr-dom-shim": "^1.2.1", + "@lit-labs/ssr-dom-shim": "^1.3.0", "@types/source-map": "0.5.2", "express": "^4.21.1", "fflate": "^0.8.1", - "igniteui-theming": "^17.0.0", + "igniteui-theming": "^17.2.0", "igniteui-trial-watermark": "^3.0.2", "lodash-es": "^4.17.21", - "rxjs": "^7.8.0", + "rxjs": "^7.8.2", "tslib": "^2.3.0", "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^19.1.7", - "@angular-devkit/schematics": "^19.1.7", - "@angular-eslint/builder": "^19.1.0", - "@angular-eslint/eslint-plugin": "^19.1.0", - "@angular-eslint/eslint-plugin-template": "^19.1.0", - "@angular-eslint/schematics": "^19.1.0", - "@angular-eslint/template-parser": "^19.1.0", - "@angular/cli": "^19.1.7", - "@angular/compiler-cli": "^19.1.6", - "@angular/language-service": "^19.1.6", + "@angular-devkit/build-angular": "^19.2.4", + "@angular-devkit/schematics": "^19.2.4", + "@angular-eslint/builder": "^19.3.0", + "@angular-eslint/eslint-plugin": "^19.3.0", + "@angular-eslint/eslint-plugin-template": "^19.3.0", + "@angular-eslint/schematics": "^19.3.0", + "@angular-eslint/template-parser": "^19.3.0", + "@angular/cli": "^19.2.4", + "@angular/compiler-cli": "^19.2.3", + "@angular/language-service": "^19.2.3", "@angularclass/hmr": "^3.0.0", "@microsoft/signalr": "^7.0.12", "@types/estree": "^1.0.0", "@types/express": "^5.0.0", "@types/hammerjs": "^2.0.46", - "@types/jasmine": "^5.1.6", + "@types/jasmine": "^5.1.7", "@types/jasminewd2": "^2.0.10", "@types/node": "^20.17.6", "@types/sass-true": "^6.0.2", @@ -118,9 +118,9 @@ "hammer-simulator": "0.0.1", "hammerjs": "^2.0.8", "ig-typedoc-theme": "^6.0.0", - "igniteui-dockmanager": "^1.16.0", + "igniteui-dockmanager": "^1.16.1", "igniteui-sassdoc-theme": "^1.2.3", - "igniteui-webcomponents": "5.2.0", + "igniteui-webcomponents": "5.3.0", "jasmine": "^5.6.0", "jasmine-core": "^5.6.0", "karma": "^6.4.4", @@ -131,11 +131,11 @@ "karma-parallel": "^0.3.1", "karma-spec-reporter": "^0.0.36", "lit-html": "^3.2.1", - "ng-packagr": "^19.1.2", + "ng-packagr": "^19.2.0", "postcss": "^8.5.1", "postcss-scss": "^4.0.6", "prettier": "^3.3.3", - "puppeteer": "^24.2.1", + "puppeteer": "^24.4.0", "sass-embedded": "^1.83.4", "sass-true": "^8.1.0", "sassdoc": "^2.7.4", diff --git a/projects/bundle-test/server.ts b/projects/bundle-test/server.ts index 918e2249166..854bab7e381 100644 --- a/projects/bundle-test/server.ts +++ b/projects/bundle-test/server.ts @@ -1,56 +1,66 @@ -import { APP_BASE_HREF } from '@angular/common'; -import { CommonEngine } from '@angular/ssr/node'; -import express from 'express'; -import { fileURLToPath } from 'node:url'; -import { dirname, join, resolve } from 'node:path'; -import bootstrap from './src/main.server'; +import { + AngularNodeAppEngine, + createNodeRequestHandler, + isMainModule, + writeResponseToNodeResponse, + } from '@angular/ssr/node'; + import express from 'express'; + import { dirname, resolve } from 'node:path'; + import { fileURLToPath } from 'node:url'; -// 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(); + const app = express(); + const angularApp = new AngularNodeAppEngine(); - server.set('view engine', 'html'); - server.set('views', browserDistFolder); + /** + * Example Express Rest API endpoints can be defined here. + * Uncomment and define endpoints as necessary. + * + * Example: + * ```ts + * app.get('/api/**', (req, res) => { + * // Handle API request + * }); + * ``` + */ - // Example Express Rest API endpoints - // server.get('/api/**', (req, res) => { }); - // Serve static files from /browser - server.get('*.*', express.static(browserDistFolder, { - maxAge: '1y' - })); + /** + * Serve static files from /browser + */ + app.use( + express.static(browserDistFolder, { + maxAge: '1y', + index: false, + redirect: false, + }), + ); - // 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)); + /** + * Handle all other requests by rendering the Angular application. + */ + app.use('/**', (req, res, next) => { + angularApp + .handle(req) + .then((response) => + response ? writeResponseToNodeResponse(response, res) : next(), + ) + .catch(next); }); - 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}`); - }); -} + /** + * Start the server if this module is the main entry point. + * The server listens on the port defined by the `PORT` environment variable, or defaults to 4000. + */ + if (isMainModule(import.meta.url)) { + const port = process.env['PORT'] || 4000; + app.listen(port, () => { + console.log(`Node Express server listening on http://localhost:${port}`); + }); + } -run(); + /** + * The request handler used by the Angular CLI (dev-server and during build). + */ + export const reqHandler = createNodeRequestHandler(app); diff --git a/projects/bundle-test/src/app/app.config.server.ts b/projects/bundle-test/src/app/app.config.server.ts index b4d57c94235..012518913ee 100644 --- a/projects/bundle-test/src/app/app.config.server.ts +++ b/projects/bundle-test/src/app/app.config.server.ts @@ -1,10 +1,13 @@ import { mergeApplicationConfig, ApplicationConfig } from '@angular/core'; import { provideServerRendering } from '@angular/platform-server'; +import { provideServerRouting } from '@angular/ssr'; import { appConfig } from './app.config'; +import { serverRoutes } from './app.routes.server'; const serverConfig: ApplicationConfig = { providers: [ - provideServerRendering() + provideServerRendering(), + provideServerRouting(serverRoutes) ] }; diff --git a/projects/bundle-test/src/app/app.routes.server.ts b/projects/bundle-test/src/app/app.routes.server.ts new file mode 100644 index 00000000000..ffd37b1f233 --- /dev/null +++ b/projects/bundle-test/src/app/app.routes.server.ts @@ -0,0 +1,8 @@ +import { RenderMode, ServerRoute } from '@angular/ssr'; + +export const serverRoutes: ServerRoute[] = [ + { + path: '**', + renderMode: RenderMode.Prerender + } +]; diff --git a/projects/bundle-test/src/app/form/form.component.ts b/projects/bundle-test/src/app/form/form.component.ts index f6c51fbb2fc..3308b98c1f8 100644 --- a/projects/bundle-test/src/app/form/form.component.ts +++ b/projects/bundle-test/src/app/form/form.component.ts @@ -1,10 +1,23 @@ import { Component } from '@angular/core'; import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; -import { IGX_INPUT_GROUP_DIRECTIVES, IGX_RADIO_GROUP_DIRECTIVES, IgxButtonDirective, IgxCheckboxComponent, IgxSwitchComponent } from 'igniteui-angular'; +import { + IGX_INPUT_GROUP_DIRECTIVES, + IGX_RADIO_GROUP_DIRECTIVES, + IgxButtonDirective, + IgxCheckboxComponent, + IgxSwitchComponent +} from 'igniteui-angular'; @Component({ selector: 'app-form', - imports: [IgxCheckboxComponent, IgxSwitchComponent, IGX_RADIO_GROUP_DIRECTIVES, IgxButtonDirective, IGX_INPUT_GROUP_DIRECTIVES, ReactiveFormsModule], + imports: [ + IgxCheckboxComponent, + IgxSwitchComponent, + IGX_RADIO_GROUP_DIRECTIVES, + IgxButtonDirective, + IGX_INPUT_GROUP_DIRECTIVES, + ReactiveFormsModule + ], templateUrl: './form.component.html', styleUrls: ['./form.component.scss'] }) diff --git a/projects/igniteui-angular-elements/src/analyzer/elements.config.ts b/projects/igniteui-angular-elements/src/analyzer/elements.config.ts index 6056d49ce84..0eb64660797 100644 --- a/projects/igniteui-angular-elements/src/analyzer/elements.config.ts +++ b/projects/igniteui-angular-elements/src/analyzer/elements.config.ts @@ -7,20 +7,20 @@ import { } from "../../../igniteui-angular/src/public_api"; import { IgxPaginatorComponent } from "../../../igniteui-angular/src/lib/paginator/paginator.component"; import { IgxPaginatorToken } from "../../../igniteui-angular/src/lib/paginator/token"; -import { IgxActionStripComponent } from "../../../igniteui-angular/src/lib/action-strip/action-strip.component"; -import { IgxActionStripToken } from "../../../igniteui-angular/src/lib/action-strip/token"; -import { IgxGridEditingActionsComponent } from "../../../igniteui-angular/src/lib/action-strip/grid-actions/grid-editing-actions.component"; -import { IgxGridActionsBaseDirective } from "../../../igniteui-angular/src/lib/action-strip/grid-actions/grid-actions-base.directive"; -import { IgxGridPinningActionsComponent } from "../../../igniteui-angular/src/lib/action-strip/grid-actions/grid-pinning-actions.component"; -import { IgxColumnComponent } from "../../../igniteui-angular/src/lib/grids/columns/column.component"; -import { IgxColumnGroupComponent } from "../../../igniteui-angular/src/lib/grids/columns/column-group.component"; -import { IgxColumnLayoutComponent } from "../../../igniteui-angular/src/lib/grids/columns/column-layout.component"; import { IgxGridToolbarTitleComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/common"; import { IgxGridToolbarActionsComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/common"; import { IgxGridToolbarAdvancedFilteringComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/grid-toolbar-advanced-filtering.component"; import { IgxGridToolbarComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/grid-toolbar.component"; import { IgxToolbarToken } from "../../../igniteui-angular/src/lib/grids/toolbar/token"; +import { IgxColumnComponent } from "../../../igniteui-angular/src/lib/grids/columns/column.component"; +import { IgxColumnGroupComponent } from "../../../igniteui-angular/src/lib/grids/columns/column-group.component"; import { IgxRowIslandComponent } from "../../../igniteui-angular/src/lib/grids/hierarchical-grid/row-island.component"; +import { IgxActionStripComponent } from "../../../igniteui-angular/src/lib/action-strip/action-strip.component"; +import { IgxActionStripToken } from "../../../igniteui-angular/src/lib/action-strip/token"; +import { IgxGridEditingActionsComponent } from "../../../igniteui-angular/src/lib/action-strip/grid-actions/grid-editing-actions.component"; +import { IgxGridActionsBaseDirective } from "../../../igniteui-angular/src/lib/action-strip/grid-actions/grid-actions-base.directive"; +import { IgxGridPinningActionsComponent } from "../../../igniteui-angular/src/lib/action-strip/grid-actions/grid-pinning-actions.component"; +import { IgxColumnLayoutComponent } from "../../../igniteui-angular/src/lib/grids/columns/column-layout.component"; import { IgxGridToolbarExporterComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/grid-toolbar-exporter.component"; import { IgxGridToolbarHidingComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/grid-toolbar-hiding.component"; import { IgxGridToolbarPinningComponent } from "../../../igniteui-angular/src/lib/grids/toolbar/grid-toolbar-pinning.component"; diff --git a/projects/igniteui-angular/karma.conf.js b/projects/igniteui-angular/karma.conf.js index 6956108857e..fabb87455a3 100644 --- a/projects/igniteui-angular/karma.conf.js +++ b/projects/igniteui-angular/karma.conf.js @@ -22,7 +22,7 @@ module.exports = function (config) { '@angular-devkit/build-angular/plugins/karma' ], parallelOptions: { - executors: 2, + executors: 3, shardStrategy: 'round-robin' }, client: { @@ -52,7 +52,7 @@ module.exports = function (config) { customLaunchers: { ChromeHeadlessNoSandbox: { base: 'ChromeHeadless', - flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800'], + flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800', '--js-flags="--expose-gc"'], debug: false } }, diff --git a/projects/igniteui-angular/karma.grid.conf.js b/projects/igniteui-angular/karma.grid.conf.js index f68d3f07429..008322d9188 100644 --- a/projects/igniteui-angular/karma.grid.conf.js +++ b/projects/igniteui-angular/karma.grid.conf.js @@ -61,7 +61,7 @@ module.exports = function (config) { customLaunchers: { ChromeHeadlessNoSandbox: { base: 'ChromeHeadless', - flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800'], + flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800', '--js-flags="--expose-gc"'], debug: false } }, diff --git a/projects/igniteui-angular/karma.hierarchical-grid.conf.js b/projects/igniteui-angular/karma.hierarchical-grid.conf.js index cf6015cd4ae..8c564a10a16 100644 --- a/projects/igniteui-angular/karma.hierarchical-grid.conf.js +++ b/projects/igniteui-angular/karma.hierarchical-grid.conf.js @@ -59,7 +59,7 @@ module.exports = function (config) { customLaunchers: { ChromeHeadlessNoSandbox: { base: 'ChromeHeadless', - flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800'], + flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800', '--js-flags="--expose-gc"'], debug: false } }, diff --git a/projects/igniteui-angular/karma.non-grid.conf.js b/projects/igniteui-angular/karma.non-grid.conf.js index 139657033d5..09bd55ea925 100644 --- a/projects/igniteui-angular/karma.non-grid.conf.js +++ b/projects/igniteui-angular/karma.non-grid.conf.js @@ -59,7 +59,7 @@ module.exports = function (config) { customLaunchers: { ChromeHeadlessNoSandbox: { base: 'ChromeHeadless', - flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800'], + flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800', '--js-flags="--expose-gc"'], debug: false } }, diff --git a/projects/igniteui-angular/karma.pivot-grid.conf.js b/projects/igniteui-angular/karma.pivot-grid.conf.js index 9bcdd89165f..a037310ecf7 100644 --- a/projects/igniteui-angular/karma.pivot-grid.conf.js +++ b/projects/igniteui-angular/karma.pivot-grid.conf.js @@ -62,7 +62,7 @@ module.exports = function (config) { customLaunchers: { ChromeHeadlessNoSandbox: { base: 'ChromeHeadless', - flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800'], + flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800', '--js-flags="--expose-gc"'], debug: false } }, diff --git a/projects/igniteui-angular/karma.tree-grid.conf.js b/projects/igniteui-angular/karma.tree-grid.conf.js index 3f5636f1fdc..4b2882a6d2a 100644 --- a/projects/igniteui-angular/karma.tree-grid.conf.js +++ b/projects/igniteui-angular/karma.tree-grid.conf.js @@ -60,7 +60,7 @@ module.exports = function (config) { customLaunchers: { ChromeHeadlessNoSandbox: { base: 'ChromeHeadless', - flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800'], + flags: ['--no-sandbox', '--disable-gpu', '--window-size=820,800', '--js-flags="--expose-gc"'], debug: false } }, diff --git a/projects/igniteui-angular/karma.watch.conf.js b/projects/igniteui-angular/karma.watch.conf.js index db8fce89053..bc83a9064bc 100644 --- a/projects/igniteui-angular/karma.watch.conf.js +++ b/projects/igniteui-angular/karma.watch.conf.js @@ -38,7 +38,17 @@ module.exports = function (config) { colors: true, logLevel: config.LOG_INFO, autoWatch: true, - browsers: ['Chrome'], + browsers: ['ChromeWithGC'], + customLaunchers: { + ChromeWithGC: { + base: 'Chrome', + flags: [ + '--js-flags="--expose-gc"', + '--disable-backgrounding-occluded-windows', // don't throttle when window is fully hidden behind others + ], + debug: false + } + }, singleRun: false }); }; diff --git a/projects/igniteui-angular/migrations/update-11_1_0/index.spec.ts b/projects/igniteui-angular/migrations/update-11_1_0/index.spec.ts index 086b6563a76..aa54dd0e083 100644 --- a/projects/igniteui-angular/migrations/update-11_1_0/index.spec.ts +++ b/projects/igniteui-angular/migrations/update-11_1_0/index.spec.ts @@ -708,47 +708,4 @@ export class CsvExportComponent { ) ).toEqual(expectedContent); }); - - it('should update GridPagingMode enum from lowerCase to TitleCase', async () => { - appTree.create( - '/testSrc/appPrefix/component/paging-test.component.ts', -`import { Component } from '@angular/core'; -import { GridPagingMode } from "igniteui-angular"; - -@Component({ - selector: "app-paging-test", - styleUrls: ["./paging-test.component.scss"], - templateUrl: "./paging-test.component.html" -}) -export class PagingComponent { - public pagingLocal: GridPagingMode = GridPagingMode.local; - public pagingRemote: GridPagingMode = GridPagingMode.remote; - constructor(){} -} -`); - - const tree = await runner - .runSchematic('migration-19', {}, appTree); - - const expectedContent = -`import { Component } from '@angular/core'; -import { GridPagingMode } from "igniteui-angular"; - -@Component({ - selector: "app-paging-test", - styleUrls: ["./paging-test.component.scss"], - templateUrl: "./paging-test.component.html" -}) -export class PagingComponent { - public pagingLocal: GridPagingMode = GridPagingMode.Local; - public pagingRemote: GridPagingMode = GridPagingMode.Remote; - constructor(){} -} -`; - expect( - tree.readContent( - '/testSrc/appPrefix/component/paging-test.component.ts' - ) - ).toEqual(expectedContent); - }); }); diff --git a/projects/igniteui-angular/migrations/update-19_2_0/changes/theme-changes.json b/projects/igniteui-angular/migrations/update-19_2_0/changes/theme-changes.json new file mode 100644 index 00000000000..093539707cf --- /dev/null +++ b/projects/igniteui-angular/migrations/update-19_2_0/changes/theme-changes.json @@ -0,0 +1,59 @@ +{ + "$schema": "../../common/schema/theme-changes.schema.json", + "changes": [ + { + "name": "$label-invalid-color", + "remove": true, + "owner": "switch-theme", + "type": "property" + }, + { + "name": "$track-error-color", + "remove": true, + "owner": "switch-theme", + "type": "property" + }, + { + "name": "$thumb-on-error-color", + "remove": true, + "owner": "switch-theme", + "type": "property" + }, + { + "name": "$error-color", + "remove": true, + "owner": "switch-theme", + "type": "property" + }, + { + "name": "$error-color-hover", + "remove": true, + "owner": "switch-theme", + "type": "property" + }, + { + "name": "$date-selected-current-outline", + "remove": true, + "owner": "calendar-theme", + "type": "property" + }, + { + "name": "$date-selected-current-hover-outline", + "remove": true, + "owner": "calendar-theme", + "type": "property" + }, + { + "name": "$date-selected-current-focus-outline", + "remove": true, + "owner": "calendar-theme", + "type": "property" + }, + { + "name": "$date-special-current-border-color", + "remove": true, + "owner": "calendar-theme", + "type": "property" + } + ] + } diff --git a/projects/igniteui-angular/migrations/update-19_2_0/index.spec.ts b/projects/igniteui-angular/migrations/update-19_2_0/index.spec.ts index 01df5d3e16f..46fd2eaba8c 100644 --- a/projects/igniteui-angular/migrations/update-19_2_0/index.spec.ts +++ b/projects/igniteui-angular/migrations/update-19_2_0/index.spec.ts @@ -34,4 +34,51 @@ describe(`Update to ${version}`, () => { ` ); }); + + it('should remove the properties related to invalid state from the switch theme', async () => { + const testFilePath = `/testSrc/appPrefix/component/test.component.scss`; + + appTree.create( + testFilePath, + `$invalid-switch-theme: switch-theme( + $label-color: orange, + $label-invalid-color: red, + $track-error-color: red, + $thumb-on-error-color: darkred, + $error-color: red, + $error-color-hover: darkred, + );` + ); + + const tree = await schematicRunner.runSchematic(migrationName, {}, appTree); + + expect(tree.readContent(testFilePath)).toEqual( + `$invalid-switch-theme: switch-theme( + $label-color: orange, + );` + ); + }); + + it('should remove unused properties from the calendar theme', async () => { + const testFilePath = `/testSrc/appPrefix/component/test.component.scss`; + + appTree.create( + testFilePath, + `$calendar-theme: calendar-theme( + $date-special-current-border-color: orange, + $date-selected-current-outline: orange, + $date-selected-current-hover-outline: orange, + $date-selected-current-focus-outline: orange, + $content-background: black + );` + ); + + const tree = await schematicRunner.runSchematic(migrationName, {}, appTree); + + expect(tree.readContent(testFilePath)).toEqual( + `$calendar-theme: calendar-theme( + $content-background: black + );` + ); + }); }); diff --git a/projects/igniteui-angular/package.json b/projects/igniteui-angular/package.json index 9910299a420..19932f8f91e 100644 --- a/projects/igniteui-angular/package.json +++ b/projects/igniteui-angular/package.json @@ -73,7 +73,7 @@ "tslib": "^2.3.0", "igniteui-trial-watermark": "^3.0.2", "lodash-es": "^4.17.21", - "igniteui-theming": "^17.0.0", + "igniteui-theming": "^17.2.0", "@igniteui/material-icons-extended": "^3.1.0" }, "peerDependencies": { diff --git a/projects/igniteui-angular/src/lib/action-strip/grid-actions/grid-editing-actions.component.spec.ts b/projects/igniteui-angular/src/lib/action-strip/grid-actions/grid-editing-actions.component.spec.ts index 9c9841e8655..44dd12f7b0d 100644 --- a/projects/igniteui-angular/src/lib/action-strip/grid-actions/grid-editing-actions.component.spec.ts +++ b/projects/igniteui-angular/src/lib/action-strip/grid-actions/grid-editing-actions.component.spec.ts @@ -15,6 +15,7 @@ import { IgxGridEditingActionsComponent } from './grid-editing-actions.component import { IgxGridPinningActionsComponent } from './grid-pinning-actions.component'; import { IgxActionStripComponent } from '../action-strip.component'; import { IRowDataCancelableEventArgs, IgxColumnComponent } from '../../grids/public_api'; +import { SampleTestData } from '../../test-utils/sample-test-data.spec'; describe('igxGridEditingActions #grid ', () => { let fixture; @@ -429,35 +430,7 @@ class IgxActionStripTestingComponent implements OnInit { { field: 'Fax', width: '200px' } ]; - this.data = [ - { ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative', Address: 'Obere Str. 57', City: 'Berlin', Region: null, PostalCode: '12209', Country: 'Germany', Phone: '030-0074321', Fax: '030-0076545' }, - { ID: 'ANATR', CompanyName: 'Ana Trujillo Emparedados y helados', ContactName: 'Ana Trujillo', ContactTitle: 'Owner', Address: 'Avda. de la Constitución 2222', City: 'México D.F.', Region: null, PostalCode: '05021', Country: 'Mexico', Phone: '(5) 555-4729', Fax: '(5) 555-3745' }, - { ID: 'ANTON', CompanyName: 'Antonio Moreno Taquería', ContactName: 'Antonio Moreno', ContactTitle: 'Owner', Address: 'Mataderos 2312', City: 'México D.F.', Region: null, PostalCode: '05023', Country: 'Mexico', Phone: '(5) 555-3932', Fax: null }, - { ID: 'AROUT', CompanyName: 'Around the Horn', ContactName: 'Thomas Hardy', ContactTitle: 'Sales Representative', Address: '120 Hanover Sq.', City: 'London', Region: null, PostalCode: 'WA1 1DP', Country: 'UK', Phone: '(171) 555-7788', Fax: '(171) 555-6750' }, - { ID: 'BERGS', CompanyName: 'Berglunds snabbköp', ContactName: 'Christina Berglund', ContactTitle: 'Order Administrator', Address: 'Berguvsvägen 8', City: 'Luleå', Region: null, PostalCode: 'S-958 22', Country: 'Sweden', Phone: '0921-12 34 65', Fax: '0921-12 34 67' }, - { ID: 'BLAUS', CompanyName: 'Blauer See Delikatessen', ContactName: 'Hanna Moos', ContactTitle: 'Sales Representative', Address: 'Forsterstr. 57', City: 'Mannheim', Region: null, PostalCode: '68306', Country: 'Germany', Phone: '0621-08460', Fax: '0621-08924' }, - { ID: 'BLONP', CompanyName: 'Blondesddsl père et fils', ContactName: 'Frédérique Citeaux', ContactTitle: 'Marketing Manager', Address: '24, place Kléber', City: 'Strasbourg', Region: null, PostalCode: '67000', Country: 'France', Phone: '88.60.15.31', Fax: '88.60.15.32' }, - { ID: 'BOLID', CompanyName: 'Bólido Comidas preparadas', ContactName: 'Martín Sommer', ContactTitle: 'Owner', Address: 'C/ Araquil, 67', City: 'Madrid', Region: null, PostalCode: '28023', Country: 'Spain', Phone: '(91) 555 22 82', Fax: '(91) 555 91 99' }, - { ID: 'BONAP', CompanyName: 'Bon app\'', ContactName: 'Laurence Lebihan', ContactTitle: 'Owner', Address: '12, rue des Bouchers', City: 'Marseille', Region: null, PostalCode: '13008', Country: 'France', Phone: '91.24.45.40', Fax: '91.24.45.41' }, - { ID: 'BOTTM', CompanyName: 'Bottom-Dollar Markets', ContactName: 'Elizabeth Lincoln', ContactTitle: 'Accounting Manager', Address: '23 Tsawassen Blvd.', City: 'Tsawassen', Region: 'BC', PostalCode: 'T2F 8M4', Country: 'Canada', Phone: '(604) 555-4729', Fax: '(604) 555-3745' }, - { ID: 'BSBEV', CompanyName: 'B\'s Beverages', ContactName: 'Victoria Ashworth', ContactTitle: 'Sales Representative', Address: 'Fauntleroy Circus', City: 'London', Region: null, PostalCode: 'EC2 5NT', Country: 'UK', Phone: '(171) 555-1212', Fax: null }, - { ID: 'CACTU', CompanyName: 'Cactus Comidas para llevar', ContactName: 'Patricio Simpson', ContactTitle: 'Sales Agent', Address: 'Cerrito 333', City: 'Buenos Aires', Region: null, PostalCode: '1010', Country: 'Argentina', Phone: '(1) 135-5555', Fax: '(1) 135-4892' }, - { ID: 'CENTC', CompanyName: 'Centro comercial Moctezuma', ContactName: 'Francisco Chang', ContactTitle: 'Marketing Manager', Address: 'Sierras de Granada 9993', City: 'México D.F.', Region: null, PostalCode: '05022', Country: 'Mexico', Phone: '(5) 555-3392', Fax: '(5) 555-7293' }, - { ID: 'CHOPS', CompanyName: 'Chop-suey Chinese', ContactName: 'Yang Wang', ContactTitle: 'Owner', Address: 'Hauptstr. 29', City: 'Bern', Region: null, PostalCode: '3012', Country: 'Switzerland', Phone: '0452-076545', Fax: null }, - { ID: 'COMMI', CompanyName: 'Comércio Mineiro', ContactName: 'Pedro Afonso', ContactTitle: 'Sales Associate', Address: 'Av. dos Lusíadas, 23', City: 'Sao Paulo', Region: 'SP', PostalCode: '05432-043', Country: 'Brazil', Phone: '(11) 555-7647', Fax: null }, - { ID: 'CONSH', CompanyName: 'Consolidated Holdings', ContactName: 'Elizabeth Brown', ContactTitle: 'Sales Representative', Address: 'Berkeley Gardens 12 Brewery', City: 'London', Region: null, PostalCode: 'WX1 6LT', Country: 'UK', Phone: '(171) 555-2282', Fax: '(171) 555-9199' }, - { ID: 'DRACD', CompanyName: 'Drachenblut Delikatessen', ContactName: 'Sven Ottlieb', ContactTitle: 'Order Administrator', Address: 'Walserweg 21', City: 'Aachen', Region: null, PostalCode: '52066', Country: 'Germany', Phone: '0241-039123', Fax: '0241-059428' }, - { ID: 'DUMON', CompanyName: 'Du monde entier', ContactName: 'Janine Labrune', ContactTitle: 'Owner', Address: '67, rue des Cinquante Otages', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.67.88.88', Fax: '40.67.89.89' }, - { ID: 'EASTC', CompanyName: 'Eastern Connection', ContactName: 'Ann Devon', ContactTitle: 'Sales Agent', Address: '35 King George', City: 'London', Region: null, PostalCode: 'WX3 6FW', Country: 'UK', Phone: '(171) 555-0297', Fax: '(171) 555-3373' }, - { ID: 'ERNSH', CompanyName: 'Ernst Handel', ContactName: 'Roland Mendel', ContactTitle: 'Sales Manager', Address: 'Kirchgasse 6', City: 'Graz', Region: null, PostalCode: '8010', Country: 'Austria', Phone: '7675-3425', Fax: '7675-3426' }, - { ID: 'FAMIA', CompanyName: 'Familia Arquibaldo', ContactName: 'Aria Cruz', ContactTitle: 'Marketing Assistant', Address: 'Rua Orós, 92', City: 'Sao Paulo', Region: 'SP', PostalCode: '05442-030', Country: 'Brazil', Phone: '(11) 555-9857', Fax: null }, - { ID: 'FISSA', CompanyName: 'FISSA Fabrica Inter. Salchichas S.A.', ContactName: 'Diego Roel', ContactTitle: 'Accounting Manager', Address: 'C/ Moralzarzal, 86', City: 'Madrid', Region: null, PostalCode: '28034', Country: 'Spain', Phone: '(91) 555 94 44', Fax: '(91) 555 55 93' }, - { ID: 'FOLIG', CompanyName: 'Folies gourmandes', ContactName: 'Martine Rancé', ContactTitle: 'Assistant Sales Agent', Address: '184, chaussée de Tournai', City: 'Lille', Region: null, PostalCode: '59000', Country: 'France', Phone: '20.16.10.16', Fax: '20.16.10.17' }, - { ID: 'FOLKO', CompanyName: 'Folk och fä HB', ContactName: 'Maria Larsson', ContactTitle: 'Owner', Address: 'Åkergatan 24', City: 'Bräcke', Region: null, PostalCode: 'S-844 67', Country: 'Sweden', Phone: '0695-34 67 21', Fax: null }, - { ID: 'FRANK', CompanyName: 'Frankenversand', ContactName: 'Peter Franken', ContactTitle: 'Marketing Manager', Address: 'Berliner Platz 43', City: 'München', Region: null, PostalCode: '80805', Country: 'Germany', Phone: '089-0877310', Fax: '089-0877451' }, - { ID: 'FRANR', CompanyName: 'France restauration', ContactName: 'Carine Schmitt', ContactTitle: 'Marketing Manager', Address: '54, rue Royale', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.32.21.21', Fax: '40.32.21.20' }, - { ID: 'FRANS', CompanyName: 'Franchi S.p.A.', ContactName: 'Paolo Accorti', ContactTitle: 'Sales Representative', Address: 'Via Monte Bianco 34', City: 'Torino', Region: null, PostalCode: '10100', Country: 'Italy', Phone: '011-4988260', Fax: '011-4988261' } - ]; + this.data = SampleTestData.contactInfoDataFull(); this.dataOneRow = [ { ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative', Address: 'Obere Str. 57', City: 'Berlin', Region: null, PostalCode: '12209', Country: 'Germany', Phone: '030-0074321', Fax: '030-0076545' }, diff --git a/projects/igniteui-angular/src/lib/action-strip/grid-actions/grid-pinning-actions.component.spec.ts b/projects/igniteui-angular/src/lib/action-strip/grid-actions/grid-pinning-actions.component.spec.ts index abc864009c7..8f1fdfb8024 100644 --- a/projects/igniteui-angular/src/lib/action-strip/grid-actions/grid-pinning-actions.component.spec.ts +++ b/projects/igniteui-angular/src/lib/action-strip/grid-actions/grid-pinning-actions.component.spec.ts @@ -8,6 +8,7 @@ import { By } from '@angular/platform-browser'; import { wait } from '../../test-utils/ui-interactions.spec'; import { IgxGridPinningActionsComponent } from './grid-pinning-actions.component'; import { IgxColumnComponent } from '../../grids/public_api'; +import { SampleTestData } from '../../test-utils/sample-test-data.spec'; describe('igxGridPinningActions #grid ', () => { @@ -140,35 +141,7 @@ class IgxActionStripTestingComponent implements OnInit { { field: 'Fax', width: '200px' } ]; - this.data = [ - { ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative', Address: 'Obere Str. 57', City: 'Berlin', Region: null, PostalCode: '12209', Country: 'Germany', Phone: '030-0074321', Fax: '030-0076545' }, - { ID: 'ANATR', CompanyName: 'Ana Trujillo Emparedados y helados', ContactName: 'Ana Trujillo', ContactTitle: 'Owner', Address: 'Avda. de la Constitución 2222', City: 'México D.F.', Region: null, PostalCode: '05021', Country: 'Mexico', Phone: '(5) 555-4729', Fax: '(5) 555-3745' }, - { ID: 'ANTON', CompanyName: 'Antonio Moreno Taquería', ContactName: 'Antonio Moreno', ContactTitle: 'Owner', Address: 'Mataderos 2312', City: 'México D.F.', Region: null, PostalCode: '05023', Country: 'Mexico', Phone: '(5) 555-3932', Fax: null }, - { ID: 'AROUT', CompanyName: 'Around the Horn', ContactName: 'Thomas Hardy', ContactTitle: 'Sales Representative', Address: '120 Hanover Sq.', City: 'London', Region: null, PostalCode: 'WA1 1DP', Country: 'UK', Phone: '(171) 555-7788', Fax: '(171) 555-6750' }, - { ID: 'BERGS', CompanyName: 'Berglunds snabbköp', ContactName: 'Christina Berglund', ContactTitle: 'Order Administrator', Address: 'Berguvsvägen 8', City: 'Luleå', Region: null, PostalCode: 'S-958 22', Country: 'Sweden', Phone: '0921-12 34 65', Fax: '0921-12 34 67' }, - { ID: 'BLAUS', CompanyName: 'Blauer See Delikatessen', ContactName: 'Hanna Moos', ContactTitle: 'Sales Representative', Address: 'Forsterstr. 57', City: 'Mannheim', Region: null, PostalCode: '68306', Country: 'Germany', Phone: '0621-08460', Fax: '0621-08924' }, - { ID: 'BLONP', CompanyName: 'Blondesddsl père et fils', ContactName: 'Frédérique Citeaux', ContactTitle: 'Marketing Manager', Address: '24, place Kléber', City: 'Strasbourg', Region: null, PostalCode: '67000', Country: 'France', Phone: '88.60.15.31', Fax: '88.60.15.32' }, - { ID: 'BOLID', CompanyName: 'Bólido Comidas preparadas', ContactName: 'Martín Sommer', ContactTitle: 'Owner', Address: 'C/ Araquil, 67', City: 'Madrid', Region: null, PostalCode: '28023', Country: 'Spain', Phone: '(91) 555 22 82', Fax: '(91) 555 91 99' }, - { ID: 'BONAP', CompanyName: 'Bon app\'', ContactName: 'Laurence Lebihan', ContactTitle: 'Owner', Address: '12, rue des Bouchers', City: 'Marseille', Region: null, PostalCode: '13008', Country: 'France', Phone: '91.24.45.40', Fax: '91.24.45.41' }, - { ID: 'BOTTM', CompanyName: 'Bottom-Dollar Markets', ContactName: 'Elizabeth Lincoln', ContactTitle: 'Accounting Manager', Address: '23 Tsawassen Blvd.', City: 'Tsawassen', Region: 'BC', PostalCode: 'T2F 8M4', Country: 'Canada', Phone: '(604) 555-4729', Fax: '(604) 555-3745' }, - { ID: 'BSBEV', CompanyName: 'B\'s Beverages', ContactName: 'Victoria Ashworth', ContactTitle: 'Sales Representative', Address: 'Fauntleroy Circus', City: 'London', Region: null, PostalCode: 'EC2 5NT', Country: 'UK', Phone: '(171) 555-1212', Fax: null }, - { ID: 'CACTU', CompanyName: 'Cactus Comidas para llevar', ContactName: 'Patricio Simpson', ContactTitle: 'Sales Agent', Address: 'Cerrito 333', City: 'Buenos Aires', Region: null, PostalCode: '1010', Country: 'Argentina', Phone: '(1) 135-5555', Fax: '(1) 135-4892' }, - { ID: 'CENTC', CompanyName: 'Centro comercial Moctezuma', ContactName: 'Francisco Chang', ContactTitle: 'Marketing Manager', Address: 'Sierras de Granada 9993', City: 'México D.F.', Region: null, PostalCode: '05022', Country: 'Mexico', Phone: '(5) 555-3392', Fax: '(5) 555-7293' }, - { ID: 'CHOPS', CompanyName: 'Chop-suey Chinese', ContactName: 'Yang Wang', ContactTitle: 'Owner', Address: 'Hauptstr. 29', City: 'Bern', Region: null, PostalCode: '3012', Country: 'Switzerland', Phone: '0452-076545', Fax: null }, - { ID: 'COMMI', CompanyName: 'Comércio Mineiro', ContactName: 'Pedro Afonso', ContactTitle: 'Sales Associate', Address: 'Av. dos Lusíadas, 23', City: 'Sao Paulo', Region: 'SP', PostalCode: '05432-043', Country: 'Brazil', Phone: '(11) 555-7647', Fax: null }, - { ID: 'CONSH', CompanyName: 'Consolidated Holdings', ContactName: 'Elizabeth Brown', ContactTitle: 'Sales Representative', Address: 'Berkeley Gardens 12 Brewery', City: 'London', Region: null, PostalCode: 'WX1 6LT', Country: 'UK', Phone: '(171) 555-2282', Fax: '(171) 555-9199' }, - { ID: 'DRACD', CompanyName: 'Drachenblut Delikatessen', ContactName: 'Sven Ottlieb', ContactTitle: 'Order Administrator', Address: 'Walserweg 21', City: 'Aachen', Region: null, PostalCode: '52066', Country: 'Germany', Phone: '0241-039123', Fax: '0241-059428' }, - { ID: 'DUMON', CompanyName: 'Du monde entier', ContactName: 'Janine Labrune', ContactTitle: 'Owner', Address: '67, rue des Cinquante Otages', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.67.88.88', Fax: '40.67.89.89' }, - { ID: 'EASTC', CompanyName: 'Eastern Connection', ContactName: 'Ann Devon', ContactTitle: 'Sales Agent', Address: '35 King George', City: 'London', Region: null, PostalCode: 'WX3 6FW', Country: 'UK', Phone: '(171) 555-0297', Fax: '(171) 555-3373' }, - { ID: 'ERNSH', CompanyName: 'Ernst Handel', ContactName: 'Roland Mendel', ContactTitle: 'Sales Manager', Address: 'Kirchgasse 6', City: 'Graz', Region: null, PostalCode: '8010', Country: 'Austria', Phone: '7675-3425', Fax: '7675-3426' }, - { ID: 'FAMIA', CompanyName: 'Familia Arquibaldo', ContactName: 'Aria Cruz', ContactTitle: 'Marketing Assistant', Address: 'Rua Orós, 92', City: 'Sao Paulo', Region: 'SP', PostalCode: '05442-030', Country: 'Brazil', Phone: '(11) 555-9857', Fax: null }, - { ID: 'FISSA', CompanyName: 'FISSA Fabrica Inter. Salchichas S.A.', ContactName: 'Diego Roel', ContactTitle: 'Accounting Manager', Address: 'C/ Moralzarzal, 86', City: 'Madrid', Region: null, PostalCode: '28034', Country: 'Spain', Phone: '(91) 555 94 44', Fax: '(91) 555 55 93' }, - { ID: 'FOLIG', CompanyName: 'Folies gourmandes', ContactName: 'Martine Rancé', ContactTitle: 'Assistant Sales Agent', Address: '184, chaussée de Tournai', City: 'Lille', Region: null, PostalCode: '59000', Country: 'France', Phone: '20.16.10.16', Fax: '20.16.10.17' }, - { ID: 'FOLKO', CompanyName: 'Folk och fä HB', ContactName: 'Maria Larsson', ContactTitle: 'Owner', Address: 'Åkergatan 24', City: 'Bräcke', Region: null, PostalCode: 'S-844 67', Country: 'Sweden', Phone: '0695-34 67 21', Fax: null }, - { ID: 'FRANK', CompanyName: 'Frankenversand', ContactName: 'Peter Franken', ContactTitle: 'Marketing Manager', Address: 'Berliner Platz 43', City: 'München', Region: null, PostalCode: '80805', Country: 'Germany', Phone: '089-0877310', Fax: '089-0877451' }, - { ID: 'FRANR', CompanyName: 'France restauration', ContactName: 'Carine Schmitt', ContactTitle: 'Marketing Manager', Address: '54, rue Royale', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.32.21.21', Fax: '40.32.21.20' }, - { ID: 'FRANS', CompanyName: 'Franchi S.p.A.', ContactName: 'Paolo Accorti', ContactTitle: 'Sales Representative', Address: 'Via Monte Bianco 34', City: 'Torino', Region: null, PostalCode: '10100', Country: 'Italy', Phone: '011-4988260', Fax: '011-4988261' } - ]; + this.data = SampleTestData.contactInfoDataFull(); } } diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.html b/projects/igniteui-angular/src/lib/calendar/calendar.component.html index 96410be5472..e7ec1e520d4 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.html +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.html @@ -189,6 +189,8 @@

[attr.aria-multiselectable]="selection !== 'single'" aria-labelledby="calendar-desc" role="grid" + (focus)="this.onWrapperFocus($event)" + (blur)="this.onWrapperBlur($event)" > @if (selection === 'multi') { diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts index 4ad06214313..273c263963c 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.spec.ts @@ -128,7 +128,7 @@ describe("IgxCalendar - ", () => { }); describe("Basic -", () => { - configureTestSuite(); + configureTestSuite({ checkLeaks: true }); beforeAll(waitForAsync(() => { TestBed.configureTestingModule({ @@ -154,6 +154,11 @@ describe("IgxCalendar - ", () => { calendar = fixture.componentInstance.calendar; dom = fixture.debugElement; })); + afterEach(() => { + fixture = undefined; + calendar = undefined; + dom = undefined; + }); it("Should initialize a calendar component", () => { expect(fixture.componentInstance).toBeDefined(); diff --git a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts index 528bc28db3a..301ff268f53 100644 --- a/projects/igniteui-angular/src/lib/calendar/calendar.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/calendar.component.ts @@ -483,9 +483,6 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af .set("PageUp", this.handlePageUp) .set("PageDown", this.handlePageDown); - this.wrapper.nativeElement.addEventListener('focus', (event: FocusEvent) => this.onWrapperFocus(event)); - this.wrapper.nativeElement.addEventListener('blur', (event: FocusEvent) => this.onWrapperBlur(event)); - this.startPageScroll$.pipe( takeUntil(this.stopPageScroll$), switchMap(() => this.scrollPage$.pipe( @@ -516,12 +513,12 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af }); } - private onWrapperFocus(_event: FocusEvent) { + protected onWrapperFocus(_event: FocusEvent) { this.showActiveDay = true; this.monthViews.forEach(view => view.changePreviewRange(this.activeDate)); } - private onWrapperBlur(_event: FocusEvent) { + protected onWrapperBlur(_event: FocusEvent) { this.showActiveDay = false; this.monthViews.forEach(view => view.clearPreviewRange()); this._onTouchedCallback(); @@ -1059,8 +1056,6 @@ export class IgxCalendarComponent extends IgxCalendarBaseDirective implements Af */ public ngOnDestroy(): void { this.keyboardNavigation.detachKeyboardHandlers(); - this.wrapper?.nativeElement.removeEventListener('focus', this.onWrapperFocus); - this.wrapper?.nativeElement.removeEventListener('blur', this.onWrapperBlur); } /** diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html index e13738c8de4..a726c6b1f50 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html +++ b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.html @@ -102,6 +102,8 @@ [attr.aria-multiselectable]="selection !== 'single'" aria-labelledby="calendar-desc" role="grid" + (focus)="this.onWrapperFocus($event)" + (blur)="this.onWrapperBlur($event)" > {{ resourceStrings.igx_calendar_singular_single_selection}} diff --git a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts index 6bda0564ec4..1929f51da7c 100644 --- a/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts +++ b/projects/igniteui-angular/src/lib/calendar/month-picker/month-picker.component.ts @@ -331,9 +331,6 @@ export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements .set("PageUp", this.handlePageUp) .set("PageDown", this.handlePageDown); - this.wrapper.nativeElement.addEventListener('focus', (event: FocusEvent) => this.onWrapperFocus(event)); - this.wrapper.nativeElement.addEventListener('blur', (event: FocusEvent) => this.onWrapperBlur(event)); - this.activeView$.subscribe((view) => { this.activeViewChanged.emit(view); @@ -344,12 +341,12 @@ export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements }); } - private onWrapperFocus(event: FocusEvent) { + protected onWrapperFocus(event: FocusEvent) { event.stopPropagation(); this.showActiveDay = true; } - private onWrapperBlur(event: FocusEvent) { + protected onWrapperBlur(event: FocusEvent) { event.stopPropagation(); this.showActiveDay = false; @@ -456,8 +453,6 @@ export class IgxMonthPickerComponent extends IgxCalendarBaseDirective implements */ public ngOnDestroy(): void { this.keyboardNavigation.detachKeyboardHandlers(); - this.wrapper?.nativeElement.removeEventListener('focus', this.onWrapperFocus); - this.wrapper?.nativeElement.removeEventListener('blur', this.onWrapperBlur); } /** diff --git a/projects/igniteui-angular/src/lib/carousel/carousel-base.ts b/projects/igniteui-angular/src/lib/carousel/carousel-base.ts index b441651292f..994e2e46d0c 100644 --- a/projects/igniteui-angular/src/lib/carousel/carousel-base.ts +++ b/projects/igniteui-angular/src/lib/carousel/carousel-base.ts @@ -1,5 +1,5 @@ import { AnimationReferenceMetadata, useAnimation } from '@angular/animations'; -import { ChangeDetectorRef, EventEmitter, Inject } from '@angular/core'; +import { ChangeDetectorRef, Directive, EventEmitter, Inject, OnDestroy } from '@angular/core'; import { IgxAngularAnimationService } from '../services/animation/angular-animation-service'; import { AnimationPlayer, AnimationService } from '../services/animation/animation'; import { fadeIn, slideInLeft } from 'igniteui-angular/animations'; @@ -19,7 +19,8 @@ export interface IgxSlideComponentBase { } /** @hidden */ -export abstract class IgxCarouselComponentBase { +@Directive() +export abstract class IgxCarouselComponentBase implements OnDestroy { /** @hidden */ public animationType: CarouselAnimationType = CarouselAnimationType.slide; @@ -50,6 +51,11 @@ export abstract class IgxCarouselComponentBase { protected cdr: ChangeDetectorRef) { } + public ngOnDestroy(): void { + this.enterAnimationPlayer?.destroy(); + this.leaveAnimationPlayer?.destroy(); + } + /** @hidden */ protected triggerAnimations() { if (this.animationType !== CarouselAnimationType.none) { @@ -146,7 +152,7 @@ export abstract class IgxCarouselComponentBase { this.enterAnimationPlayer.animationEnd.subscribe(() => { // TODO: animation may never end. Find better way to clean up the player if (this.enterAnimationPlayer) { - this.enterAnimationPlayer.reset(); + this.enterAnimationPlayer.destroy(); this.enterAnimationPlayer = null; } this.animationPosition = 0; @@ -169,7 +175,7 @@ export abstract class IgxCarouselComponentBase { this.leaveAnimationPlayer.animationEnd.subscribe(() => { // TODO: animation may never end. Find better way to clean up the player if (this.leaveAnimationPlayer) { - this.leaveAnimationPlayer.reset(); + this.leaveAnimationPlayer.destroy(); this.leaveAnimationPlayer = null; } this.animationPosition = 0; diff --git a/projects/igniteui-angular/src/lib/carousel/carousel.component.ts b/projects/igniteui-angular/src/lib/carousel/carousel.component.ts index 98533ee8fa1..50444aa4683 100644 --- a/projects/igniteui-angular/src/lib/carousel/carousel.component.ts +++ b/projects/igniteui-angular/src/lib/carousel/carousel.component.ts @@ -86,7 +86,6 @@ export class CarouselHammerConfig extends HammerGestureConfig { }`], imports: [IgxButtonDirective, IgxIconComponent, NgClass, NgTemplateOutlet] }) - export class IgxCarouselComponent extends IgxCarouselComponentBase implements OnDestroy, AfterContentInit { /** @@ -699,7 +698,8 @@ export class IgxCarouselComponent extends IgxCarouselComponentBase implements On } /** @hidden */ - public ngOnDestroy() { + public override ngOnDestroy() { + super.ngOnDestroy(); this.destroy$.next(true); this.destroy$.complete(); this.destroyed = true; diff --git a/projects/igniteui-angular/src/lib/checkbox/checkbox-base.directive.ts b/projects/igniteui-angular/src/lib/checkbox/checkbox-base.directive.ts index fb9cf5e07f6..d83915b098e 100644 --- a/projects/igniteui-angular/src/lib/checkbox/checkbox-base.directive.ts +++ b/projects/igniteui-angular/src/lib/checkbox/checkbox-base.directive.ts @@ -8,7 +8,6 @@ import { ViewChild, ElementRef, ChangeDetectorRef, - Renderer2, Optional, Self, booleanAttribute, @@ -250,7 +249,6 @@ export class CheckboxBaseDirective implements AfterViewInit { constructor( protected cdr: ChangeDetectorRef, - protected renderer: Renderer2, @Inject(THEME_TOKEN) protected themeToken: ThemeToken, @Optional() @Self() public ngControl: NgControl diff --git a/projects/igniteui-angular/src/lib/combo/combo.common.ts b/projects/igniteui-angular/src/lib/combo/combo.common.ts index 71e63a32d3c..0b3f69cdd58 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.common.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.common.ts @@ -991,7 +991,6 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh /** @hidden @internal */ public ngOnInit() { - this.ngControl = this._injector.get(NgControl, null); this.selectionService.set(this.id, new Set()); this._iconService?.addSvgIconFromText(caseSensitive.name, caseSensitive.value, 'imx-icons'); @@ -1096,8 +1095,8 @@ export abstract class IgxComboBaseDirective implements IgxComboBase, AfterViewCh * ``` */ public get selection(): any[] { - const items = Array.from(this.selectionService.get(this.id)); - return this.convertKeysToItems(items); + const serviceRef = this.selectionService.get(this.id); + return serviceRef ? this.convertKeysToItems(Array.from(serviceRef)) : []; } /** diff --git a/projects/igniteui-angular/src/lib/core/styles/components/action-strip/_action-strip-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/action-strip/_action-strip-theme.scss index 4c87c2df3a4..78d97b80462 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/action-strip/_action-strip-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/action-strip/_action-strip-theme.scss @@ -195,5 +195,11 @@ igx-icon { color: var-get($theme, 'delete-action'); } + + [igxIconButton] { + igx-icon { + color: var-get($theme, 'delete-action'); + } + } } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss index e7590e2526b..ac78526f137 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-component.scss @@ -179,6 +179,10 @@ @extend %date-range-preview !optional; } + @include e(date, $mods: ('range-preview', 'inactive')) { + @extend %date-range-preview-inactive !optional; + } + @include e(date, $mods: ('range-preview', 'current')) { @extend %date-range-preview-current !optional; } @@ -389,6 +393,18 @@ @extend %date-last-preview-special !optional; } + @include e(date, $mods: ('first', 'range-preview', 'active')) { + @extend %date-first-preview-active !optional; + } + + @include e(date, $mods: ('last', 'range-preview', 'active')) { + @extend %date-last-preview-active !optional; + } + + @include e(date, $mods: ('first', 'last', 'selected')) { + @extend %date-first-last-selected !optional; + } + @include e(date, $mods: ('first', 'range-preview', 'special', 'current')) { @extend %date-first-preview-special-current !optional; } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss index 88dce836976..cf254985f27 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/calendar/_calendar-theme.scss @@ -108,10 +108,6 @@ /// @param {Color} $date-selected-current-range-focus-foreground [null] - The :focus foreground of the current date in the selected range. /// @param {Color} $date-selected-current-range-focus-background [null] - The :focus background of the current date in the selected range. /// -/// @param {Color} $date-selected-current-outline [null] - The outline of the current selected date. -/// @param {Color} $date-selected-current-hover-outline [null] - The :hover outline of the current selected date. -/// @param {Color} $date-selected-current-focus-outline [null] - The :focus outline of the current selected date. -/// /// @param {Color} $date-selected-special-border-color: [null] - The border color of the selected special date, /// @param {Color} $date-selected-special-hover-border-color: [null] - The :hover border color of the selected special date, /// @param {Color} $date-selected-special-focus-border-color: [null] - The :focus border color of the selected special date, @@ -137,8 +133,6 @@ /// @param {Color} $date-special-range-foreground [null] - The foreground of the dates inside a range and marked as special. /// @param {Color} $date-special-range-border-color [null] - The outline of the dates inside a range and marked as special. /// -/// @param {Color} $date-special-current-border-color [null] - The outline color of a special current date. -/// /// @param {Color} $border-color [null] - The calendar border color. /// /// @param {Color} $date-border-color [null] - The border color of the date. @@ -282,10 +276,6 @@ $date-selected-current-hover-border-color: null, $date-selected-current-focus-border-color: null, - $date-selected-current-outline: null, - $date-selected-current-hover-outline: null, - $date-selected-current-focus-outline: null, - $date-selected-special-border-color: null, $date-selected-special-hover-border-color: null, $date-selected-special-focus-border-color: null, @@ -310,7 +300,6 @@ $date-special-range-focus-background: null, $date-special-range-foreground: null, $date-special-range-border-color: null, - $date-special-current-border-color: null, $date-disabled-foreground: null, $date-disabled-range-foreground: null, @@ -400,26 +389,6 @@ } } - @if $variant == 'material' or $variant == 'indigo' { - @if not($date-selected-current-outline) and $content-background { - @if meta.type-of($content-background) == 'color' { - $date-selected-current-outline: $content-background; - } - } - - @if not($date-selected-current-hover-outline) and $content-background { - @if meta.type-of($content-background) == 'color' { - $date-selected-current-hover-outline: $content-background; - } - } - - @if not($date-selected-current-focus-outline) and $content-background { - @if meta.type-of($content-background) == 'color' { - $date-selected-current-focus-outline: $content-background; - } - } - } - @if not($content-foreground) and $content-background { @if meta.type-of($content-background) == 'color' { $content-foreground: text-contrast($content-background); @@ -640,10 +609,6 @@ date-selected-current-hover-foreground: $date-selected-current-hover-foreground, date-selected-current-focus-foreground: $date-selected-current-focus-foreground, - date-selected-current-outline: $date-selected-current-outline, - date-selected-current-hover-outline: $date-selected-current-hover-outline, - date-selected-current-focus-outline: $date-selected-current-focus-outline, - date-selected-special-border-color: $date-selected-special-border-color, date-selected-special-hover-border-color: $date-selected-special-hover-border-color, date-selected-special-focus-border-color: $date-selected-special-focus-border-color, @@ -1578,7 +1543,9 @@ %date-selected-special-active { %date-inner { &::after { - border-color: var-get($theme, 'date-selected-special-focus-border-color'); + @if $variant != 'fluent' { + border-color: var-get($theme, 'date-selected-special-focus-border-color'); + } } } } @@ -1641,7 +1608,9 @@ %date-selected-special-current-first-last { %date-inner { &::after { - border-color: var-get($theme, 'date-selected-special-border-color'); + @if $variant != 'fluent' { + border-color: var-get($theme, 'date-selected-special-border-color'); + } } } } @@ -1814,7 +1783,9 @@ %date-special-current-selected-active { %date-inner { &::after { - border-color: var-get($theme, 'date-selected-special-border-color'); + @if $variant != 'fluent' { + border-color: var-get($theme, 'date-selected-special-border-color'); + } } } } @@ -1887,6 +1858,16 @@ } } + @if $variant == 'fluent' { + %date-selected-current-special { + %date-inner { + &::after { + border-color: var-get($theme, 'date-selected-current-background'); + } + } + } + } + %date-inactive { cursor: default; @@ -2042,7 +2023,7 @@ %date-selected-current-range-special-active:not(%date-selected-current-range-special-first), %date-selected-current-range-special-active:not(%date-selected-current-range-special-last) { %date-inner { - @if not $bootstrap-theme { + @if not $bootstrap-theme and not $variant == 'fluent' { color: var-get($theme, 'date-special-focus-foreground'); } @@ -2192,7 +2173,6 @@ position: absolute; height: $date-size; width: $date-size; - border-radius: var-get($theme, 'date-border-radius'); } } @@ -2218,7 +2198,32 @@ &::after { width: $date-inner-size; height: $date-inner-size; - border-color: var-get($theme, 'date-selected-special-border-color'); + + @if $variant != 'fluent' { + border-color: var-get($theme, 'date-selected-special-border-color'); + } + } + } + } + + @if $variant == 'fluent' { + %date-first-preview-active { + %date-inner { + background: transparent; + border-inline-end-color: transparent; + } + } + + %date-last-preview-active { + %date-inner { + background: transparent; + border-inline-start-color: transparent; + } + } + + %date-first-last-selected { + %date-inner { + background: transparent; } } } @@ -2338,7 +2343,7 @@ content: ''; position: absolute; height: $date-size; - width: calc($date-size / 2 + #{$border-size}); + width: $date-size; border: rem(1px) solid var-get($theme, 'date-range-border-color'); z-index: 3; pointer-events: none; @@ -2346,16 +2351,53 @@ } %date-range-selected-first { + %date-inner { + border-start-end-radius: var-get($theme, 'date-border-radius'); + border-end-end-radius: var-get($theme, 'date-border-radius'); + } + &::before { - inset-inline-end: calc(50% - #{$border-size}); border-inline-end-color: transparent; + border-start-start-radius: var-get($theme, 'date-range-border-radius'); + border-end-start-radius: var-get($theme, 'date-range-border-radius'); } } %date-range-selected-last { + %date-inner { + border-start-start-radius: var-get($theme, 'date-border-radius'); + border-end-start-radius: var-get($theme, 'date-border-radius'); + } + &::before { - inset-inline-start: calc(50% - #{$border-size}); border-inline-start-color: transparent; + border-start-end-radius: var-get($theme, 'date-range-border-radius'); + border-end-end-radius: var-get($theme, 'date-range-border-radius'); + } + } + + + %date-first-preview { + %date-inner { + border-start-start-radius: var-get($theme, 'date-range-border-radius'); + border-end-start-radius: var-get($theme, 'date-range-border-radius'); + border-start-end-radius: 0; + border-end-end-radius: 0; + } + } + + %date-last-preview { + %date-inner { + border-start-end-radius: var-get($theme, 'date-range-border-radius'); + border-end-end-radius: var-get($theme, 'date-range-border-radius'); + border-start-start-radius: 0; + border-end-start-radius: 0; + } + } + + %date-first-last { + %date-inner { + border-radius: var-get($theme, 'date-range-border-radius'); } } } @@ -2389,6 +2431,12 @@ } } + %date-range-preview-inactive { + %date-inner { + color: var-get($theme, 'inactive-color'); + } + } + %date-range-preview-current { %date-inner { color: var-get($theme, 'date-selected-current-range-foreground'); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/card/_card-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/card/_card-theme.scss index 576570dc37c..4955db6dbee 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/card/_card-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/card/_card-theme.scss @@ -103,8 +103,6 @@ $not-material-theme: $variant != 'material'; $card-heading-padding: rem(16px, 16px); - $card-content-padding: rem(16px); - $card-actions-padding: rem(8px); $card-tgroup-margin: 0 em(16px); @@ -148,7 +146,7 @@ %igx-card-header { display: flex; flex-flow: row wrap; - align-content: flex-start; + align-items: center; width: 100%; padding: $card-heading-padding; color: var-get($theme, 'header-text-color'); @@ -157,10 +155,6 @@ display: block; padding: 0; } - - @if $variant == 'fluent' { - padding: rem(16px) rem(8px); - } } %igx-card-header--vertical { @@ -184,7 +178,6 @@ } %igx-card-header-thumbnail { - align-self: flex-start; margin-inline-end: rem(16px); @if $variant == 'indigo' { @@ -224,7 +217,7 @@ %igx-card-content { display: block; width: 100%; - padding: $card-content-padding; + padding: rem(16px); color: var-get($theme, 'content-text-color'); overflow: auto; } @@ -248,6 +241,14 @@ } %igx-card-actions { + $card-actions-padding: map.get(( + 'material': rem(8px) rem(16px), + 'fluent': rem(8px) rem(16px), + 'bootstrap': rem(16px), + 'indigo': rem(16px), + ), $variant); + + display: flex; flex-flow: row wrap; justify-content: space-between; @@ -272,29 +273,26 @@ @if $variant == 'bootstrap' { %igx-card-content { - @if $variant == 'bootstrap' { - padding-block: rem(16px) rem(24px); - padding-inline: rem(24px); - } - } - - %igx-card-actions { - padding: rem(16px); + padding-block-end: rem(24px); } } @if $variant == 'indigo' { - %igx-card-content, - %igx-card-actions { - padding: rem(16px); + %igx-card-content { + padding-block-end: rem(8px); } - %igx-card-content + %igx-card-actions { - padding-block-start: rem(8px); + %igx-card-content:last-child { + padding-block-end: rem(16px); } - %igx-card-header + %igx-card-content { - padding-block-start: 0; + %igx-card-header { + padding-block-end: 0; + } + + %igx-card-header:last-child, + %igx-card-header:first-child { + padding-block-end: rem(16px); } } @@ -318,6 +316,10 @@ margin-inline-start: auto; gap: rem(8px); + [igxIconButton] { + color: var-get($theme, 'actions-text-color'); + } + &:empty { display: none; } @@ -329,6 +331,10 @@ order: 0; gap: rem(8px); + [igxIconButton] { + color: var-get($theme, 'actions-text-color'); + } + &:empty { display: none; } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-component.scss index ea5e85bc339..5c0def5856a 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-component.scss @@ -163,7 +163,7 @@ @extend %igx-checkbox--focused-bootstrap !optional; &:hover { - @extend %igx-checkbox--focused-hovered !optional; + @extend %igx-checkbox--focused-hovered-bootstrap !optional; } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-theme.scss index 4f8f632a66e..48ed1cffa0e 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/checkbox/_checkbox-theme.scss @@ -29,8 +29,11 @@ /// @param {List} $border-radius [null] - The border radius used for checkbox component. /// @param {List} $border-radius-ripple [null] - The border radius used for checkbox ripple. /// @param {Color} $focus-outline-color [null] - The focus outlined color. +/// @param {Color} $focus-outline-color-focused [null] - The focus outlined color for focused state. +/// @param {Color} $focus-border-color [null] - The focus border color. /// @param {Color} $error-color [null] - The border and fill colors in invalid state. /// @param {Color} $error-color-hover [null] - The border and fill colors in invalid state on hover. +/// @param {Color} $focus-outline-color-error [null] - The focus outline error color. /// Set to light when the surrounding area is dark. /// /// @requires $light-material-schema @@ -58,8 +61,11 @@ $disabled-color-label: null, $border-radius-ripple: null, $focus-outline-color: null, + $focus-outline-color-focused: null, + $focus-border-color: null, $error-color: null, $error-color-hover: null, + $focus-outline-color-error: null, ) { $name: 'igx-checkbox'; $checkbox-schema: (); @@ -71,7 +77,55 @@ } $theme: digest-schema($checkbox-schema); - $meta: map.get($theme, '_meta'); + $variant: map.get($theme, '_meta', 'theme'); + + @if not($empty-color-hover) and $empty-color { + $empty-color-hover: hsl(from var(--empty-color) h s calc(l * 0.9)); + } + + @if not($fill-color-hover) and $fill-color { + $fill-color-hover: hsl(from var(--fill-color) h s calc(l * 0.9)); + } + + @if not($tick-color) and $fill-color { + $tick-color: adaptive-contrast(var(--fill-color)); + } + + @if not($label-color-hover) and $label-color { + $label-color-hover: hsl(from var(--label-color) h s calc(l * 0.9)); + } + + @if not($focus-border-color) and $fill-color { + $focus-border-color: var(--fill-color); + } + + @if not($disabled-indeterminate-color) and $fill-color { + $disabled-indeterminate-color: hsla(from var(--fill-color) h s l / 0.5); + } + + @if not($error-color-hover) and $error-color { + $error-color-hover: hsl(from var(--error-color) h s calc(l * 0.9)); + } + + @if not($focus-outline-color-error) and $error-color { + $focus-outline-color-error: hsla(from var(--error-color) h s l / .5); + } + + @if $variant == 'bootstrap' { + @if not($focus-outline-color) and $fill-color { + $focus-outline-color: hsla(from var(--fill-color) h s l / .5); + } + } + + @if $variant == 'indigo' { + @if not($focus-outline-color) and $empty-color { + $focus-outline-color: hsla(from var(--empty-color) h s l / .5); + } + + @if not($focus-outline-color-focused) and $fill-color { + $focus-outline-color-focused: hsla(from var(--fill-color) h s l / .5); + } + } @return extend($theme, ( name: $name, @@ -91,13 +145,11 @@ border-radius: $border-radius, border-radius-ripple: $border-radius-ripple, focus-outline-color: $focus-outline-color, + focus-outline-color-focused: $focus-outline-color-focused, + focus-border-color: $focus-border-color, error-color: $error-color, error-color-hover: $error-color-hover, - theme: map.get($schema, '_meta', 'theme'), - _meta: map.merge(if($meta, $meta, ()), ( - variant: map.get($schema, '_meta', 'theme'), - theme-variant: map.get($schema, '_meta', 'variant') - )), + focus-outline-color-error: $focus-outline-color-error )); } @@ -106,8 +158,8 @@ /// @param {Map} $theme - The theme used to style the component. @mixin checkbox($theme) { @include css-vars($theme); - $theme-variant: map.get($theme, '_meta', 'theme-variant'); - $variant: map.get($theme, '_meta', 'variant'); + $theme-variant: map.get($theme, '_meta', 'variant'); + $variant: map.get($theme, '_meta', 'theme'); $material-theme: $variant == 'material'; $bootstrap-theme: $variant == 'bootstrap'; @@ -591,14 +643,14 @@ %igx-checkbox--focused-bootstrap { %cbx-composite { border-radius: var-get($theme, 'border-radius'); - border-color: color($color: 'primary', $variant: 200); + border-color: var-get($theme, 'focus-border-color'); box-shadow: 0 0 0 rem(4px) var-get($theme, 'focus-outline-color'); } } - %igx-checkbox--focused-hovered { + %igx-checkbox--focused-hovered-bootstrap { %cbx-composite { - border-color: color($color: 'primary', $variant: 300); + border-color: hsl(from var-get($theme, 'focus-border-color') h calc(s * 1.12) calc(l * 0.82)); } } 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 752f35b2d48..45b929e1bda 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 @@ -268,14 +268,14 @@ $box-shadow-focus: map.get(( 'material': null, 'fluent': null, - 'bootstrap': 0 0 0 rem(2px) var-get($theme, 'focus-outline-color'), + 'bootstrap': 0 0 0 rem(4px) var-get($theme, 'focus-outline-color'), 'indigo': 0 0 0 rem(3px) var-get($theme, 'focus-outline-color') ), $variant); $box-shadow-focus-selected: map.get(( 'material': null, 'fluent': null, - 'bootstrap': 0 0 0 rem(2px) var-get($theme, 'focus-selected-outline-color'), + 'bootstrap': 0 0 0 rem(4px) var-get($theme, 'focus-selected-outline-color'), 'indigo': 0 0 0 rem(3px) var-get($theme, 'focus-selected-outline-color') ), $variant); @@ -378,19 +378,21 @@ } igx-avatar, - igx-circular-bar, igx-icon { --component-size: var(--chip-size); } + igx-circular-bar { + --diameter: #{sizable(rem(14px), rem(18px), rem(24px))}; + } + @if $variant == 'indigo' { igx-icon { --size: #{sizable(rem(14px), rem(14px), rem(16px))} } } - igx-avatar, - igx-circular-bar { + igx-avatar { max-height: 100%; width: sizable(rem(14px), rem(18px), rem(24px)); max-width: sizable(rem(14px), rem(18px), rem(24px)); @@ -427,9 +429,17 @@ %igx-chip%igx-chip--primary { &:focus { %igx-chip__item { - color: contrast-color($color: 'primary', $variant: 800); - background: color($color: 'primary', $variant: 800); - border-color: color($color: 'primary', $variant: 800); + @if $variant != 'bootstrap' and $variant != 'indigo' { + color: contrast-color($color: 'primary', $variant: 800); + background: color($color: 'primary', $variant: 800); + border-color: color($color: 'primary', $variant: 800); + } + + @if $variant == "bootstrap" { + color: contrast-color($color: 'primary', $variant: 500); + background: color($color: 'primary', $variant: 500); + border-color: color($color: 'primary', $variant: 500); + } @if $variant == 'indigo' { color: contrast-color($color: 'primary', $variant: 900); @@ -439,7 +449,7 @@ } @if $variant == 'bootstrap' { - box-shadow: 0 0 0 rem(2px) color($color: 'primary', $variant: 200); + box-shadow: 0 0 0 rem(4px) color($color: 'primary', $variant: 500, $opacity: .38); } } } @@ -472,15 +482,18 @@ background: color($color: 'info', $variant: 800); border-color: color($color: 'info', $variant: 800); - @if $variant == 'indigo' { + @if $variant == 'indigo' or $variant == 'bootstrap' { color: contrast-color($color: 'info', $variant: 500); background: color($color: 'info', $variant: 500); border-color: color($color: 'info', $variant: 500); + } + + @if $variant == 'indigo' { box-shadow: 0 0 0 rem(3px) color($color: 'info', $variant: if($theme-variant == 'light', 100, 800)); } @if $variant == 'bootstrap' { - box-shadow: 0 0 0 rem(2px) color($color: 'info', $variant: 200); + box-shadow: 0 0 0 rem(4px) color($color: 'info', $variant: 500, $opacity: .38); } } } @@ -517,15 +530,19 @@ background: color($color: 'success', $variant: 800); border-color: color($color: 'success', $variant: 800); - @if $variant == 'indigo' { - color: contrast-color($color: 'success', $variant: 900); + @if $variant == 'indigo' or $variant == 'bootstrap' { background: color($color: 'success', $variant: 500); border-color: color($color: 'success', $variant: 500); box-shadow: 0 0 0 rem(3px) color($color: 'success', $variant: if($theme-variant == 'light', 200, 800)); } + @if $variant == 'indigo' { + color: contrast-color($color: 'success', $variant: 900); + } + @if $variant == 'bootstrap' { - box-shadow: 0 0 0 rem(2px) color($color: 'success', $variant: 200); + color: contrast-color($color: 'success', $variant: 600); + box-shadow: 0 0 0 rem(4px) color($color: 'success', $variant: 500, $opacity: .38); } } } @@ -558,15 +575,18 @@ background: color($color: 'warn', $variant: 800); border-color: color($color: 'warn', $variant: 800); - @if $variant == 'indigo' { + @if $variant == 'indigo' or $variant == 'bootstrap' { color: contrast-color($color: 'warn', $variant: 900); background: color($color: 'warn', $variant: 500); border-color: color($color: 'warn', $variant: 500); + } + + @if $variant == 'indigo' { box-shadow: 0 0 0 rem(3px) color($color: 'warn', $variant: if($theme-variant == 'light', 100, 900)); } @if $variant == 'bootstrap' { - box-shadow: 0 0 0 rem(2px) color($color: 'warn', $variant: 200); + box-shadow: 0 0 0 rem(4px) color($color: 'warn', $variant: 500, $opacity: .38); } } } @@ -603,15 +623,19 @@ background: color($color: 'error', $variant: 800); border-color: color($color: 'error', $variant: 800); - @if $variant == 'indigo' { - color: contrast-color($color: 'error', $variant: 900); + @if $variant == 'indigo' or $variant == 'bootstrap' { background: color($color: 'error', $variant: 500); border-color: color($color: 'error', $variant: 500); + } + + @if $variant == 'indigo' { + color: contrast-color($color: 'error', $variant: 900); box-shadow: 0 0 0 rem(3px) color($color: 'error', $variant: if($theme-variant == 'light', 100, 900)); } @if $variant == 'bootstrap' { - box-shadow: 0 0 0 rem(2px) color($color: 'error', $variant: 200); + color: contrast-color($color: 'error', $variant: 600); + box-shadow: 0 0 0 rem(4px) color($color: 'error', $variant: 500, $opacity: .38); } } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss index 379581b5914..0166b635863 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss @@ -2084,7 +2084,7 @@ .sort-icon { color: var-get($theme, 'header-selected-text-color'); - + ::after { background: var-get($theme, 'header-selected-background'); } @@ -2112,10 +2112,18 @@ &%igx-grid-th--sorted { .sort-icon { color: var-get($theme, 'header-selected-text-color'); + + > igx-icon { + color: inherit; + } &:focus, &:hover { color: var-get($theme, 'header-selected-text-color'); + + > igx-icon { + color: inherit; + } } } } @@ -2169,9 +2177,17 @@ .sort-icon { opacity: 1; color: var-get($theme, 'sorted-header-icon-color'); + + > igx-icon { + color: inherit; + } &:hover { color: var-get($theme, 'sortable-header-icon-hover-color'); + + > igx-icon { + color: inherit; + } } } } 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 4e248b5cf49..a48422df79f 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 @@ -1648,6 +1648,18 @@ [igxPrefix] { overflow: hidden; } + + igx-prefix, + [igxPrefix] { + background: var(--igx-input-group-input-prefix-background, transparent); + color: var(--igx-input-group-input-prefix-color, var(--ig-primary-500)); + } + + igx-suffix, + [igxSuffix] { + background: var(--igx-input-group-input-suffix-background, transparent); + color: var(--igx-input-group-input-suffix-color, var(--ig-primary-500)); + } } %igx-input-group-fluent-search--focused { @@ -1731,6 +1743,10 @@ %form-group-bundle--fluent--focus { border-color: var-get($theme, 'focused-border-color'); border-width: rem(2px); + + &:hover { + border-color: var-get($theme, 'focused-border-color'); + } } %form-group-bundle-error--fluent, @@ -1846,7 +1862,6 @@ } %fluent-label-focused { - color: color(null, 'gray', 800); transform: translateY(0) scale(1); } 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 7605e2504f9..ee2f3119d64 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 @@ -425,7 +425,6 @@ justify-content: center; border-radius: var-get($theme, 'item-border-radius'); color: var-get($theme, 'item-text-color'); - background: var-get($theme, 'item-background'); @if $bootstrap-theme or $variant == 'fluent' { border-bottom: var-get($theme, 'border-width') solid var-get($theme, 'border-color'); @@ -436,9 +435,6 @@ } &:hover { - color: var-get($theme, 'item-text-color-hover'); - background: var-get($theme, 'item-background-hover'); - %igx-list__item-lines { color: currentColor; } @@ -544,9 +540,15 @@ align-items: center; position: relative; border-radius: var-get($theme, 'item-border-radius'); - background: inherit; + background: var-get($theme, 'item-background'); z-index: 2; gap: if($variant == 'indigo', rem(8px), rem(16px)); + + &:hover, + &:focus-within { + color: var-get($theme, 'item-text-color-hover'); + background: var-get($theme, 'item-background-hover'); + } } %igx-list-header, diff --git a/projects/igniteui-angular/src/lib/core/styles/components/progress/circular/_circular-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/progress/circular/_circular-theme.scss index d9e55d2095e..8c0512966e6 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/progress/circular/_circular-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/progress/circular/_circular-theme.scss @@ -64,6 +64,7 @@ @return extend($theme, ( name: $name, base-circle-color: $base-circle-color, + fill-color-default: $fill-color-default, fill-color-default-start: $fill-color-default-start, fill-color-default-end: $fill-color-default-end, fill-color-danger: $fill-color-danger, @@ -134,6 +135,8 @@ transform-origin: center; %outer { + stroke: var-get($theme, 'fill-color-default'); + @if $variant != 'bootstrap' { animation: igx-initial-dashoffset var(--_transition-duration) linear; } @else { @@ -310,14 +313,14 @@ %text--hidden { visibility: hidden; } - - %gradient-start { - stop-color: var-get($theme, 'fill-color-default-start'); - } - - %gradient-end { - stop-color: var-get($theme, 'fill-color-default-end'); - } + + %gradient-start { + stop-color: var-get($theme, 'fill-color-default-end'); + } + + %gradient-end { + stop-color: var-get($theme, 'fill-color-default-start'); + } @keyframes igx-indeterminate-accordion { 0% { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/query-builder/_query-builder-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/query-builder/_query-builder-theme.scss index 98c2167bf4a..e1d2cafd988 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/query-builder/_query-builder-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/query-builder/_query-builder-theme.scss @@ -486,18 +486,31 @@ --ig-body-2-text-transform: unset; padding-inline: rem(32px); - + color: color($color: 'gray', $variant: if($theme-variant == 'light', 600, 900)); border: rem(1px) dashed color($color: 'gray', $variant: if($theme-variant == 'light', 600, 300)); background: transparent; } } - + %filter-tree__expression-item-keyboard-ghost { .igx-chip__item { box-shadow: var(--ghost-shadow); background: var(--ghost-background); + color: var(--focus-text-color); } + + .igx-chip:hover { + .igx-chip__item { + box-shadow: var(--ghost-shadow); + background: var(--ghost-background); + color: var(--focus-text-color); + + @if $variant == 'indigo' { + border-color: var(--border-color); + } + } + } } %filter-tree__expression-column { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-component.scss index eb2109e485f..d814253f8e5 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-component.scss @@ -132,56 +132,6 @@ } } - @include m(invalid) { - @include e(composite) { - @extend %switch-composite--invalid !optional; - } - - &:hover { - @include e(ripple) { - @extend %switch-ripple--hover !optional; - @extend %switch-ripple--hover-invalid !optional; - } - - @include e(composite) { - @extend %switch-composite--invalid--hover !optional; - } - } - - &:active { - @include e(ripple) { - @extend %switch-ripple--hover !optional; - @extend %switch-ripple--hover-invalid !optional; - @extend %switch-ripple--pressed !optional; - } - } - - @include e(label) { - @extend %switch-label--invalid !optional; - } - - @include e(label, $m: before) { - @extend %switch-label--invalid !optional; - } - - @include e(thumb) { - @extend %switch-thumb--invalid !optional; - } - } - - @include mx(invalid, checked) { - @include e(thumb) { - @extend %switch-thumb--x--invalid !optional; - } - - &:hover { - @include e(ripple) { - @extend %switch-ripple--hover !optional; - @extend %switch-ripple--hover-checked-invalid !optional; - } - } - } - @include m(disabled) { @extend %switch-display--disabled !optional; @@ -202,26 +152,11 @@ } } - @include mx(disabled, invalid) { - @include e(thumb) { - @extend %switch-thumb--disabled !optional; - } - } - @include mx(focused, checked) { @include e(ripple) { @extend %switch-ripple--focused !optional; @extend %switch-ripple--focused-checked !optional; } } - - @include mx(focused, invalid) { - @include e(ripple) { - @extend %switch-ripple--focused !optional; - @extend %switch-ripple--focused-invalid !optional; - } - - @extend %igx-switch--focused--invalid !optional; - } } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-theme.scss index 05a800a75d9..fc4dda80469 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/switch/_switch-theme.scss @@ -39,11 +39,6 @@ /// @param {Color} $focus-outline-color-focused [null] - The focus outlined color for focused state. /// @param {Color} $focus-fill-color [null] - The focus fill color. /// @param {Color} $focus-fill-hover-color [null] - The focus fill color on hover. -/// @param {Color} $label-invalid-color [null] - The color of the switch label in invalid state. -/// @param {Color} $track-error-color [null] - The color of the track in invalid state when the switch is off. -/// @param {Color} $thumb-on-error-color [null] - The color of the thumb when the switch is on and invalid. -/// @param {Color} $error-color [null] - The border and fill colors in invalid state. -/// @param {Color} $error-color-hover [null] - The border and fill colors in invalid state on hover. /// @requires $light-material-schema /// /// @example scss Set custom track and thumb on colors @@ -68,7 +63,6 @@ $label-color: null, $label-hover-color: null, $label-disabled-color: null, - $label-invalid-color: null, $resting-shadow: null, $hover-shadow: null, @@ -86,10 +80,6 @@ $focus-outline-color-focused: null, $focus-fill-color: null, $focus-fill-hover-color: null, - $track-error-color: null, - $thumb-on-error-color: null, - $error-color: null, - $error-color-hover: null, ) { $name: 'igx-switch'; $switch-schema: (); @@ -148,7 +138,6 @@ label-color: $label-color, label-hover-color: $label-hover-color, label-disabled-color: $label-disabled-color, - label-invalid-color: $label-invalid-color, resting-shadow: $resting-shadow, hover-shadow: $hover-shadow, @@ -166,10 +155,6 @@ focus-outline-color-focused: $focus-outline-color-focused, focus-fill-color: $focus-fill-color, focus-fill-hover-color: $focus-fill-hover-color, - track-error-color: $track-error-color, - thumb-on-error-color: $thumb-on-error-color, - error-color: $error-color, - error-color-hover: $error-color-hover, theme: map.get($schema, '_meta', 'theme'), _meta: map.merge(if($meta, $meta, ()), ( variant: map.get($schema, '_meta', 'theme'), @@ -316,25 +301,6 @@ } } - %switch-composite--invalid { - border-color: var-get($theme, 'error-color'); - - @if $variant == 'material' { - border-color: var-get($theme, 'track-error-color'); - background: var-get($theme, 'track-error-color'); - } - } - - %switch-composite--invalid--hover { - @if $variant == 'fluent' { - border-color: var-get($theme, 'error-color-hover'); - - %switch-thumb { - background: var-get($theme, 'error-color-hover'); - } - } - } - %switch-composite--x { background: var-get($theme, 'track-on-color'); border-color: var-get($theme, 'border-on-color'); @@ -403,14 +369,6 @@ background: var-get($theme, 'thumb-on-color'); } - %switch-thumb--invalid { - background: var-get($theme, 'error-color'); - } - - %switch-thumb--x--invalid { - background: var-get($theme, 'thumb-on-error-color'); - } - %switch-thumb--disabled { background: var-get($theme, 'thumb-disabled-color'); box-shadow: $thumb-disabled-shadow; @@ -477,25 +435,6 @@ } } - %igx-switch--focused--invalid { - @if $variant == 'bootstrap' { - %switch-composite { - border-color: var-get($theme, 'error-color'); - box-shadow: 0 0 0 rem(4px) var-get($theme, 'error-color-hover'); - } - - %switch-thumb { - background: var-get($theme, 'error-color'); - } - } - - @if $variant == 'indigo' { - %switch-composite { - box-shadow: 0 0 0 rem(3px) var-get($theme, 'error-color-hover'); - } - } - } - %igx-switch--focused-checked { @if $variant == 'bootstrap' { %switch-composite { @@ -550,10 +489,6 @@ background: var-get($theme, 'thumb-on-color'); } - %switch-ripple--focused-invalid { - background: var-get($theme, 'error-color-hover'); - } - %switch-label { display: inline-block; color: var-get($theme, 'label-color'); @@ -585,10 +520,6 @@ color: var-get($theme, 'label-hover-color'); } - %switch-label--invalid { - color: var-get($theme, 'label-invalid-color'); - } - %switch-label--disabled { color: var-get($theme, 'label-disabled-color'); } @@ -618,18 +549,6 @@ } } - %switch-ripple--hover-invalid { - &::after { - background: var-get($theme, 'error-color-hover'); - } - } - - %switch-ripple--hover-checked-invalid { - &::after { - background: var-get($theme, 'thumb-on-color'); - } - } - %switch-ripple--pressed { &::after { opacity: .12; 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 4c46d1c6bfc..f64a00a367d 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 @@ -311,9 +311,7 @@ } igx-circular-bar { - --circular-bar: #{sizable(#{map.get($circular-bar-size, 'compact')}, #{map.get($circular-bar-size, 'cosy')}, #{map.get($circular-bar-size, 'comfortable')})}; - width: var(--circular-bar); - height: var(--circular-bar); + --diameter: #{sizable(#{map.get($circular-bar-size, 'compact')}, #{map.get($circular-bar-size, 'cosy')}, #{map.get($circular-bar-size, 'comfortable')})}; } } diff --git a/projects/igniteui-angular/src/lib/data-operations/expressions-tree-util.ts b/projects/igniteui-angular/src/lib/data-operations/expressions-tree-util.ts index c9543362999..365f349d603 100644 --- a/projects/igniteui-angular/src/lib/data-operations/expressions-tree-util.ts +++ b/projects/igniteui-angular/src/lib/data-operations/expressions-tree-util.ts @@ -178,8 +178,9 @@ export function isTree(entry: IExpressionTree | IFilteringExpression): entry is * @param entities An array of entities to use for recreating the tree. * @returns The recreated expression tree. */ -export function recreateTree(tree: IExpressionTree, entities: EntityType[]): IExpressionTree { - const entity = entities.find(e => e.name === tree.entity); +export function recreateTree(tree: IExpressionTree, entities: EntityType[], isRoot: boolean = false): IExpressionTree { + const entity = isRoot ? entities[0] : entities.find(e => e.name === tree.entity); + if (!entity) return tree; for (let i = 0; i < tree.filteringOperands.length; i++) { const operand = tree.filteringOperands[i]; @@ -187,7 +188,7 @@ export function recreateTree(tree: IExpressionTree, entities: EntityType[]): IEx tree.filteringOperands[i] = recreateTree(operand, entities); } else { if (operand.searchTree) { - operand.searchTree = recreateTree(operand.searchTree, entities); + operand.searchTree = recreateTree(operand.searchTree, entities[0].childEntities ?? entities); } tree.filteringOperands[i] = recreateExpression(operand, entity?.fields); } diff --git a/projects/igniteui-angular/src/lib/data-operations/filtering-expression.interface.ts b/projects/igniteui-angular/src/lib/data-operations/filtering-expression.interface.ts index dfb3212e810..78076df46b3 100644 --- a/projects/igniteui-angular/src/lib/data-operations/filtering-expression.interface.ts +++ b/projects/igniteui-angular/src/lib/data-operations/filtering-expression.interface.ts @@ -7,7 +7,6 @@ export enum FilteringLogic { Or } -/* tsPlainInterface */ /* marshalByValue */ /** * Represents filtering expressions. diff --git a/projects/igniteui-angular/src/lib/data-operations/filtering-expressions-tree.ts b/projects/igniteui-angular/src/lib/data-operations/filtering-expressions-tree.ts index 229050379b4..4a46dafc421 100644 --- a/projects/igniteui-angular/src/lib/data-operations/filtering-expressions-tree.ts +++ b/projects/igniteui-angular/src/lib/data-operations/filtering-expressions-tree.ts @@ -8,6 +8,7 @@ export enum FilteringExpressionsTreeType { Advanced } +/* marshalByValue */ export declare interface IExpressionTree { filteringOperands: (IExpressionTree | IFilteringExpression)[]; operator: FilteringLogic; @@ -16,6 +17,7 @@ export declare interface IExpressionTree { returnFields?: string[] | null; } +/* alternateBaseType: ExpressionTree */ /* marshalByValue */ export declare interface IFilteringExpressionsTree extends IBaseEventArgs, IExpressionTree { filteringOperands: (IFilteringExpressionsTree | IFilteringExpression)[]; diff --git a/projects/igniteui-angular/src/lib/data-operations/filtering-strategy.ts b/projects/igniteui-angular/src/lib/data-operations/filtering-strategy.ts index 37a5759e231..bc8812b713b 100644 --- a/projects/igniteui-angular/src/lib/data-operations/filtering-strategy.ts +++ b/projects/igniteui-angular/src/lib/data-operations/filtering-strategy.ts @@ -1,12 +1,13 @@ import { FilteringLogic, IFilteringExpression } from './filtering-expression.interface'; import { FilteringExpressionsTree, IFilteringExpressionsTree } from './filtering-expressions-tree'; import { resolveNestedPath, parseDate, formatDate, formatCurrency } from '../core/utils'; -import { ColumnType, GridType } from '../grids/common/grid.interface'; +import { ColumnType, EntityType, GridType } from '../grids/common/grid.interface'; import { GridColumnDataType } from './data-util'; import { SortingDirection } from './sorting-strategy'; import { formatNumber, formatPercent, getLocaleCurrencyCode } from '@angular/common'; import { IFilteringState } from './filtering-state.interface'; import { isTree } from './expressions-tree-util'; +import { IgxHierarchicalGridComponent } from '../grids/hierarchical-grid/hierarchical-grid.component'; const DateType = 'date'; const DateTimeType = 'dateTime'; @@ -39,6 +40,26 @@ export interface IgxFilterItem { export abstract class BaseFilteringStrategy implements IFilteringStrategy { // protected public findMatchByExpression(rec: any, expr: IFilteringExpression, isDate?: boolean, isTime?: boolean, grid?: GridType): boolean { + if (expr.searchTree) { + const records = rec[expr.searchTree.entity]; + const shouldMatchRecords = expr.conditionName === 'inQuery'; + if (!records) { // child grid is not yet created + return true; + } else if (records.length === 0) { // child grid is empty + return false; + } + + for (let index = 0; index < records.length; index++) { + const record = records[index]; + if ((shouldMatchRecords && this.matchRecord(record, expr.searchTree, grid, expr.searchTree.entity)) || + (!shouldMatchRecords && !this.matchRecord(record, expr.searchTree, grid, expr.searchTree.entity))) { + return true; + } + } + + return false; + } + const val = this.getFieldValue(rec, expr.fieldName, isDate, isTime, grid); if (expr.condition?.logic) { return expr.condition.logic(val, expr.searchVal, expr.ignoreCase); @@ -46,7 +67,7 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy { } // protected - public matchRecord(rec: any, expressions: IFilteringExpressionsTree | IFilteringExpression, grid?: GridType): boolean { + public matchRecord(rec: any, expressions: IFilteringExpressionsTree | IFilteringExpression, grid?: GridType, entity?: string): boolean { if (expressions) { if (isTree(expressions)) { const expressionsTree = expressions; @@ -55,7 +76,7 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy { if (expressionsTree.filteringOperands && expressionsTree.filteringOperands.length) { for (const operand of expressionsTree.filteringOperands) { - matchOperand = this.matchRecord(rec, operand, grid); + matchOperand = this.matchRecord(rec, operand, grid, entity); // Return false if at least one operand does not match and the filtering logic is And if (!matchOperand && operator === FilteringLogic.And) { @@ -74,9 +95,19 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy { return true; } else { const expression = expressions; - const column = grid && grid.getColumnByName(expression.fieldName); - const isDate = column ? column.dataType === DateType || column.dataType === DateTimeType : false; - const isTime = column ? column.dataType === TimeType : false; + let dataType = null; + if (!entity) { + const column = grid && grid.getColumnByName(expression.fieldName); + dataType = column?.dataType; + } else if (grid.type === 'hierarchical') { + const schema = (grid as IgxHierarchicalGridComponent).schema; + const entityMatch = this.findEntityByName(schema, entity); + dataType = entityMatch?.fields.find(f => f.field === expression.fieldName)?.dataType; + } + + const isDate = dataType ? dataType === DateType || dataType === DateTimeType : false; + const isTime = dataType ? dataType === TimeType : false; + return this.findMatchByExpression(rec, expression, isDate, isTime, grid); } } @@ -84,6 +115,22 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy { return true; } + private findEntityByName(schema: EntityType[], name: string): EntityType | null { + for (const entity of schema) { + if (entity.name === name) { + return entity; + } + + if (entity.childEntities && entity.childEntities.length > 0) { + const found = this.findEntityByName(entity.childEntities, name); + if (found) { + return found; + } + } + } + return null; + } + public getFilterItems(column: ColumnType, tree: IFilteringExpressionsTree): Promise { let data = column.grid.gridAPI.filterDataByExpressions(tree); diff --git a/projects/igniteui-angular/src/lib/date-common/util/date-time.util.spec.ts b/projects/igniteui-angular/src/lib/date-common/util/date-time.util.spec.ts index a3d653a49cc..ce2e34b41a1 100644 --- a/projects/igniteui-angular/src/lib/date-common/util/date-time.util.spec.ts +++ b/projects/igniteui-angular/src/lib/date-common/util/date-time.util.spec.ts @@ -1,6 +1,9 @@ import { DateTimeUtil } from './date-time.util'; import { DatePart, DatePartInfo } from '../../directives/date-time-editor/date-time-editor.common'; import { DataType } from '../../data-operations/data-util'; +import localeBg from "@angular/common/locales/bg"; +import { registerLocaleData } from '@angular/common'; + const reduceToDictionary = (parts: DatePartInfo[]) => parts.reduce((obj, x) => { obj[x.type] = x; @@ -8,6 +11,9 @@ const reduceToDictionary = (parts: DatePartInfo[]) => parts.reduce((obj, x) => { }, {}); describe(`DateTimeUtil Unit tests`, () => { + + registerLocaleData(localeBg); + describe('Date Time Parsing', () => { it('should correctly parse all date time parts (base)', () => { let result = DateTimeUtil.parseDateTimeFormat('dd/MM/yyyy HH:mm:ss:SS a'); diff --git a/projects/igniteui-angular/src/lib/directives/button/button.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/button/button.directive.spec.ts index c7e90180af7..f4fbdd53c10 100644 --- a/projects/igniteui-angular/src/lib/directives/button/button.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/button/button.directive.spec.ts @@ -10,7 +10,7 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; const BUTTON_COMFORTABLE = 'igx-button'; describe('IgxButton', () => { - configureTestSuite(); + configureTestSuite({ checkLeaks: true }); const baseClass = BUTTON_COMFORTABLE; const classes = { diff --git a/projects/igniteui-angular/src/lib/directives/button/button.directive.ts b/projects/igniteui-angular/src/lib/directives/button/button.directive.ts index e414134bfac..dca32de8112 100644 --- a/projects/igniteui-angular/src/lib/directives/button/button.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/button/button.directive.ts @@ -3,12 +3,11 @@ import { ElementRef, EventEmitter, HostBinding, + HostListener, Input, Output, Renderer2, booleanAttribute, - AfterContentInit, - OnDestroy } from '@angular/core'; import { mkenum } from '../../core/utils'; import { IBaseEventArgs } from '../../core/utils'; @@ -47,7 +46,7 @@ export type IgxButtonType = typeof IgxButtonType[keyof typeof IgxButtonType]; selector: '[igxButton]', standalone: true }) -export class IgxButtonDirective extends IgxButtonBaseDirective implements AfterContentInit, OnDestroy { +export class IgxButtonDirective extends IgxButtonBaseDirective { private static ngAcceptInputType_type: IgxButtonType | ''; /** @@ -93,7 +92,8 @@ export class IgxButtonDirective extends IgxButtonBaseDirective implements AfterC */ private _selected = false; - private emitSelected() { + @HostListener('click') + protected emitSelected() { this.buttonSelected.emit({ button: this }); @@ -127,14 +127,6 @@ export class IgxButtonDirective extends IgxButtonBaseDirective implements AfterC super(element); } - public ngAfterContentInit() { - this.nativeElement.addEventListener('click', this.emitSelected.bind(this)); - } - - public ngOnDestroy(): void { - this.nativeElement.removeEventListener('click', this.emitSelected); - } - /** * Sets the type of the button. * diff --git a/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.directive.ts b/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.directive.ts index 4c18c7beccf..a6e9fd882fa 100644 --- a/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.directive.ts @@ -695,6 +695,10 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { public renderer: Renderer2, protected platformUtil: PlatformUtil ) { + this.onTransitionEnd = this.onTransitionEnd.bind(this); + this.onPointerMove = this.onPointerMove.bind(this); + this.onPointerUp = this.onPointerUp.bind(this); + this.onPointerLost = this.onPointerLost.bind(this); } /** @@ -765,7 +769,7 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { fromEvent(this.document.defaultView, 'mouseup').pipe(takeUntil(this._destroy)) .subscribe((res) => this.onPointerUp(res)); } - this.element.nativeElement.addEventListener('transitionend', this.onTransitionEnd.bind(this)); + this.element.nativeElement.addEventListener('transitionend', this.onTransitionEnd); }); // Set transition duration to 0s. This also helps with setting `visibility: hidden` to the base to not lag. @@ -779,13 +783,11 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { this._destroy.next(true); this._destroy.complete(); - if (this.ghost && this.ghostElement && this._removeOnDestroy) { - this.ghostElement.parentNode.removeChild(this.ghostElement); - this.ghostElement = null; - - if (this._dynamicGhostRef) { - this._dynamicGhostRef.destroy(); - this._dynamicGhostRef = null; + if (this.ghostElement) { + if (this._removeOnDestroy) { + this.clearGhost(); + } else { + this.detachGhost(); } } @@ -1219,11 +1221,15 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { }); } - protected clearGhost() { + protected detachGhost() { this.ghostElement.removeEventListener('pointermove', this.onPointerMove); this.ghostElement.removeEventListener('pointerup', this.onPointerUp); this.ghostElement.removeEventListener('lostpointercapture', this.onPointerLost); this.ghostElement.removeEventListener('transitionend', this.onTransitionEnd); + } + + protected clearGhost() { + this.detachGhost(); this.ghostElement.remove(); this.ghostElement = null; @@ -1309,13 +1315,13 @@ export class IgxDragDirective implements AfterContentInit, OnDestroy { if (this._pointerDownId !== null) { this.ghostElement.setPointerCapture(this._pointerDownId); } - this.ghostElement.addEventListener('pointermove', this.onPointerMove.bind(this)); - this.ghostElement.addEventListener('pointerup', this.onPointerUp.bind(this)); - this.ghostElement.addEventListener('lostpointercapture', this.onPointerLost.bind(this)); + this.ghostElement.addEventListener('pointermove', this.onPointerMove); + this.ghostElement.addEventListener('pointerup', this.onPointerUp); + this.ghostElement.addEventListener('lostpointercapture', this.onPointerLost); } // Transition animation when the ghostElement is released and it returns to it's original position. - this.ghostElement.addEventListener('transitionend', this.onTransitionEnd.bind(this)); + this.ghostElement.addEventListener('transitionend', this.onTransitionEnd); this.cdr.detectChanges(); } diff --git a/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.spec.ts b/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.spec.ts index 525fec4c950..6a3acf17d69 100644 --- a/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/drag-drop/drag-drop.spec.ts @@ -22,7 +22,7 @@ describe('General igxDrag/igxDrop', () => { let dropAreaRects = { top: 0, left: 0, right: 0, bottom: 0}; let dragDirsRects = [{ top: 0, left: 0, right: 0, bottom: 0}]; - configureTestSuite(); + configureTestSuite({ checkLeaks: true }); beforeAll(waitForAsync(() => { TestBed.configureTestingModule({ imports: [TestDragDropComponent] @@ -39,6 +39,13 @@ describe('General igxDrag/igxDrop', () => { dropAreaRects = getElemRects(dropArea.element.nativeElement); }); + afterEach(() => { + fix = null; + dragDirsRects = null; + dropArea = null; + dropAreaRects = null; + }); + it('should correctly initialize drag and drop directives.', () => { const ignoredElem = fix.debugElement.query(By.css('.ignoredElem')).nativeElement; diff --git a/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.spec.ts index cea8758dec5..7c5872e7e4f 100644 --- a/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.spec.ts @@ -1393,7 +1393,7 @@ export class TestIgxForOfDirective extends IgxForOfDirective { `, - imports: [TestIgxForOfDirective, IgxForOfDirective] + imports: [TestIgxForOfDirective] }) export class EmptyVirtualComponent { @@ -1421,7 +1421,7 @@ export class EmptyVirtualComponent { `, - imports: [TestIgxForOfDirective, IgxForOfDirective] + imports: [TestIgxForOfDirective] }) export class VirtualComponent { @ViewChild('container', { read: ViewContainerRef, static: true }) @@ -1495,7 +1495,7 @@ export class VirtualComponent { `, selector: 'igx-vertical-virtual', - imports: [TestIgxForOfDirective, IgxForOfDirective] + imports: [TestIgxForOfDirective] }) export class VerticalVirtualComponent extends VirtualComponent { public override width = '450px'; @@ -1531,7 +1531,7 @@ export class VerticalVirtualComponent extends VirtualComponent { } `, - imports: [TestIgxForOfDirective, IgxForOfDirective] + imports: [TestIgxForOfDirective] }) export class VerticalVirtualDestroyComponent extends VerticalVirtualComponent { public exists = true; @@ -1602,7 +1602,7 @@ export class VerticalVirtualCreateComponent extends VerticalVirtualComponent { `, - imports: [TestIgxForOfDirective, IgxForOfDirective] + imports: [TestIgxForOfDirective] }) export class HorizontalVirtualComponent extends VirtualComponent { public override width = '800px'; @@ -1625,7 +1625,7 @@ export class HorizontalVirtualComponent extends VirtualComponent { `, - imports: [TestIgxForOfDirective, IgxForOfDirective] + imports: [TestIgxForOfDirective] }) export class VirtualVariableSizeComponent { @ViewChild('container', { static: true }) @@ -1661,7 +1661,7 @@ export class VirtualVariableSizeComponent { `, selector: 'igx-vertical-virtual-no-data', - imports: [TestIgxForOfDirective, IgxForOfDirective] + imports: [TestIgxForOfDirective] }) export class VerticalVirtualNoDataComponent extends VerticalVirtualComponent { } @@ -1722,7 +1722,7 @@ export class LocalService { `, providers: [LocalService], - imports: [TestIgxForOfDirective, IgxForOfDirective, AsyncPipe] + imports: [TestIgxForOfDirective, AsyncPipe] }) export class RemoteVirtualizationComponent implements OnInit, AfterViewInit { @ViewChild('scrollContainer', { read: TestIgxForOfDirective, static: true }) @@ -1767,7 +1767,7 @@ export class RemoteVirtualizationComponent implements OnInit, AfterViewInit { `, providers: [LocalService], - imports: [TestIgxForOfDirective, IgxForOfDirective, AsyncPipe] + imports: [TestIgxForOfDirective, AsyncPipe] }) export class RemoteVirtCountComponent implements OnInit, AfterViewInit { @ViewChild('scrollContainer', { read: TestIgxForOfDirective, static: true }) @@ -1822,7 +1822,7 @@ export class RemoteVirtCountComponent implements OnInit, AfterViewInit { flex: 0 0 60px; border-right: 1px solid #888; }`], - imports: [TestIgxForOfDirective, IgxForOfDirective] + imports: [TestIgxForOfDirective] }) export class NoWidthAndHeightComponent { @@ -1897,7 +1897,7 @@ export class CustomSlicePipe implements PipeTransform { `, - imports: [IgxForOfDirective, CustomSlicePipe, NgClass] + imports: [IgxForOfDirective, CustomSlicePipe] }) export class LocalVariablesAsComponent { public data = []; 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 672d2fa9c66..6f79dc8751b 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 @@ -1800,7 +1800,7 @@ export class IgxGridForOfDirective extends IgxForOfDirec changes.forEachItem((item) => { if (item.previousIndex !== null && (numRemovedItems < 2 || !identityChanges.length || identityChanges[item.currentIndex]) - && this.igxForScrollOrientation !== "horizontal") { + && this.igxForScrollOrientation !== "horizontal" && this.individualSizeCache.length > 0) { // Reuse cache on those who have previousIndex. // When there are more than one removed items currently the changes are not readable so ones with identity change // should be racalculated. diff --git a/projects/igniteui-angular/src/lib/directives/mask/mask.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/mask/mask.directive.spec.ts index 96449fc1d75..875da952d73 100644 --- a/projects/igniteui-angular/src/lib/directives/mask/mask.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/mask/mask.directive.spec.ts @@ -866,7 +866,7 @@ class PlaceholderMaskComponent { [(ngModel)]="value" [igxMask]="mask"/> `, - imports: [FormsModule, IgxInputGroupComponent, IgxInputDirective, IgxMaskDirective, InputFormatPipe, DisplayFormatPipe] + imports: [FormsModule, IgxInputGroupComponent, IgxInputDirective, IgxMaskDirective] }) class PipesMaskComponent { diff --git a/projects/igniteui-angular/src/lib/directives/scroll-inertia/scroll_inertia.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/scroll-inertia/scroll_inertia.directive.spec.ts index a4131ce589d..4cdf44f240a 100644 --- a/projects/igniteui-angular/src/lib/directives/scroll-inertia/scroll_inertia.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/scroll-inertia/scroll_inertia.directive.spec.ts @@ -4,7 +4,7 @@ import { NgZone, OnInit, ViewChild, - ElementRef + ElementRef, } from '@angular/core'; import { TestBed, ComponentFixture, fakeAsync, tick, waitForAsync } from '@angular/core/testing'; import { IgxScrollInertiaDirective } from './scroll_inertia.directive'; @@ -15,21 +15,28 @@ import { wait } from '../../test-utils/ui-interactions.spec'; describe('Scroll Inertia Directive - Rendering', () => { let fix: ComponentFixture; - configureTestSuite(); + configureTestSuite({ checkLeaks: true }); beforeAll(waitForAsync(() => { TestBed.configureTestingModule({ imports: [ IgxTestScrollInertiaDirective, ScrollInertiaComponent ] - }).compileComponents().then(() => { - fix = TestBed.createComponent(ScrollInertiaComponent); - fix.detectChanges(); - }); + }).compileComponents(); })); - it('should initialize directive on non-scrollable container.', () => { + beforeEach(() => { + fix = TestBed.createComponent(ScrollInertiaComponent); + fix.detectChanges(); + }); + + afterEach(() => { + fix = null; + }); + + it('should initialize directive on non-scrollable container.', async () => { expect(fix.componentInstance.scrInertiaDir).toBeDefined('scroll inertia initializing through markup failed'); + await fix.whenStable(); }); // Unit tests for inertia function. @@ -89,6 +96,10 @@ describe('Scroll Inertia Directive - Scrolling', () => { scrollInertiaDir.smoothingDuration = 0; }); + afterEach(() => { + scrollInertiaDir.ngOnDestroy(); + }); + // Unit test for wheel - wheelDelataY/wheelDeltaX supported on Chrome, Safari, Opera. it('should change scroll top for related scrollbar if onWheel is executed with wheelDeltaY.', () => { scrollInertiaDir.IgxScrollInertiaDirection = 'vertical'; @@ -336,7 +347,7 @@ export class IgxTestScrollInertiaDirective extends IgxScrollInertiaDirective {
-
+
`, @@ -358,10 +369,6 @@ export class ScrollInertiaComponent implements OnInit { public ngOnInit() { this.scrInertiaDir.IgxScrollInertiaScrollContainer = this.scrollContainer.nativeElement; - - this.scrollContainer.nativeElement.addEventListener('scroll', (evt) => { - this.onScroll(evt); - }); } public onScroll(evt) { diff --git a/projects/igniteui-angular/src/lib/directives/scroll-inertia/scroll_inertia.directive.ts b/projects/igniteui-angular/src/lib/directives/scroll-inertia/scroll_inertia.directive.ts index 2e7a0460c25..474be997a01 100644 --- a/projects/igniteui-angular/src/lib/directives/scroll-inertia/scroll_inertia.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/scroll-inertia/scroll_inertia.directive.ts @@ -69,10 +69,14 @@ export class IgxScrollInertiaDirective implements OnInit, OnDestroy { return; } const targetElem = this.parentElement; - targetElem.addEventListener('wheel', this.onWheel.bind(this), { passive: false }); - targetElem.addEventListener('touchstart', this.onTouchStart.bind(this), { passive: false }); - targetElem.addEventListener('touchmove', this.onTouchMove.bind(this), { passive: false }); - targetElem.addEventListener('touchend', this.onTouchEnd.bind(this), { passive: false }); + this.onWheel = this.onWheel.bind(this); + this.onTouchStart = this.onTouchStart.bind(this); + this.onTouchMove = this.onTouchMove.bind(this); + this.onTouchEnd = this.onTouchEnd.bind(this); + targetElem.addEventListener('wheel', this.onWheel, { passive: false }); + targetElem.addEventListener('touchstart', this.onTouchStart, { passive: false }); + targetElem.addEventListener('touchmove', this.onTouchMove, { passive: false }); + targetElem.addEventListener('touchend', this.onTouchEnd, { passive: false }); }); } diff --git a/projects/igniteui-angular/src/lib/expansion-panel/expansion-panel.spec.ts b/projects/igniteui-angular/src/lib/expansion-panel/expansion-panel.spec.ts index c743e019df5..b91939122ea 100644 --- a/projects/igniteui-angular/src/lib/expansion-panel/expansion-panel.spec.ts +++ b/projects/igniteui-angular/src/lib/expansion-panel/expansion-panel.spec.ts @@ -1348,7 +1348,7 @@ export class IgxExpansionPanelGridComponent {
`, - imports: [IgxExpansionPanelComponent, IgxExpansionPanelHeaderComponent, IgxExpansionPanelBodyComponent, IgxListComponent, IgxListItemComponent, IgxExpansionPanelTitleDirective, IgxExpansionPanelDescriptionDirective] + imports: [IgxExpansionPanelComponent, IgxExpansionPanelHeaderComponent, IgxExpansionPanelBodyComponent, IgxListComponent, IgxListItemComponent, IgxExpansionPanelTitleDirective] }) export class IgxExpansionPanelListComponent { @ViewChild(IgxExpansionPanelHeaderComponent, { read: IgxExpansionPanelHeaderComponent, static: true }) diff --git a/projects/igniteui-angular/src/lib/grids/columns/column.component.ts b/projects/igniteui-angular/src/lib/grids/columns/column.component.ts index 94ecf6ca9ff..dce87662e5b 100644 --- a/projects/igniteui-angular/src/lib/grids/columns/column.component.ts +++ b/projects/igniteui-angular/src/lib/grids/columns/column.component.ts @@ -524,8 +524,14 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy */ @WatchColumnChanges() @Input() - public maxWidth: string; + public set maxWidth(value: string) { + this._maxWidth = value; + this.grid.notifyChanges(true); + } + public get maxWidth(): string { + return this._maxWidth; + } /** * Sets/gets the class selector of the column header. * ```typescript @@ -938,6 +944,15 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy return isPercentageWidth ? parseFloat(this.minWidth) / 100 * gridAvailableSize : parseFloat(this.minWidth); } + /** + * @hidden + */ + public get userSetMinWidthPx() { + const gridAvailableSize = this.grid.calcWidth; + const isPercentageWidth = this._defaultMinWidth && typeof this._defaultMinWidth === 'string' && this._defaultMinWidth.indexOf('%') !== -1; + return isPercentageWidth ? parseFloat(this._defaultMinWidth) / 100 * gridAvailableSize : parseFloat(this._defaultMinWidth); + } + /** * @hidden */ @@ -969,7 +984,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy return; } this._defaultMinWidth = value; - + this.grid.notifyChanges(true); } public get minWidth(): string { return !this._defaultMinWidth ? this.defaultMinWidth : this._defaultMinWidth; @@ -1407,7 +1422,8 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy return this.grid.dataView .map((rec, index) => { if (!this.grid.isGroupByRecord(rec) && !this.grid.isSummaryRow(rec)) { - this.grid.pagingMode === 1 && this.grid.page !== 0 ? index = index + this.grid.perPage * this.grid.page : index = this.grid.dataRowList.first.index + index; + this.grid.pagingMode === 'remote' && this.grid.page !== 0 ? + index = index + this.grid.perPage * this.grid.page : index = this.grid.dataRowList.first.index + index; const cell = new IgxGridCell(this.grid as any, index, this); return cell; } @@ -1737,6 +1753,11 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy */ public destroy$ = new Subject(); + /** + * @hidden + */ + public widthConstrained = false; + /** * @hidden */ @@ -1811,6 +1832,10 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy * @hidden */ protected _defaultMinWidth = ''; + /** + * @hidden + */ + protected _maxWidth; /** * @hidden */ @@ -2096,7 +2121,8 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy if (size && !!size.width) { result.push(size.width + 'px'); } else { - result.push(parseFloat(this.grid.getPossibleColumnWidth()) + 'px'); + const currentWidth = parseFloat(this.grid.getPossibleColumnWidth()); + result.push((this.getConstrainedSizePx(currentWidth)) + 'px'); } } return result; @@ -2558,6 +2584,23 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy return res.join(' '); } + /** + * @hidden + * @internal + */ + public getConstrainedSizePx(newSize){ + if (this.maxWidth && newSize > this.maxWidthPx) { + this.widthConstrained = true; + return this.maxWidthPx; + } else if (this.minWidth && newSize < this.userSetMinWidthPx) { + this.widthConstrained = true; + return this.userSetMinWidthPx; + } else { + this.widthConstrained = false; + return newSize; + } + } + /** * @hidden * @internal @@ -2567,14 +2610,17 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy const isPercentageWidth = colWidth && typeof colWidth === 'string' && colWidth.indexOf('%') !== -1; const isAutoWidth = colWidth && typeof colWidth === 'string' && colWidth === 'fit-content'; if (isPercentageWidth && this.grid.isColumnWidthSum) { - this._calcWidth = this.grid.minColumnWidth; + this._calcWidth = this.userSetMinWidthPx ? this.userSetMinWidthPx : this.grid.minColumnWidth; } else if (isPercentageWidth) { - this._calcWidth = parseFloat(colWidth) / 100 * this.grid.calcWidth; + const currentCalcWidth = parseFloat(colWidth) / 100 * this.grid.calcWidth; + this._calcWidth = this.grid.calcWidth ? this.getConstrainedSizePx(currentCalcWidth) : 0; } else if (!colWidth || isAutoWidth && !this.autoSize) { // no width - this._calcWidth = this.defaultWidth || this.grid.getPossibleColumnWidth(); + const currentCalcWidth = this.defaultWidth || this.grid.getPossibleColumnWidth(); + this._calcWidth = this.getConstrainedSizePx(currentCalcWidth); } else { - this._calcWidth = this.width; + const currentCalcWidth = parseFloat(this.width); + this._calcWidth =this.getConstrainedSizePx(currentCalcWidth); } this.calcPixelWidth = parseFloat(this._calcWidth); } diff --git a/projects/igniteui-angular/src/lib/grids/common/enums.ts b/projects/igniteui-angular/src/lib/grids/common/enums.ts index 753b05d512d..233b42b1a06 100644 --- a/projects/igniteui-angular/src/lib/grids/common/enums.ts +++ b/projects/igniteui-angular/src/lib/grids/common/enums.ts @@ -103,16 +103,16 @@ export enum RowPinningPosition { Bottom } -/* mustCoerceToInt */ /** * Enumeration representing different paging modes for the grid. * - Local: The grid will use local data to extract pages during paging. * - Remote: The grid will expect pages to be delivered from a remote location and will only raise events during paging interactions. */ -export enum GridPagingMode { - Local, - Remote -} +export const GridPagingMode = /*@__PURE__*/mkenum({ + Local: 'local', + Remote: 'remote' +}); +export type GridPagingMode = (typeof GridPagingMode)[keyof typeof GridPagingMode]; /** * @hidden @internal 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 f0ea80c2def..3c8d8aa4f38 100644 --- a/projects/igniteui-angular/src/lib/grids/common/grid.interface.ts +++ b/projects/igniteui-angular/src/lib/grids/common/grid.interface.ts @@ -1497,4 +1497,5 @@ export interface IClipboardOptions { export interface EntityType { name: string; fields: FieldType[]; + childEntities?: EntityType[]; } diff --git a/projects/igniteui-angular/src/lib/grids/common/random.spec.ts b/projects/igniteui-angular/src/lib/grids/common/random.spec.ts new file mode 100644 index 00000000000..05da7a0e090 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/common/random.spec.ts @@ -0,0 +1,26 @@ +import { getUUID } from './random'; + +describe('Random (crypto.randomUuid()) fallback unit tests', () => { + let originalRandomUuid = crypto.randomUUID; + + beforeAll(() => { + crypto.randomUUID = null; // Mock crypto.randomUUID to simulate a non-secure context + }); + + it('should generate a valid UUID', () => { + const uuid = getUUID(); + expect(uuid).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/); + }); + + it('should generate unique UUIDs', () => { + const uuids = new Set(); + for (let i = 0; i < 100; i++) { + uuids.add(getUUID()); + } + expect(uuids.size).toBe(100); // All UUIDs should be unique + }); + + afterAll(() => { + crypto.randomUUID = originalRandomUuid; // Restore the original function + }); +}); \ No newline at end of file diff --git a/projects/igniteui-angular/src/lib/grids/common/random.ts b/projects/igniteui-angular/src/lib/grids/common/random.ts new file mode 100644 index 00000000000..4c7d0684653 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/common/random.ts @@ -0,0 +1,19 @@ +/** + * Use the function to get a random UUID string when secure context is not guaranteed making crypto.randomUUID unavailable. + * @returns A random UUID string. + */ +export function getUUID(): `${string}-${string}-${string}-${string}-${string}` { + if (typeof crypto.randomUUID === 'function') { + return crypto.randomUUID(); + } + // Secure fallback using crypto.getRandomValues() + const bytes = new Uint8Array(16); + crypto.getRandomValues(bytes); + + // Set version (4) and variant (RFC 4122) + bytes[6] = (bytes[6] & 0x0f) | 0x40; // Version 4 + bytes[8] = (bytes[8] & 0x3f) | 0x80; // Variant 1 + + const a = [...bytes].map((b) => b.toString(16).padStart(2, '0')).join(''); + return `${a.slice(0, 8)}-${a.slice(8, 12)}-${a.slice(12, 16)}-${a.slice(16, 20)}-${a.slice(20)}`; +} diff --git a/projects/igniteui-angular/src/lib/grids/filtering/advanced-filtering/advanced-filtering-dialog.component.ts b/projects/igniteui-angular/src/lib/grids/filtering/advanced-filtering/advanced-filtering-dialog.component.ts index 3a733ddd475..e98253b688d 100644 --- a/projects/igniteui-angular/src/lib/grids/filtering/advanced-filtering/advanced-filtering-dialog.component.ts +++ b/projects/igniteui-angular/src/lib/grids/filtering/advanced-filtering/advanced-filtering-dialog.component.ts @@ -6,7 +6,7 @@ import { IDragStartEventArgs, IgxDragDirective, IgxDragHandleDirective } from '. import { Subject } from 'rxjs'; import { IActiveNode } from '../../grid-navigation.service'; import { PlatformUtil } from '../../../core/utils'; -import { FieldType, GridType } from '../../common/grid.interface'; +import { EntityType, FieldType, GridType } from '../../common/grid.interface'; import { IgxQueryBuilderComponent } from '../../../query-builder/query-builder.component'; import { GridResourceStringsEN } from '../../../core/i18n/grid-resources'; import { IFilteringExpressionsTree } from '../../../data-operations/filtering-expressions-tree'; @@ -15,6 +15,8 @@ import { IgxQueryBuilderHeaderComponent } from '../../../query-builder/query-bui import { NgClass } from '@angular/common'; import { getCurrentResourceStrings } from '../../../core/i18n/resources'; import { QueryBuilderResourceStringsEN } from '../../../core/i18n/query-builder-resources'; +import { IgxHierarchicalGridComponent } from '../../hierarchical-grid/hierarchical-grid.component'; +import { IgxRowIslandComponent } from '../../hierarchical-grid/row-island.component'; /** * A component used for presenting advanced filtering UI for a Grid. @@ -191,18 +193,33 @@ export class IgxAdvancedFilteringDialogComponent implements AfterViewInit, OnDes this.closeDialog(); } - /** * @hidden @internal */ public generateEntity() { - const entities = [ - { - name: null, - fields: this.filterableFields - } - ]; - return entities; + if (this.queryBuilder?.entities) { + return this.queryBuilder?.entities; + } else if (this.grid.type === 'hierarchical') { + return (this.grid as IgxHierarchicalGridComponent).schema; + } else { + const entities: EntityType[] = [ + { + name: null, + fields: this.filterableFields.map(f => ({ + field: f.field, + dataType: f.dataType, + // label: f.label, + // header: f.header, + editorOptions: f.editorOptions, + filters: f.filters, + pipeArgs: f.pipeArgs, + defaultTimeFormat: f.defaultTimeFormat, + defaultDateTimeFormat: f.defaultDateTimeFormat + })) as FieldType[] + } + ]; + return entities; + } } private assignResourceStrings() { diff --git a/projects/igniteui-angular/src/lib/grids/filtering/excel-style/common.ts b/projects/igniteui-angular/src/lib/grids/filtering/excel-style/common.ts index d48448c1f46..31b38405266 100644 --- a/projects/igniteui-angular/src/lib/grids/filtering/excel-style/common.ts +++ b/projects/igniteui-angular/src/lib/grids/filtering/excel-style/common.ts @@ -1,6 +1,7 @@ import { isTree } from '../../../data-operations/expressions-tree-util'; import { FilteringLogic, IFilteringExpression } from '../../../data-operations/filtering-expression.interface'; import { IFilteringExpressionsTree } from '../../../data-operations/filtering-expressions-tree'; +import { getUUID } from '../../common/random'; /** * @hidden @internal @@ -30,7 +31,7 @@ export class ExpressionUI { constructor() { // Use IDs to identify expressions clearly and use to track them in template @for cycles. - this.expressionId = crypto.randomUUID(); + this.expressionId = getUUID(); } } 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 0b346c079b5..fb89132ee38 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -4,6 +4,7 @@ import { AfterViewInit, booleanAttribute, ChangeDetectorRef, + ComponentRef, ContentChild, ContentChildren, createComponent, @@ -146,7 +147,8 @@ import { ISizeInfo, RowType, IPinningConfig, - IClipboardOptions + IClipboardOptions, + EntityType } from './common/grid.interface'; import { DropPosition } from './moving/moving.service'; import { IgxHeadSelectorDirective, IgxRowSelectorDirective } from './selection/row-selectors'; @@ -178,7 +180,8 @@ import { DefaultDataCloneStrategy, IDataCloneStrategy } from '../data-operations import { IgxGridCellComponent } from './cell.component'; import { IgxGridValidationService } from './grid/grid-validation.service'; import { getCurrentResourceStrings } from '../core/i18n/resources'; -import { isTree, recreateTreeFromFields } from '../data-operations/expressions-tree-util'; +import { isTree, recreateTree, recreateTreeFromFields } from '../data-operations/expressions-tree-util'; +import { getUUID } from './common/random'; interface IMatchInfoCache { row: any; @@ -260,7 +263,7 @@ export abstract class IgxGridBaseDirective implements GridType, * ``` */ @Input() - public emptyGridTemplate: TemplateRef; + public emptyGridTemplate: TemplateRef; /** * Gets/Sets a custom template for adding row UI when grid is empty. @@ -282,7 +285,7 @@ export abstract class IgxGridBaseDirective implements GridType, * ``` */ @Input() - public loadingGridTemplate: TemplateRef; + public loadingGridTemplate: TemplateRef; /** * Get/Set IgxSummaryRow height @@ -1857,7 +1860,7 @@ export abstract class IgxGridBaseDirective implements GridType, value.type = FilteringExpressionsTreeType.Regular; if (value && this._columns?.length > 0) { - this._filteringExpressionsTree = recreateTreeFromFields(value, this._columns) as IFilteringExpressionsTree; + this._filteringExpressionsTree = this.getRecreatedTree(value); } else { this._filteringExpressionsTree = value; } @@ -1907,7 +1910,7 @@ export abstract class IgxGridBaseDirective implements GridType, if (value && isTree(value)) { value.type = FilteringExpressionsTreeType.Advanced; if (this._columns && this._columns.length > 0) { - this._advancedFilteringExpressionsTree = recreateTreeFromFields(value, this._columns) as IFilteringExpressionsTree; + this._advancedFilteringExpressionsTree = this.getRecreatedTree(value); } else { this._advancedFilteringExpressionsTree = value; } @@ -3050,7 +3053,7 @@ export abstract class IgxGridBaseDirective implements GridType, /** * @hidden */ - protected _pagingMode = GridPagingMode.Local; + protected _pagingMode: GridPagingMode = 'local'; /** * @hidden */ @@ -3125,6 +3128,7 @@ export abstract class IgxGridBaseDirective implements GridType, protected _sortingOptions: ISortingOptions = { mode: 'multiple' }; protected _filterStrategy: IFilteringStrategy = new FilteringStrategy(); protected _autoGeneratedCols = []; + protected _autoGeneratedColsRefs: ComponentRef[] = []; protected _dataView = []; protected _lastSearchInfo: ISearchInfo = { searchText: '', @@ -3135,6 +3139,7 @@ export abstract class IgxGridBaseDirective implements GridType, matchCount: 0, content: '' }; + protected _hGridSchema: EntityType[]; protected gridComputedStyles; /** @hidden @internal */ @@ -3361,12 +3366,26 @@ export abstract class IgxGridBaseDirective implements GridType, private get hasZeroResultFilter(): boolean { return this.filteredData && this.filteredData.length === 0; } + protected get totalCalcWidth() { + return this.platform.isBrowser ? this.calcWidth : undefined; + } + + protected get renderData() { + // omit data if not in the browser and size is % + return !this.platform.isBrowser && this.isPercentHeight ? undefined : this.data; + } + + @HostBinding('style.display') + protected displayStyle = 'grid'; + + @HostBinding('style.grid-template-rows') + protected templateRows = 'auto auto auto 1fr auto auto'; /** * @hidden @internal */ private get hasNoData(): boolean { - return !this.data || this.dataLength === 0; + return !this.data || this.dataLength === 0 || !this.platform.isBrowser; } /** @@ -3765,7 +3784,7 @@ export abstract class IgxGridBaseDirective implements GridType, this._setupListeners(); this.rowListDiffer = this.differs.find([]).create(null); // compare based on field, not on object ref. - this.columnListDiffer = this.differs.find([]).create((index, col: ColumnType) => col.field); + this.columnListDiffer = this.differs.find([]).create((_index, col: ColumnType) => col.field); this.calcWidth = this.width && this.width.indexOf('%') === -1 ? parseInt(this.width, 10) : 0; this.gridComputedStyles = this.document.defaultView.getComputedStyle(this.nativeElement); } @@ -3785,7 +3804,7 @@ export abstract class IgxGridBaseDirective implements GridType, const primaryColumn = this._columns.find(col => col.field === this.primaryKey); const idType = this.data.length ? this.resolveDataTypes(this.data[0][this.primaryKey]) : primaryColumn ? primaryColumn.dataType : 'string'; - return idType === 'string' ? crypto.randomUUID() : FAKE_ROW_ID--; + return idType === 'string' ? getUUID() : FAKE_ROW_ID--; } /** @@ -3924,7 +3943,9 @@ export abstract class IgxGridBaseDirective implements GridType, /** @hidden @internal */ public setUpPaginator() { if (this.paginator) { - this.paginator.pageChange.pipe(takeWhile(() => !!this.paginator), filter(() => !this._init)) + this.paginator.pageChange + .pipe(takeWhile(() => !!this.paginator), filter(() => !this._init)) + .pipe(takeUntil(this.destroy$)) .subscribe(() => { this.selectionService.clear(true); this.crudService.endEdit(false); @@ -3932,7 +3953,9 @@ export abstract class IgxGridBaseDirective implements GridType, this.navigateTo(0); this.notifyChanges(); }); - this.paginator.perPageChange.pipe(takeWhile(() => !!this.paginator), filter(() => !this._init)) + this.paginator.perPageChange + .pipe(takeWhile(() => !!this.paginator), filter(() => !this._init)) + .pipe(takeUntil(this.destroy$)) .subscribe(() => { this.selectionService.clear(true); this.page = 0; @@ -4000,8 +4023,10 @@ export abstract class IgxGridBaseDirective implements GridType, */ public _zoneBegoneListeners() { this.zone.runOutsideAngular(() => { - this.verticalScrollContainer.getScroll().addEventListener('scroll', this.verticalScrollHandler.bind(this)); - this.headerContainer?.getScroll().addEventListener('scroll', this.horizontalScrollHandler.bind(this)); + this.verticalScrollHandler = this.verticalScrollHandler.bind(this); + this.horizontalScrollHandler = this.horizontalScrollHandler.bind(this); + this.verticalScrollContainer.getScroll().addEventListener('scroll', this.verticalScrollHandler); + this.headerContainer?.getScroll().addEventListener('scroll', this.horizontalScrollHandler); if (this.hasColumnsToAutosize) { this.headerContainer?.dataChanged.pipe(takeUntil(this.destroy$)).subscribe(() => { this.cdr.detectChanges(); @@ -4029,7 +4054,7 @@ export abstract class IgxGridBaseDirective implements GridType, this._zoneBegoneListeners(); const vertScrDC = this.verticalScrollContainer.displayContainer; - vertScrDC.addEventListener('scroll', this.preventContainerScroll.bind(this)); + vertScrDC.addEventListener('scroll', this.preventContainerScroll); this._pinnedRowList.changes .pipe(takeUntil(this.destroy$)) @@ -4104,6 +4129,8 @@ export abstract class IgxGridBaseDirective implements GridType, this.tmpOutlets.forEach((tmplOutlet) => { tmplOutlet.cleanCache(); }); + this._autoGeneratedColsRefs.forEach(ref => ref.destroy()); + this._autoGeneratedColsRefs = []; this.destroy$.next(true); this.destroy$.complete(); @@ -4598,7 +4625,7 @@ export abstract class IgxGridBaseDirective implements GridType, */ protected _getDataViewIndex(index: number): number { let newIndex = index; - if ((index < 0 || index >= this.dataView.length) && this.pagingMode === 1 && this.page !== 0) { + if ((index < 0 || index >= this.dataView.length) && this.pagingMode === 'remote' && this.page !== 0) { newIndex = index - this.perPage * this.page; } else if (this.gridAPI.grid.verticalScrollContainer.isRemote) { newIndex = index - this.gridAPI.grid.virtualizationState.startIndex; @@ -5158,7 +5185,8 @@ export abstract class IgxGridBaseDirective implements GridType, /** @hidden @internal */ public get totalHeight() { - return this.calcHeight ? this.calcHeight + this.pinnedRowHeight : this.calcHeight; + const height = this.calcHeight ? this.calcHeight + this.pinnedRowHeight : this.calcHeight; + return this.platform.isBrowser ? height : undefined; } /** @@ -5424,14 +5452,15 @@ export abstract class IgxGridBaseDirective implements GridType, const columnsWithSetWidths = this.hasColumnLayouts ? visibleCols.filter(c => c.widthSetByUser) : - visibleChildColumns.filter(c => c.widthSetByUser && c.width !== 'fit-content'); + visibleChildColumns.filter(c => (c.widthSetByUser || c.widthConstrained) && c.width !== 'fit-content'); const columnsToSize = this.hasColumnLayouts ? combinedBlocksSize - columnsWithSetWidths.length : visibleChildColumns.length - columnsWithSetWidths.length; const sumExistingWidths = columnsWithSetWidths .reduce((prev, curr) => { - const colWidth = curr.width; + const colInstance = this.hasColumnLayouts ? curr.ref : curr; + const colWidth = !colInstance.widthConstrained ? curr.width : colInstance.calcPixelWidth; let widthValue = parseFloat(colWidth); if (isNaN(widthValue)) { widthValue = MINIMUM_COLUMN_WIDTH; @@ -5439,7 +5468,9 @@ export abstract class IgxGridBaseDirective implements GridType, const currWidth = colWidth && typeof colWidth === 'string' && colWidth.indexOf('%') !== -1 ? widthValue / 100 * computedWidth : widthValue; - return prev + currWidth; + // apply constraints, since constraint may change width + const constrainedWidth = this.hasColumnLayouts ? currWidth : colInstance.getConstrainedSizePx(currWidth); + return prev + constrainedWidth; }, 0); // When all columns are hidden, return 0px width @@ -6091,7 +6122,7 @@ export abstract class IgxGridBaseDirective implements GridType, /** * @hidden @internal */ - public trackColumnChanges(index, col) { + public trackColumnChanges(_index, col) { return col.field + col._calcWidth; } @@ -6110,7 +6141,7 @@ export abstract class IgxGridBaseDirective implements GridType, this.configureRowEditingOverlay(id, this.rowList.length <= MIN_ROW_EDITING_COUNT_THRESHOLD); this.rowEditingOverlay.open(this.rowEditSettings); - this.rowEditingOverlay.element.addEventListener('wheel', this.rowEditingWheelHandler.bind(this)); + this.rowEditingOverlay.element.addEventListener('wheel', this.rowEditingWheelHandler); } /** @@ -6242,7 +6273,7 @@ export abstract class IgxGridBaseDirective implements GridType, /** * @hidden */ - public rowEditingWheelHandler(event: WheelEvent) { + public rowEditingWheelHandler = (event: WheelEvent) => { if (event.deltaY > 0) { this.verticalScrollContainer.scrollNext(); } else { @@ -6555,7 +6586,7 @@ export abstract class IgxGridBaseDirective implements GridType, if (width && typeof width !== 'string') { width = String(width); } - const minWidth = width.indexOf('%') === -1 ? column.minWidthPx : column.minWidthPercent; + const minWidth = width.indexOf('%') === -1 ? column.userSetMinWidthPx : column.minWidthPercent; const maxWidth = width.indexOf('%') === -1 ? column.maxWidthPx : column.maxWidthPercent; if (column.hidden) { return width; @@ -6608,11 +6639,11 @@ export abstract class IgxGridBaseDirective implements GridType, .filter((c) => c.pinned); this._unpinnedColumns = newColumns.filter((c) => !c.pinned); this._columns = newColumns; - if (this._columns && this._filteringExpressionsTree) { - this._filteringExpressionsTree = recreateTreeFromFields(this._filteringExpressionsTree, this.columns) as IFilteringExpressionsTree; + if (this._columns && this._columns.length && this._filteringExpressionsTree) { + this._filteringExpressionsTree = this.getRecreatedTree(this._filteringExpressionsTree); } - if (this._columns && this._advancedFilteringExpressionsTree) { - this._advancedFilteringExpressionsTree = recreateTreeFromFields(this._advancedFilteringExpressionsTree, this.columns) as IFilteringExpressionsTree; + if (this._columns && this._columns.length && this._advancedFilteringExpressionsTree) { + this._advancedFilteringExpressionsTree = this.getRecreatedTree(this._advancedFilteringExpressionsTree); } this.resetCaches(); } @@ -6676,11 +6707,11 @@ export abstract class IgxGridBaseDirective implements GridType, } else { this._columns = this.getColumnList(); } - if (this._columns && this._filteringExpressionsTree) { - this._filteringExpressionsTree = recreateTreeFromFields(this._filteringExpressionsTree, this._columns) as IFilteringExpressionsTree; + if (this._columns && this._columns.length && this._filteringExpressionsTree) { + this._filteringExpressionsTree = this.getRecreatedTree(this._filteringExpressionsTree); } - if (this._columns && this._advancedFilteringExpressionsTree) { - this._advancedFilteringExpressionsTree = recreateTreeFromFields(this._advancedFilteringExpressionsTree, this._columns) as IFilteringExpressionsTree; + if (this._columns && this._columns.length && this._advancedFilteringExpressionsTree) { + this._advancedFilteringExpressionsTree = this.getRecreatedTree(this._advancedFilteringExpressionsTree); } this.initColumns(this._columns, (col: IgxColumnComponent) => this.columnInit.emit(col)); @@ -7099,11 +7130,14 @@ export abstract class IgxGridBaseDirective implements GridType, const fields = this.generateDataFields(data); const columns = []; + this._autoGeneratedColsRefs.forEach(ref => ref.destroy()); + this._autoGeneratedColsRefs = []; fields.forEach((field) => { const ref = createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector }); ref.instance.field = field; ref.instance.dataType = this.resolveDataTypes(data[0][field]); ref.changeDetectorRef.detectChanges(); + this._autoGeneratedColsRefs.push(ref); columns.push(ref.instance); }); this._autoGeneratedCols = columns; @@ -7236,7 +7270,7 @@ export abstract class IgxGridBaseDirective implements GridType, // eslint-disable-next-line prefer-const for (let [row, set] of selectionMap) { - row = this.paginator && (this.pagingMode === GridPagingMode.Local && source === this.filteredSortedData) ? row + (this.perPage * this.page) : row; + row = this.paginator && (this.pagingMode === 'local' && source === this.filteredSortedData) ? row + (this.perPage * this.page) : row; row = isRemote ? row - this.virtualizationState.startIndex : row; if (!source[row] || source[row].detailsData !== undefined) { continue; @@ -7343,8 +7377,8 @@ export abstract class IgxGridBaseDirective implements GridType, let maxSize = Math.ceil(Math.max(...cellsContentWidths)) + 1; if (col.maxWidth && maxSize > col.maxWidthPx) { maxSize = col.maxWidthPx; - } else if (maxSize < col.minWidthPx) { - maxSize = col.minWidthPx; + } else if (maxSize < col.userSetMinWidthPx) { + maxSize = col.userSetMinWidthPx; } col.autoSize = maxSize; col.resetCaches(); @@ -7411,7 +7445,7 @@ export abstract class IgxGridBaseDirective implements GridType, } if (delayScrolling) { - this.verticalScrollContainer.dataChanged.pipe(first()).subscribe(() => { + this.verticalScrollContainer.dataChanged.pipe(first(), takeUntil(this.destroy$)).subscribe(() => { this.scrollDirective(this.verticalScrollContainer, typeof (row) === 'number' ? row : this.unpinnedDataView.indexOf(row)); }); @@ -7565,7 +7599,7 @@ export abstract class IgxGridBaseDirective implements GridType, let row = this.summariesRowList.filter(s => s.index !== 0).concat(this.rowList.toArray()).find(r => r.index === rowIndex); if (!row) { if ((this as any).totalItemCount) { - this.verticalScrollContainer.dataChanged.pipe(first()).subscribe(() => { + this.verticalScrollContainer.dataChanged.pipe(first(), takeUntil(this.destroy$)).subscribe(() => { this.cdr.detectChanges(); row = this.summariesRowList.filter(s => s.index !== 0).concat(this.rowList.toArray()).find(r => r.index === rowIndex); const cbArgs = this.getNavigationArguments(row, visibleColIndex); @@ -7615,7 +7649,7 @@ export abstract class IgxGridBaseDirective implements GridType, } // find next/prev record that is editable. const nextRowIndex = previous ? this.findPrevEditableDataRowIndex(currentRowIndex) : - this.dataView.findIndex((rec, index) => + this.dataView.findIndex((_rec, index) => index > resolvedIndex && this.isEditableDataRecordAtIndex(index)); const nextDataIndex = this.getDataIndex(nextRowIndex); return nextDataIndex !== -1 ? nextDataIndex : currentRowIndex; @@ -7890,4 +7924,12 @@ export abstract class IgxGridBaseDirective implements GridType, this.navigation.activeNode = {} as IActiveNode; this.notifyChanges(); } + + private getRecreatedTree(value: IFilteringExpressionsTree): IFilteringExpressionsTree { + if (this._hGridSchema) { + return recreateTree(value, this._hGridSchema, true) as IFilteringExpressionsTree; + } else { + return recreateTreeFromFields(value, this._columns) as IFilteringExpressionsTree; + } + } } diff --git a/projects/igniteui-angular/src/lib/grids/grid/column.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/column.spec.ts index b63728b1b98..7f4ee5f57d5 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/column.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/column.spec.ts @@ -1564,7 +1564,8 @@ describe('IgxGrid - Column properties #grid', () => { tick(); let widths = grid.columns.map(x => x.width); - expect(widths).toEqual(['80px', '130px', '121px', '114px', '92px', '80px', '86px', '108px', '82px', '80px']); + // default min of 80px is disregarded for user-set widths, including auto. + expect(widths).toEqual(['68px', '130px', '121px', '114px', '92px', '72px', '86px', '108px', '82px', '69px']); fix.componentInstance.data = SampleTestData.contactInfoData(); fix.detectChanges(); tick(); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts index 9fb2b661cfe..8e591807f24 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts @@ -20,7 +20,7 @@ import { IgxGridAdvancedFilteringWithToolbarComponent } from '../../test-utils/grid-samples.spec'; import { FormattedValuesFilteringStrategy } from '../../data-operations/filtering-strategy'; -import { IgxHierGridExternalAdvancedFilteringComponent } from '../../test-utils/hierarchical-grid-components.spec'; +import { IgxHierarchicalGridExportComponent, IgxHierarchicalGridTestBaseComponent, IgxHierGridExternalAdvancedFilteringComponent } from '../../test-utils/hierarchical-grid-components.spec'; import { IgxHierarchicalGridComponent } from '../hierarchical-grid/public_api'; import { IFilteringEventArgs, IgxGridToolbarAdvancedFilteringComponent } from '../public_api'; import { SampleTestData } from '../../test-utils/sample-test-data.spec'; @@ -28,6 +28,7 @@ import { QueryBuilderFunctions } from '../../query-builder/query-builder-functio import { By } from '@angular/platform-browser'; import { IgxDateTimeEditorDirective } from '../../directives/date-time-editor/date-time-editor.directive'; import { QueryBuilderSelectors } from '../../query-builder/query-builder.common'; +import { IgxHGridRemoteOnDemandComponent } from '../hierarchical-grid/hierarchical-grid.spec'; describe('IgxGrid - Advanced Filtering #grid - ', () => { configureTestSuite((() => { @@ -40,7 +41,10 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => { IgxGridAdvancedFilteringBindingComponent, IgxHierGridExternalAdvancedFilteringComponent, IgxGridAdvancedFilteringDynamicColumnsComponent, - IgxGridAdvancedFilteringWithToolbarComponent + IgxGridAdvancedFilteringWithToolbarComponent, + IgxHierarchicalGridTestBaseComponent, + IgxHierarchicalGridExportComponent, + IgxHGridRemoteOnDemandComponent ] }); })); @@ -637,9 +641,9 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => { fix.detectChanges(); const dropdownItems = QueryBuilderFunctions.getQueryBuilderSelectDropdownItems(queryBuilderElement); expect(dropdownItems.length).toBe(4); - expect((dropdownItems[0] as HTMLElement).innerText).toBe('HeaderID'); + expect((dropdownItems[0] as HTMLElement).innerText).toBe('ID'); expect((dropdownItems[1] as HTMLElement).innerText).toBe('ProductName'); - expect((dropdownItems[2] as HTMLElement).innerText).toBe('Another Field'); + expect((dropdownItems[2] as HTMLElement).innerText).toBe('AnotherField'); expect((dropdownItems[3] as HTMLElement).innerText).toBe('ReleaseTime'); })); @@ -1292,7 +1296,7 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => { QueryBuilderFunctions.selectColumnInEditModeExpression(fix, 1); // Select 'ProductName' column. QueryBuilderFunctions.selectOperatorInEditModeExpression(fix, 0); // Select 'Contains' operator. - let input = QueryBuilderFunctions.getQueryBuilderValueInput(fix).querySelector('input'); + const input = QueryBuilderFunctions.getQueryBuilderValueInput(fix).querySelector('input'); UIInteractions.clickAndSendInputElementValue(input, 'angular', fix); // Type filter value. // Commit the populated expression. QueryBuilderFunctions.clickQueryBuilderExpressionCommitButton(fix); @@ -1328,7 +1332,7 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => { QueryBuilderFunctions.clickQueryBuilderColumnSelect(fix); fix.detectChanges(); const dropdownValues = QueryBuilderFunctions.getQueryBuilderSelectDropdownItems(queryBuilderElement).map((x: any) => x.innerText); - const expectedValues = ['ID', 'ProductName', 'Downloads', 'Released', 'ReleaseDate', 'Another Field', 'DateTimeCreated']; + const expectedValues = ['ID', 'ProductName', 'Downloads', 'Released', 'ReleaseDate', 'AnotherField', 'DateTimeCreated']; expect(expectedValues).toEqual(dropdownValues); })); }); @@ -1455,11 +1459,17 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => { }); describe('Expression tree rehydration - ', () => { + let fix: ComponentFixture; + let grid: IgxGridComponent; + + beforeEach(fakeAsync(() => { + fix = TestBed.createComponent(IgxGridAdvancedFilteringSerializedTreeComponent); + grid = fix.componentInstance.grid; + fix.detectChanges(); + })); + it('should correctly filter with a deserialized expression tree.', fakeAsync(() => { const errorSpy = spyOn(console, 'error'); - let fix = TestBed.createComponent(IgxGridAdvancedFilteringSerializedTreeComponent); - fix.detectChanges(); - let grid = fix.componentInstance.grid; expect(errorSpy).not.toHaveBeenCalled(); @@ -1470,12 +1480,8 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => { it('should correctly filter with a declared IFilteringExpressionsTree object.', fakeAsync(() => { const errorSpy = spyOn(console, 'error'); - let fix = TestBed.createComponent(IgxGridAdvancedFilteringSerializedTreeComponent); - fix.detectChanges(); fix.componentInstance.grid.advancedFilteringExpressionsTree = fix.componentInstance.filterTreeObject; fix.detectChanges(); - let grid = fix.componentInstance.grid; - expect(errorSpy).not.toHaveBeenCalled(); // Verify filtered data @@ -1485,11 +1491,8 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => { it('should correctly filter when binding to a declared IFilteringExpressionsTree object.', fakeAsync(() => { const errorSpy = spyOn(console, 'error'); - let fix = TestBed.createComponent(IgxGridAdvancedFilteringSerializedTreeComponent); - fix.detectChanges(); fix.componentInstance.filterTree = fix.componentInstance.filterTreeObject; fix.detectChanges(); - let grid = fix.componentInstance.grid; expect(errorSpy).not.toHaveBeenCalled(); @@ -1498,6 +1501,299 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => { expect(grid.rowList.length).toBe(2); })); }); + + describe('Hierarchical grid advanced filtering - ', () => { + let fix: ComponentFixture; + let hgrid: IgxHierarchicalGridComponent; + + beforeEach(fakeAsync(() => { + fix = TestBed.createComponent(IgxHierarchicalGridTestBaseComponent); + hgrid = fix.componentInstance.hgrid; + hgrid.allowAdvancedFiltering = true; + fix.detectChanges(); + + // Open Advanced Filtering dialog. + hgrid.openAdvancedFilteringDialog(); + fix.detectChanges(); + + // Click the initial 'Add Condition' button of the query builder. + QueryBuilderFunctions.clickQueryBuilderInitialAddConditionBtn(fix, 0); + tick(100); + fix.detectChanges(); + })); + + it(`Should have 'In'/'Not-In' operators for fields with chilld entities.`, fakeAsync(() => { + // Populate edit inputs. + QueryBuilderFunctions.selectColumnInEditModeExpression(fix, 0); // Select 'ID' column. + + // Open the operator dropdown and verify they are 'string' specific + 'In'/'Not In'. + QueryBuilderFunctions.clickQueryBuilderOperatorSelect(fix); + fix.detectChanges(); + const queryBuilderElement: HTMLElement = fix.debugElement.queryAll(By.css(`.${QueryBuilderSelectors.QUERY_BUILDER_TREE}`))[0].nativeElement; + const dropdownValues: string[] = QueryBuilderFunctions.getQueryBuilderSelectDropdownItems(queryBuilderElement).map((x: any) => x.innerText); + const expectedValues = ['Contains', 'Does Not Contain', 'Starts With', 'Ends With', 'Equals', + 'Does Not Equal', 'Empty', 'Not Empty', 'Null', 'Not Null', 'In', 'Not In'];; + expect(dropdownValues).toEqual(expectedValues); + + // Close Advanced Filtering dialog. + hgrid.closeAdvancedFilteringDialog(false); + tick(200); + fix.detectChanges(); + })); + + it(`Should NOT have 'In'/'Not-In' operators for fields without chilld entities.`, fakeAsync(() => { + // Populate edit inputs. + QueryBuilderFunctions.selectColumnInEditModeExpression(fix, 0); // Select 'ID' column. + QueryBuilderFunctions.selectOperatorInEditModeExpression(fix, 10); // Select 'In' operator. + + // Select entity in nested level + QueryBuilderFunctions.selectEntityAndClickInitialAddCondition(fix, 0, 1); + // Populate edit inputs on level 1. + QueryBuilderFunctions.selectColumnInEditModeExpression(fix, 0, 1); // Select 'ID' column. + QueryBuilderFunctions.selectOperatorInEditModeExpression(fix, 11, 1); // Select 'Not In' operator. + + // Select entity in nested level + QueryBuilderFunctions.selectEntityAndClickInitialAddCondition(fix, 0, 2); + QueryBuilderFunctions.selectColumnInEditModeExpression(fix, 0, 2); // Select 'ID' column. + // Open the operator dropdown and verify they are 'string' specific + 'In'/'Not In'. + QueryBuilderFunctions.clickQueryBuilderOperatorSelect(fix, 2); + fix.detectChanges(); + const queryBuilderElement: HTMLElement = fix.debugElement.queryAll(By.css(`.${QueryBuilderSelectors.QUERY_BUILDER_TREE}`))[2].nativeElement; + const dropdownValues: string[] = QueryBuilderFunctions.getQueryBuilderSelectDropdownItems(queryBuilderElement).map((x: any) => x.innerText); + const expectedValues = ['Contains', 'Does Not Contain', 'Starts With', 'Ends With', 'Equals', + 'Does Not Equal', 'Empty', 'Not Empty', 'Null', 'Not Null'];; + expect(dropdownValues).toEqual(expectedValues); + + // Close Advanced Filtering dialog. + hgrid.closeAdvancedFilteringDialog(false); + tick(200); + fix.detectChanges(); + })); + + it('Should have correct entities depending on the hierarchy level.', fakeAsync(() => { + // Populate edit inputs. + QueryBuilderFunctions.selectColumnInEditModeExpression(fix, 0); // Select 'ID' column. + QueryBuilderFunctions.selectOperatorInEditModeExpression(fix, 10); // Select 'In' operator. + + QueryBuilderFunctions.clickQueryBuilderEntitySelect(fix, 1); + fix.detectChanges(); + const queryBuilderElement: HTMLElement = fix.debugElement.queryAll(By.css(`.${QueryBuilderSelectors.QUERY_BUILDER_TREE}`))[1].nativeElement; + const dropdownValues: string[] = QueryBuilderFunctions.getQueryBuilderSelectDropdownItems(queryBuilderElement).map((x: any) => x.innerText); + const expectedValues = ['childData']; + expect(dropdownValues).toEqual(expectedValues); + + // Close Advanced Filtering dialog. + hgrid.closeAdvancedFilteringDialog(false); + tick(200); + fix.detectChanges(); + })); + + it(`Should apply 'In'/'Not-In' operators for each level properly.`, fakeAsync(() => { + // Populate edit inputs. + QueryBuilderFunctions.selectColumnInEditModeExpression(fix, 0); // Select 'ID' column. + QueryBuilderFunctions.selectOperatorInEditModeExpression(fix, 10); // Select 'In' operator. + tick(100); + fix.detectChanges(); + + // When there is one entity, it should be selected by default + const entityInputGroup = QueryBuilderFunctions.getQueryBuilderEntitySelect(fix, 1).querySelector('input'); + expect(entityInputGroup.value).toBe('childData'); + + const fieldInputGroup = QueryBuilderFunctions.getQueryBuilderFieldsCombo(fix, 1).querySelector('input'); + expect(fieldInputGroup.value).toBe('ID'); + + // Click the initial 'Add Condition' button. + QueryBuilderFunctions.clickQueryBuilderInitialAddConditionBtn(fix, 0); + tick(100); + fix.detectChanges(); + // Populate edit inputs on level 1. + QueryBuilderFunctions.selectColumnInEditModeExpression(fix, 0, 1); // Select 'ID' column. + QueryBuilderFunctions.selectOperatorInEditModeExpression(fix, 0, 1); // Select 'Contains' operator. + + const input = QueryBuilderFunctions.getQueryBuilderValueInput(fix, false, 1).querySelector('input'); + // Type Value + UIInteractions.clickAndSendInputElementValue(input, '39'); + tick(100); + fix.detectChanges(); + + QueryBuilderFunctions.clickQueryBuilderExpressionCommitButton(fix, 1); + fix.detectChanges(); + QueryBuilderFunctions.clickQueryBuilderExpressionCommitButton(fix, 0); + fix.detectChanges(); + // Close Advanced Filtering dialog. + hgrid.closeAdvancedFilteringDialog(true); + tick(200); + fix.detectChanges(); + + // Veify grid data + expect(hgrid.filteredData.length).toEqual(5); + expect(hgrid.rowList.length).toBe(5); + })); + + it(`Should have correct return fields in the child query when there are multiple child entities.`, fakeAsync(() => { + const fixture = TestBed.createComponent(IgxHierarchicalGridExportComponent); + const hierarchicalGrid = fixture.componentInstance.hGrid; + fixture.componentInstance.shouldDisplayArtist = true; + hierarchicalGrid.allowAdvancedFiltering = true; + fixture.detectChanges(); + + hierarchicalGrid.openAdvancedFilteringDialog(); + fixture.detectChanges(); + + // Click the initial 'Add Condition' button. + QueryBuilderFunctions.clickQueryBuilderInitialAddConditionBtn(fixture, 0); + tick(100); + fixture.detectChanges(); + // Populate edit inputs. + QueryBuilderFunctions.selectColumnInEditModeExpression(fixture, 0); // Select 'Artist' column. + QueryBuilderFunctions.selectOperatorInEditModeExpression(fixture, 10); // Select 'In' operator. + tick(100); + fixture.detectChanges(); + + QueryBuilderFunctions.selectEntityInEditModeExpression(fixture, 0, 1); + tick(100); + fixture.detectChanges(); + + const fieldInputGroup = QueryBuilderFunctions.getQueryBuilderFieldsCombo(fixture, 1).querySelector('input'); + expect(fieldInputGroup.value).toBe('Artist'); + })); + + it('Should correctly apply filtering expressions tree to the hgrid component through API.', fakeAsync(() => { + // Close Advanced Filtering dialog. + hgrid.closeAdvancedFilteringDialog(false); + tick(200); + fix.detectChanges(); + // Spy for error messages in the console + const consoleSpy = spyOn(console, 'error'); + // Apply advanced filter through API. + const innerTree = new FilteringExpressionsTree(0, undefined, 'childData', ['ID']); + innerTree.filteringOperands.push({ + fieldName: 'ID', + ignoreCase: false, + conditionName: IgxStringFilteringOperand.instance().condition('contains').name, + searchVal: '39' + }); + + const tree = new FilteringExpressionsTree(0, undefined, 'rootData', ['ID']); + tree.filteringOperands.push({ + fieldName: 'ID', + conditionName: IgxStringFilteringOperand.instance().condition('inQuery').name, + ignoreCase: false, + searchTree: innerTree + }); + + hgrid.advancedFilteringExpressionsTree = tree; + fix.detectChanges(); + + // Check for error messages in the console + expect(consoleSpy).not.toHaveBeenCalled(); + expect(hgrid.filteredData.length).toBe(5); + })); + + it('Should correctly apply JSON filtering expressions tree to the hgrid correctly.', fakeAsync(() => { + // Close Advanced Filtering dialog. + hgrid.closeAdvancedFilteringDialog(false); + tick(200); + fix.detectChanges(); + // Spy for error messages in the console + const consoleSpy = spyOn(console, 'error'); + + const innerTree = new FilteringExpressionsTree(0, undefined, 'childData', ['ID']); + innerTree.filteringOperands.push({ + fieldName: 'ID', + ignoreCase: false, + conditionName: IgxStringFilteringOperand.instance().condition('contains').name, + searchVal: '39' + }); + + const tree = new FilteringExpressionsTree(0, undefined, 'rootData', ['ID']); + tree.filteringOperands.push({ + fieldName: 'ID', + conditionName: IgxStringFilteringOperand.instance().condition('inQuery').name, + ignoreCase: false, + searchTree: innerTree + }); + + hgrid.advancedFilteringExpressionsTree = JSON.parse(JSON.stringify(tree)); + fix.detectChanges(); + + // Check for error messages in the console + expect(consoleSpy).not.toHaveBeenCalled(); + expect(hgrid.filteredData.length).toBe(5); + })); + + it('Should have proper fields in UI when schema is defined with load on demand.', fakeAsync(() => { + const fixture = TestBed.createComponent(IgxHGridRemoteOnDemandComponent); + const hierarchicalGrid = fixture.componentInstance.instance; + hierarchicalGrid.allowAdvancedFiltering = true; + hierarchicalGrid.schema = [ + { + name: 'rootLevel', + fields: [ + { field: 'ID', dataType: 'string' }, + { field: 'ChildLevels', dataType: 'number' }, + { field: 'ProductName', dataType: 'string' }, + { field: 'Col1', dataType: 'number' }, + { field: 'Col2', dataType: 'number' }, + { field: 'Col3', dataType: 'number' } + ], + childEntities: [ + { + name: 'childData', + fields: [ + { field: 'ID', dataType: 'string' }, + { field: 'ProductName', dataType: 'string' } + ], + childEntities: [ + { + name: 'childData2', + fields: [ + { field: 'ID', dataType: 'string' }, + { field: 'ProductName', dataType: 'string' } + ] + } + ] + } + ] + } + ] + fixture.detectChanges(); + + hierarchicalGrid.openAdvancedFilteringDialog(); + fixture.detectChanges(); + + // Click the initial 'Add Condition' button. + QueryBuilderFunctions.clickQueryBuilderInitialAddConditionBtn(fixture, 0); + tick(100); + fixture.detectChanges(); + // Populate edit inputs. + QueryBuilderFunctions.selectColumnInEditModeExpression(fixture, 0); // Select 'ID' column. + QueryBuilderFunctions.selectOperatorInEditModeExpression(fixture, 10); // Select 'In' operator. + tick(100); + fixture.detectChanges(); + + const entityInputGroup = QueryBuilderFunctions.getQueryBuilderEntitySelect(fixture, 1).querySelector('input'); + expect(entityInputGroup.value).toBe('childData'); + + const fieldInputGroup = QueryBuilderFunctions.getQueryBuilderFieldsCombo(fixture, 1).querySelector('input'); + expect(fieldInputGroup.value).toBe('ID'); + + // Verify entities + QueryBuilderFunctions.clickQueryBuilderEntitySelect(fixture, 1); + fixture.detectChanges(); + const queryBuilderElement: HTMLElement = fixture.debugElement.queryAll(By.css(`.${QueryBuilderSelectors.QUERY_BUILDER_TREE}`))[1].nativeElement; + let dropdownValues: string[] = QueryBuilderFunctions.getQueryBuilderSelectDropdownItems(queryBuilderElement).map((x: any) => x.innerText); + let expectedValues = ['childData']; + expect(dropdownValues).toEqual(expectedValues); + + // Verify return fileds + QueryBuilderFunctions.clickQueryBuilderFieldsCombo(fixture, 1); + fixture.detectChanges(); + dropdownValues = QueryBuilderFunctions.getQueryBuilderSelectDropdownItems(queryBuilderElement, 1).map((x: any) => x.innerText); + expectedValues = ['ID', 'ProductName']; + expect(dropdownValues).toEqual(expectedValues); + })); + }); }); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-toolbar.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-toolbar.spec.ts index 6bb40c445ba..c844b346d9f 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-toolbar.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-toolbar.spec.ts @@ -310,7 +310,6 @@ export class DefaultToolbarComponent { IgxGridComponent, IgxGridToolbarComponent, IgxGridToolbarActionsComponent, - IgxGridToolbarTitleComponent, IgxGridToolbarPinningComponent, IgxGridToolbarHidingComponent, IgxGridToolbarAdvancedFilteringComponent, diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.html b/projects/igniteui-angular/src/lib/grids/grid/grid.component.html index 900ac1c9572..e5db8db8d69 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.html @@ -34,7 +34,7 @@
+ [style.height.px]="totalHeight" [style.width.px]="totalCalcWidth" [style.width]="!platform.isBrowser ? '100%' : undefined" #tbody [attr.aria-activedescendant]="activeDescendant"> @if (moving && columnInDrag && pinnedColumns.length <= 0) { - { const TBODY_CLASS = '.igx-grid__tbody-content'; const THEAD_CLASS = '.igx-grid-thead'; - configureTestSuite(); + configureTestSuite({ checkLeaks: true }); describe('IgxGrid - input properties', () => { beforeAll(waitForAsync(() => { @@ -1502,7 +1502,7 @@ describe('IgxGrid Component Tests #grid', () => { })); it('should render correct columns if after scrolling right container size changes so that all columns become visible.', - async () => { + skipLeakCheck(async () => { const fix = TestBed.createComponent(IgxGridDefaultRenderingComponent); fix.detectChanges(); const grid = fix.componentInstance.grid; @@ -1523,8 +1523,9 @@ describe('IgxGrid Component Tests #grid', () => { expect(headers.length).toEqual(5); for (let i = 0; i < headers.length; i++) { expect(headers[i].context.column.field).toEqual(grid.columnList.get(i).field); + // Note: We use skipLeakCheck because using `headers[i].context` messes up memory leak detection } - }); + })); it('Should render date and number values based on default formatting', fakeAsync(() => { const fixture = TestBed.createComponent(IgxGridFormattingComponent); @@ -2008,6 +2009,267 @@ describe('IgxGrid Component Tests #grid', () => { })); }); + describe('IgxGrid - min/max width constraints rules', () => { + beforeAll(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [ + NoopAnimationsModule, + IgxGridDefaultRenderingComponent + ] + }) + .compileComponents(); + })); + + describe('min/max in px', () => { + + it('in column with no width should not go outside bounds.', async() => { + const fix = TestBed.createComponent(IgxGridDefaultRenderingComponent); + // 4 cols + fix.componentInstance.initColumnsRows(5, 4); + fix.detectChanges(); + + const grid = fix.componentInstance.grid; + grid.width = "1500px"; + fix.detectChanges(); + const col1 = grid.columns[0]; + const col2 = grid.columns[1]; + const col3 = grid.columns[2]; + const col4 = grid.columns[3]; + + // without constraint, they split width equally + expect(col1.calcPixelWidth).toBe(grid.calcWidth / 4); + expect(col2.calcPixelWidth).toBe(grid.calcWidth / 4); + expect(col3.calcPixelWidth).toBe(grid.calcWidth / 4); + expect(col4.calcPixelWidth).toBe(grid.calcWidth / 4); + + // set smaller max in px + col1.maxWidth = '100px'; + fix.detectChanges(); + + // first column takes new max + expect(col1.calcPixelWidth).toBe(100); + // the rest split the remaining width + expect(col2.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col3.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col4.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + + + // set larger min in px + col1.maxWidth = null; + fix.detectChanges(); + + col1.minWidth = '600px'; + fix.detectChanges(); + await wait(16); + fix.detectChanges(); + + // first column takes new min + expect(col1.calcPixelWidth).toBe(600); + // the rest split the remaining width + expect(col2.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col3.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col4.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + }); + + it('in column with pixel width should not go outside bounds.', async() => { + const fix = TestBed.createComponent(IgxGridDefaultRenderingComponent); + // 4 cols + fix.componentInstance.initColumnsRows(5, 4); + fix.detectChanges(); + const grid = fix.componentInstance.grid; + grid.width = "1500px"; + fix.detectChanges(); + + const col1 = grid.columns[0]; + col1.width = "150px"; + fix.detectChanges(); + + expect(col1.calcPixelWidth).toBe(150); + + // set smaller max in px + col1.maxWidth = '100px'; + fix.detectChanges(); + + // first column takes new max + expect(col1.calcPixelWidth).toBe(100); + + // set larger min in px + col1.maxWidth = null; + fix.detectChanges(); + col1.minWidth = '500px'; + fix.detectChanges(); + await wait(100); + fix.detectChanges(); + + // first column takes new min + expect(col1.calcPixelWidth).toBe(500); + }); + + it('in column with auto width should not go outside bounds.', async() => { + const fix = TestBed.createComponent(IgxGridDefaultRenderingComponent); + // 4 cols + fix.componentInstance.initColumnsRows(5, 4); + fix.componentInstance.columns[0].header = "Some longer text to auto-size"; + fix.componentInstance.columns[0].width = 'auto'; + fix.detectChanges(); + // wait for auto-sizing + await wait(100); + fix.detectChanges(); + + const grid = fix.componentInstance.grid; + grid.width = "1500px"; + fix.detectChanges(); + const col1 = grid.columns[0]; + + // some autosize should be calculated + expect(col1.autoSize).not.toBeUndefined(); + + // set smaller max in px + col1.maxWidth = '100px'; + fix.detectChanges(); + + // first column takes new max + expect(col1.calcPixelWidth).toBe(100); + + // set larger min in px + col1.maxWidth = null; + fix.detectChanges(); + col1.minWidth = '500px'; + fix.detectChanges(); + await wait(100); + fix.detectChanges(); + + // first column takes new min + expect(col1.calcPixelWidth).toBe(500); + }); + }); + + + describe('min/max in %', () => { + it('in column with no width should not go outside bounds.', async () => { + const fix = TestBed.createComponent(IgxGridDefaultRenderingComponent); + // 4 cols + fix.componentInstance.initColumnsRows(5, 4); + fix.detectChanges(); + + const grid = fix.componentInstance.grid; + grid.width = "1500px"; + fix.detectChanges(); + const col1 = grid.columns[0]; + const col2 = grid.columns[1]; + const col3 = grid.columns[2]; + const col4 = grid.columns[3]; + + // set smaller max in % + col1.maxWidth = '10%'; + fix.detectChanges(); + + // first column takes new max + expect(col1.calcPixelWidth).toBe(grid.calcWidth * 0.1); + // the rest split the remaining width + expect(col2.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col3.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col4.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + + // set larger min in px + col1.maxWidth = null; + fix.detectChanges(); + col1.minWidth = '50%'; + fix.detectChanges(); + await wait(100); + fix.detectChanges(); + + // first column takes new min + expect(col1.calcPixelWidth).toBe(grid.calcWidth * 0.5); + // the rest split the remaining width + expect(col2.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col3.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col4.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + }); + + it('in column with pixel width should not go outside bounds.', async() => { + const fix = TestBed.createComponent(IgxGridDefaultRenderingComponent); + // 4 cols + fix.componentInstance.initColumnsRows(5, 4); + fix.componentInstance.columns[0].width = '400px'; + fix.detectChanges(); + + const grid = fix.componentInstance.grid; + grid.width = "1500px"; + fix.detectChanges(); + const col1 = grid.columns[0]; + const col2 = grid.columns[1]; + const col3 = grid.columns[2]; + const col4 = grid.columns[3]; + + // set smaller max in % + col1.maxWidth = '10%'; + fix.detectChanges(); + + // first column takes new max + expect(col1.calcPixelWidth).toBe(grid.calcWidth * 0.1); + // the rest split the remaining width + expect(col2.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col3.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col4.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + + // set larger min in px + col1.maxWidth = null; + fix.detectChanges(); + col1.minWidth = '50%'; + fix.detectChanges(); + await wait(100); + fix.detectChanges(); + + // first column takes new min + expect(col1.calcPixelWidth).toBe(grid.calcWidth * 0.5); + // the rest split the remaining width + expect(col2.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col3.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + expect(col4.calcPixelWidth).toBe((grid.calcWidth - col1.calcPixelWidth) / 3); + }); + + it('in column with auto width should not go outside bounds.', async() => { + const fix = TestBed.createComponent(IgxGridDefaultRenderingComponent); + // 4 cols + fix.componentInstance.initColumnsRows(5, 4); + fix.componentInstance.columns[0].header = "Some longer text to auto-size"; + fix.componentInstance.columns[0].width = 'auto'; + fix.detectChanges(); + await wait(100); + fix.detectChanges(); + + + const grid = fix.componentInstance.grid; + grid.width = "1500px"; + fix.detectChanges(); + const col1 = grid.columns[0]; + + // some autosize should be calculated + expect(col1.autoSize).not.toBeUndefined(); + + // set smaller max in px + col1.maxWidth = '10%'; + fix.detectChanges(); + + // first column takes new max + expect(col1.calcPixelWidth).toBe(grid.calcWidth * 0.1); + + // set larger min in px + col1.maxWidth = null; + fix.detectChanges(); + col1.minWidth = '50%'; + fix.detectChanges(); + await wait(100); + fix.detectChanges(); + + // first column takes new min + expect(col1.calcPixelWidth).toBe(grid.calcWidth * 0.5); + }); + }) + + }); + describe('IgxGrid - API methods', () => { beforeAll(waitForAsync(() => { TestBed.configureTestingModule({ @@ -2270,7 +2532,9 @@ describe('IgxGrid Component Tests #grid', () => { expect(grid.getRowData(7)).toEqual({}); }); - it(`Verify that getRowByIndex and RowType API returns correct data`, () => { + // note: it leaks when grid.groupBy() is executed because template-outlet doesn't destroy the viewrefs + // to be addressed in a separate PR + it(`Verify that getRowByIndex and RowType API returns correct data`, skipLeakCheck(() => { const fix = TestBed.createComponent(IgxGridDefaultRenderingComponent); fix.componentInstance.initColumnsRows(35, 5); fix.detectChanges(); @@ -2429,7 +2693,7 @@ describe('IgxGrid Component Tests #grid', () => { expect(thirdRow instanceof IgxGroupByRow).toBe(true); expect(thirdRow.index).toBe(2); expect(thirdRow.viewIndex).toBe(7); - }); + })); it('Verify that getRowByIndex returns correct data when paging is enabled', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridWrappedInContComponent); @@ -2715,6 +2979,7 @@ describe('IgxGrid Component Tests #grid', () => { afterEach(() => { observer?.disconnect(); + observer = null; }); it('should render the grid in a certain amount of time', async () => { @@ -3005,7 +3270,7 @@ export class IgxGridTestComponent { @Component({ template: ` @for (col of columns; track col.key) { - + } @if (paging) { @@ -3565,7 +3830,7 @@ export class IgxGridInsideIgxTabsComponent { `, - imports: [IgxGridComponent, IgxColumnComponent, IgxPaginatorComponent, IgxPaginatorContentDirective, AsyncPipe] + imports: [IgxGridComponent, IgxPaginatorComponent, IgxPaginatorContentDirective, AsyncPipe] }) export class IgxGridWithCustomPaginationTemplateComponent { @ViewChild('grid', { read: IgxGridComponent, static: true }) diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts index 07d3b4cdb9b..dbc7171abdd 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.ts @@ -1126,7 +1126,7 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType, } } - if (this.pagingMode === 1 && this.page !== 0) { + if (this.pagingMode === 'remote' && this.page !== 0) { row.index = index + this.perPage * this.page; } return row; @@ -1160,7 +1160,8 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType, */ public allRows(): RowType[] { return this.dataView.map((rec, index) => { - this.pagingMode === 1 && this.page !== 0 ? index = index + this.perPage * this.page : index = this.dataRowList.first.index + index; + this.pagingMode === 'remote' && this.page !== 0 ? + index = index + this.perPage * this.page : index = this.dataRowList.first.index + index; return this.createRow(index); }); } @@ -1201,7 +1202,7 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType, const row = this.getRowByIndex(rowIndex); const column = this._columns.find((col) => col.field === columnField); if (row && row instanceof IgxGridRow && !row.data?.detailsData && column) { - if (this.pagingMode === 1 && this.page !== 0) { + if (this.pagingMode === 'remote' && this.page !== 0) { row.index = rowIndex + this.perPage * this.page; } return new IgxGridCell(this, row.index, column); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts index 6cafdf5946d..1f38b49654f 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts @@ -4298,7 +4298,7 @@ export class GridGroupByTestDateTimeDataComponent { `, - imports: [IgxGridComponent, IgxColumnComponent, IgxPaginatorComponent, IgxGridStateDirective] + imports: [IgxGridComponent, IgxColumnComponent, IgxGridStateDirective] }) export class GridGroupByStateComponent extends GridGroupByTestDateTimeDataComponent { @ViewChild(IgxGridStateDirective, { static: true }) diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.pipes.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.pipes.ts index 314c1e496b4..4f5a4238eb4 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.pipes.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.pipes.ts @@ -7,7 +7,6 @@ import { IFilteringExpressionsTree, FilteringExpressionsTree } from '../../data- import { IGroupingExpression } from '../../data-operations/grouping-expression.interface'; import { GridType, IGX_GRID_BASE } from '../common/grid.interface'; import { FilterUtil, IFilteringStrategy } from '../../data-operations/filtering-strategy'; -import { GridPagingMode } from '../common/enums'; import { ISortingExpression } from '../../data-operations/sorting-strategy'; import { IGridSortingStrategy, IGridGroupingStrategy } from '../common/strategy'; @@ -89,7 +88,7 @@ export class IgxGridPagingPipe implements PipeTransform { constructor(@Inject(IGX_GRID_BASE) private grid: GridType) { } public transform(collection: IGroupByResult, enabled: boolean, page = 0, perPage = 15, _: number): IGroupByResult { - if (!enabled || this.grid.pagingMode !== GridPagingMode.Local) { + if (!enabled || this.grid.pagingMode !== 'local') { return collection; } const state = { diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/events.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/events.ts index 437b47ccb74..fea356e7817 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/events.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/events.ts @@ -7,4 +7,5 @@ export interface IGridCreatedEventArgs extends IBaseEventArgs { owner: IgxRowIslandComponent; parentID: any; grid: IgxHierarchicalGridComponent; + parentRowData?: any; } diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html index 962169bcf4d..feec21b53bb 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html @@ -20,7 +20,7 @@
+ [style.height.px]="totalHeight" [style.width.px]="totalCalcWidth" [style.width]="!platform.isBrowser ? '100%' : undefined" #tbody (scroll)="preventContainerScroll($event)"> @if (moving && columnInDrag && pinnedColumns.length <= 0) { - + [style.height.px]="totalHeight" [style.width.px]="pivotContentCalcWidth || null" [style.width]="!platform.isBrowser ? '100%' : undefined" #tbody [attr.aria-activedescendant]="activeDescendant"> @if (hasMovableColumns && columnInDrag && pinnedColumns.length <= 0) { @@ -31,7 +31,7 @@ } - + [style.height.px]='totalHeight' [style.width.px]="totalCalcWidth" [style.width]="!platform.isBrowser ? '100%' : undefined" #tbody (scroll)='preventContainerScroll($event)'> @if (moving && columnInDrag && pinnedColumns.length <= 0) { - `, + value: ``, categories: ['editor'], fontSet: 'indigo' } diff --git a/projects/igniteui-angular/src/lib/navigation-drawer/navigation-drawer.component.spec.ts b/projects/igniteui-angular/src/lib/navigation-drawer/navigation-drawer.component.spec.ts index a2360d3ba37..6edcfb82335 100644 --- a/projects/igniteui-angular/src/lib/navigation-drawer/navigation-drawer.component.spec.ts +++ b/projects/igniteui-angular/src/lib/navigation-drawer/navigation-drawer.component.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { Component, ViewChild, PLATFORM_ID } from '@angular/core'; +import { Component, ViewChild } from '@angular/core'; import { By } from '@angular/platform-browser'; import { wait } from '../test-utils/ui-interactions.spec'; import { IgxNavigationDrawerComponent } from './navigation-drawer.component'; @@ -192,7 +192,8 @@ describe('Navigation Drawer', () => { `; TestBed.overrideComponent(TestComponentDIComponent, { set: { - template + template, + imports: [IgxNavigationDrawerComponent, IgxNavDrawerTemplateDirective, IgxNavDrawerMiniTemplateDirective] } }); @@ -219,7 +220,8 @@ describe('Navigation Drawer', () => { `; TestBed.overrideComponent(TestComponentMiniComponent, { set: { - template + template, + imports: [IgxNavigationDrawerComponent, IgxNavDrawerTemplateDirective, IgxNavDrawerMiniTemplateDirective] } }); let fixture; @@ -251,7 +253,8 @@ describe('Navigation Drawer', () => { `; TestBed.overrideComponent(TestComponentPinComponent, { set: { - template + template, + imports: [IgxNavigationDrawerComponent, IgxNavDrawerTemplateDirective, IgxNavDrawerMiniTemplateDirective] } }); @@ -444,7 +447,8 @@ describe('Navigation Drawer', () => { let fixture: ComponentFixture; TestBed.overrideComponent(TestComponentDIComponent, { set: { - template + template, + imports: [IgxNavigationDrawerComponent, IgxNavDrawerTemplateDirective, IgxNavDrawerMiniTemplateDirective] } }); @@ -473,7 +477,8 @@ describe('Navigation Drawer', () => { `; TestBed.overrideComponent(TestComponentDIComponent, { set: { - template + template, + imports: [IgxNavigationDrawerComponent, IgxNavDrawerTemplateDirective, IgxNavDrawerMiniTemplateDirective] } }); @@ -690,7 +695,7 @@ class TestComponent { providers: [IgxNavigationService], selector: 'igx-test-cmp-di', template: '', - imports: [IgxNavigationDrawerComponent, IgxNavDrawerTemplateDirective, IgxNavDrawerMiniTemplateDirective] + imports: [IgxNavigationDrawerComponent] }) class TestComponentDIComponent { @ViewChild(IgxNavigationDrawerComponent, { static: true }) public navDrawer: IgxNavigationDrawerComponent; @@ -702,7 +707,7 @@ class TestComponentDIComponent { selector: 'igx-test-cmp-pin', providers: [IgxNavigationService], template: '', - imports: [IgxNavigationDrawerComponent, IgxNavDrawerTemplateDirective, IgxNavDrawerMiniTemplateDirective] + imports: [IgxNavigationDrawerComponent] }) class TestComponentPinComponent extends TestComponentDIComponent { public pin = true; @@ -714,7 +719,7 @@ class TestComponentPinComponent extends TestComponentDIComponent { selector: 'igx-test-cmp-mini', providers: [IgxNavigationService], template: '', - imports: [IgxNavigationDrawerComponent, IgxNavDrawerTemplateDirective, IgxNavDrawerMiniTemplateDirective] + imports: [IgxNavigationDrawerComponent] }) class TestComponentMiniComponent extends TestComponentDIComponent { public miniView = true; diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder-functions.spec.ts b/projects/igniteui-angular/src/lib/query-builder/query-builder-functions.spec.ts index d824c7547ab..917a630ffaf 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder-functions.spec.ts +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder-functions.spec.ts @@ -311,14 +311,14 @@ export class QueryBuilderFunctions { return outlet; } - public static getQueryBuilderSelectDropdown(queryBuilderElement: HTMLElement) { + public static getQueryBuilderSelectDropdown(queryBuilderElement: HTMLElement, index = 0) { const outlet = QueryBuilderFunctions.getQueryBuilderOutlet(queryBuilderElement); - const selectDropdown = outlet.querySelector(`.${QueryBuilderSelectors.DROP_DOWN_LIST_SCROLL}`); + const selectDropdown = outlet.querySelectorAll(`.${QueryBuilderSelectors.DROP_DOWN_LIST_SCROLL}`).item(index); return selectDropdown; } - public static getQueryBuilderSelectDropdownItems(queryBuilderElement: HTMLElement) { - const selectDropdown = QueryBuilderFunctions.getQueryBuilderSelectDropdown(queryBuilderElement); + public static getQueryBuilderSelectDropdownItems(queryBuilderElement: HTMLElement, index = 0) { + const selectDropdown = QueryBuilderFunctions.getQueryBuilderSelectDropdown(queryBuilderElement, index); const items = Array.from(selectDropdown.querySelectorAll('.igx-drop-down__item')); return items; } @@ -841,13 +841,13 @@ export class QueryBuilderFunctions { fix.detectChanges(); } - public static selectEntityAndClickInitialAddCondition(fix: ComponentFixture, entityIndex: number, groupIndex = 0) { - QueryBuilderFunctions.selectEntityInEditModeExpression(fix, entityIndex); + public static selectEntityAndClickInitialAddCondition(fix: ComponentFixture, entityIndex: number, level = 0) { + QueryBuilderFunctions.selectEntityInEditModeExpression(fix, entityIndex, level); tick(100); fix.detectChanges(); // Click the initial 'Add Condition' button. - QueryBuilderFunctions.clickQueryBuilderInitialAddConditionBtn(fix, groupIndex); + QueryBuilderFunctions.clickQueryBuilderInitialAddConditionBtn(fix, level); tick(100); fix.detectChanges(); } @@ -934,4 +934,71 @@ export class QueryBuilderFunctions { return [dropGhost, prevElement, nextElement, newChipContents]; } + + public static verifyGhostPositionOnMouseDrag(fix: ComponentFixture, draggedChip: any, X: number, Y: number, moveDown: boolean) { + const ghostPositionVisits: boolean[] = [false, false, false, false, false, false, false, false]; + const draggedChipCenter = QueryBuilderFunctions.getElementCenter(draggedChip.chipArea.nativeElement); + const dragDir = draggedChip.dragDirective; + + //pickup chip + dragDir.onPointerDown({ pointerId: 1, pageX: draggedChipCenter.X, pageY: draggedChipCenter.Y }); + fix.detectChanges(); + + //trigger ghost + QueryBuilderFunctions.dragMove(dragDir, draggedChipCenter.X + 10, draggedChipCenter.Y + 10); + fix.detectChanges(); + + spyOn(dragDir.ghostElement, 'dispatchEvent').and.callThrough(); + + let target = moveDown ? 350 : 0; + let shift = moveDown ? 1 : -1 + //Drag ghost up or down and check if drop ghost is rendered in the expected positions + for (let i = moveDown ? 0 : 350; moveDown ? i <= target : i >= target; i += shift) { + Y += moveDown ? 1 : -1; + + QueryBuilderFunctions.dragMove(dragDir, X, Y); + tick(); + fix.detectChanges(); + + const [dropGhost, prevElement, nextElement] = QueryBuilderFunctions.getDropGhostAndItsSiblings(fix); + + if (i < 40 && !ghostPositionVisits[0]) { + if (i <= 42) tick(50); + if (!dropGhost) ghostPositionVisits[0] = true; + } + + if (i > 35 && i < 122 && !ghostPositionVisits[1]) { + if (dropGhost && !prevElement && nextElement == 'OrderName Equals foo') ghostPositionVisits[1] = true; + } + + if (i > 120 && i < 165 && !ghostPositionVisits[2]) { + if (dropGhost && prevElement == 'OrderName Equals foo' && nextElement === 'or OrderName Ends With a OrderDate Today') ghostPositionVisits[2] = true; + } + + if (i > 166 && i < 201 && !ghostPositionVisits[3]) { + if (dropGhost && !prevElement && nextElement == 'OrderName Ends With a') ghostPositionVisits[3] = true; + } + + if (i > 202 && i < 241 && !ghostPositionVisits[4]) { + if (dropGhost && prevElement == 'OrderName Ends With a' && nextElement === 'OrderDate Today') ghostPositionVisits[4] = true; + } + + if (i > 240 && i < 273 && !ghostPositionVisits[5]) { + if (dropGhost && prevElement == 'OrderDate Today' && !nextElement) ghostPositionVisits[5] = true; + } + + if (i > 256 && i < 316 && !ghostPositionVisits[6]) { + if (X > 400 || (dropGhost && prevElement == 'or OrderName Ends With a OrderDate Today' && !nextElement)) ghostPositionVisits[6] = true; + } + + if (i > 320 && !ghostPositionVisits[7]) { + if (i >= 340) tick(50); + if (!dropGhost) ghostPositionVisits[7] = true; + } + } + + //When dragged to the end, check results + expect(ghostPositionVisits).not.toContain(false, + `Ghost was not rendered on position(s) ${ghostPositionVisits.reduce((arr, e, ix) => ((e == false) && arr.push(ix), arr), []).toString()}`); + } } diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.html b/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.html index 2197f888cd8..9ebaf1a9191 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.html +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.html @@ -7,7 +7,7 @@ -
+
From
- Select + @if (!this.isHierarchicalNestedQuery()) { + Select + } @if (!parentExpression) { diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.ts b/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.ts index 1e47d7dd7f4..7a59165e80c 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.ts +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.ts @@ -172,17 +172,12 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { @Input() public set fields(fields: FieldType[]) { this._fields = fields; - + + this._fields = this._fields?.map(f => ({...f, filters: this.getFilters(f), pipeArgs: this.getPipeArgs(f) })); + if (!this._fields && this.isAdvancedFiltering()) { this._fields = this.entities[0].fields; } - - if (this._fields) { - this._fields.forEach(field => { - this.setFilters(field); - this.setFormat(field); - }); - } } /** @@ -199,8 +194,8 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { public set expressionTree(expressionTree: IExpressionTree) { this._expressionTree = expressionTree; if (!expressionTree) { - this._selectedEntity = null; - this._selectedReturnFields = []; + this._selectedEntity = this.isAdvancedFiltering() && this.entities.length === 1 ? this.entities[0] : null; + this._selectedReturnFields = this._selectedEntity ? this._selectedEntity.fields?.map(f => f.field) : []; } if (!this._preventInit) { @@ -247,6 +242,11 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { return this._resourceStrings; } + /** + * Gets/sets the expected return field. + */ + @Input() public expectedReturnField: string = null; + /** * Event fired as the expression tree is changed. */ @@ -521,7 +521,14 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { /** @hidden */ protected isAdvancedFiltering(): boolean { - return this.entities?.length === 1 && !this.entities[0]?.name; + return (this.entities?.length === 1 && !this.entities[0]?.name) || + this.entities?.find(e => e.childEntities?.length > 0) !== undefined || + this.entities !== this.queryBuilder?.entities; + } + + /** @hidden */ + protected isHierarchicalNestedQuery(): boolean { + return this.queryBuilder.entities !== this.entities } /** @hidden */ @@ -553,6 +560,14 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { this.returnFieldSelectOverlaySettings.outlet = this.overlayOutlet; this.addExpressionDropDownOverlaySettings.outlet = this.overlayOutlet; this.groupContextMenuDropDownOverlaySettings.outlet = this.overlayOutlet; + + if (this.isAdvancedFiltering() && this.entities?.length === 1) { + this.selectedEntity = this.entities[0].name; + if (this._selectedEntity.fields.find(f => f.field === this.expectedReturnField)) { + this._selectedReturnFields = [this.expectedReturnField]; + } + } + // Trigger additional change detection cycle this.cdr.detectChanges(); } @@ -622,7 +637,11 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { } this.fields = this._entityNewValue ? this._entityNewValue.fields : []; - this._selectedReturnFields = this.parentExpression ? [] : this._entityNewValue.fields?.map(f => f.field); + if (this._selectedEntity.fields.find(f => f.field === this.expectedReturnField)) { + this._selectedReturnFields = [this.expectedReturnField]; + } else { + this._selectedReturnFields = this.parentExpression ? [] : this._entityNewValue.fields?.map(f => f.field); + } if (this._expressionTree) { this._expressionTree.entity = this._entityNewValue.name; @@ -685,6 +704,10 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { if (this._selectedField !== value) { this._selectedField = value; + if (this._selectedField && !this._selectedField.dataType) { + this._selectedField.filters = this.getFilters(this._selectedField); + } + this.selectDefaultCondition(); if (oldValue && this._selectedField && this._selectedField.dataType !== oldValue.dataType) { this.searchValue.value = null; @@ -828,7 +851,10 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { if (innerQuery && this.selectedField?.filters?.condition(this.selectedCondition)?.isNestedQuery) { innerQuery.exitEditAddMode(); this._editedExpression.expression.searchTree = this.getExpressionTreeCopy(innerQuery.expressionTree); - this._editedExpression.expression.searchTree.returnFields = innerQuery.selectedReturnFields; + const returnFields = innerQuery.selectedReturnFields.length > 0 ? + innerQuery.selectedReturnFields : + [innerQuery.fields[0].field]; + this._editedExpression.expression.searchTree.returnFields = returnFields; } else { this._editedExpression.expression.searchTree = null; } @@ -842,6 +868,10 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { this._editedExpression = null; } + if (this.selectedReturnFields.length === 0) { + this.selectedReturnFields = this.fields.map(f => f.field); + } + this._expressionTree = this.createExpressionTreeFromGroupItem(this.rootGroup, this.selectedEntity?.name, this.selectedReturnFields); if (!this.parentExpression) { this.expressionTreeChange.emit(this._expressionTree); @@ -925,7 +955,6 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { */ public operandCanBeCommitted(): boolean { const innerQuery = this.innerQueries.filter(q => q.isInEditMode())[0]; - return this.selectedField && this.selectedCondition && ( ( @@ -938,7 +967,7 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { this.selectedField.filters.condition(this.selectedCondition)?.isUnary ); } - + /** * @hidden @internal */ @@ -1182,7 +1211,7 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { if (!this.selectedField) { this.fieldSelect.input.nativeElement.focus(); } else if (this.selectedField.filters.condition(this.selectedCondition)?.isUnary) { - this.conditionSelect.input.nativeElement.focus(); + this.conditionSelect?.input.nativeElement.focus(); } else { const input = this.searchValueInput?.nativeElement || this.picker?.getEditElement(); input?.focus(); @@ -1358,7 +1387,12 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { public getConditionList(): string[] { if (!this.selectedField) return []; - if (this.entities?.length === 1 && !this.entities[0].name) { + if (!this.selectedField.filters) { + this.selectedField.filters = this.getFilters(this.selectedField); + } + + if ((this.isAdvancedFiltering() && !this.entities[0].childEntities) || + (this.isHierarchicalNestedQuery() && this.selectedEntity.name && !this.selectedEntity.childEntities)) { return this.selectedField.filters.conditionList(); } @@ -1485,16 +1519,19 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { return ctx; } - private setFormat(field: FieldType) { - if (!field.pipeArgs) { - field.pipeArgs = { digitsInfo: DEFAULT_PIPE_DIGITS_INFO }; + private getPipeArgs(field: FieldType) { + let pipeArgs = {...field.pipeArgs}; + if (!pipeArgs) { + pipeArgs = { digitsInfo: DEFAULT_PIPE_DIGITS_INFO }; } - if (!field.pipeArgs.format) { - field.pipeArgs.format = field.dataType === DataType.Time ? + if (!pipeArgs.format) { + pipeArgs.format = field.dataType === DataType.Time ? DEFAULT_PIPE_TIME_FORMAT : field.dataType === DataType.DateTime ? DEFAULT_PIPE_DATE_TIME_FORMAT : DEFAULT_PIPE_DATE_FORMAT; } + + return pipeArgs; } private selectDefaultCondition() { @@ -1503,31 +1540,27 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { } } - private setFilters(field: FieldType) { + private getFilters(field: FieldType) { if (!field.filters) { switch (field.dataType) { case DataType.Boolean: - field.filters = IgxBooleanFilteringOperand.instance(); - break; + return IgxBooleanFilteringOperand.instance(); case DataType.Number: case DataType.Currency: case DataType.Percent: - field.filters = IgxNumberFilteringOperand.instance(); - break; + return IgxNumberFilteringOperand.instance(); case DataType.Date: - field.filters = IgxDateFilteringOperand.instance(); - break; + return IgxDateFilteringOperand.instance(); case DataType.Time: - field.filters = IgxTimeFilteringOperand.instance(); - break; + return IgxTimeFilteringOperand.instance(); case DataType.DateTime: - field.filters = IgxDateTimeFilteringOperand.instance(); - break; + return IgxDateTimeFilteringOperand.instance(); case DataType.String: default: - field.filters = IgxStringFilteringOperand.instance(); - break; + return IgxStringFilteringOperand.instance(); } + } else { + return field.filters; } } diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts index d5ad0b22234..0800ba40c53 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts @@ -119,6 +119,16 @@ describe('IgxQueryBuilder', () => { expect(mainEntityContainer.children[1].children[1].tagName).toBe('IGX-COMBO'); expect(nestedEntityContainer.children[1].children[1].tagName).toBe('IGX-SELECT'); })); + + it('Should return proper fields collection without additional props.', fakeAsync(() => { + queryBuilder.expressionTree = QueryBuilderFunctions.generateExpressionTree(); + fix.detectChanges(); + + queryBuilder.entities[0].fields.forEach(field => { + expect(field.filters).toBeUndefined(); + expect(field.pipeArgs).toBeUndefined(); + }); + })); }); describe('Interactions', () => { @@ -452,16 +462,16 @@ describe('IgxQueryBuilder', () => { // Verify the returnFields let exprTreeReturnFields = JSON.stringify(fix.componentInstance.queryBuilder.expressionTree.returnFields); expect(exprTreeReturnFields).toBe(`["*"]`); - + // Change the selected return fields QueryBuilderFunctions.selectFieldsInEditModeExpression(fix, [1]); tick(100); fix.detectChanges(); - + // Verify the returnFields exprTreeReturnFields = JSON.stringify(fix.componentInstance.queryBuilder.expressionTree.returnFields); expect(exprTreeReturnFields).toBe(`["OrderId"]`); - + // Change the entity QueryBuilderFunctions.selectEntityAndClickInitialAddCondition(fix, 0); @@ -474,16 +484,16 @@ describe('IgxQueryBuilder', () => { queryBuilder.expressionTree = QueryBuilderFunctions.generateExpressionTree(); queryBuilder.showEntityChangeDialog = false; fix.detectChanges(); - + // Click selectAll button in order to deselect all fields QueryBuilderFunctions.selectFieldsInEditModeExpression(fix, [0]); tick(100); fix.detectChanges(); - + // Verify the returnFields let exprTreeReturnFields = JSON.stringify(fix.componentInstance.queryBuilder.expressionTree.returnFields); expect(exprTreeReturnFields).toBe(`[]`); - + // Click selectAll button in order to select all fields QueryBuilderFunctions.selectFieldsInEditModeExpression(fix, [0]); tick(100); @@ -1877,10 +1887,7 @@ describe('IgxQueryBuilder', () => { tick(100); fix.detectChanges(); - commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); - ControlsFunction.verifyButtonIsDisabled(commitBtn as HTMLElement, true); - - // Select return field + // Change return field from preselected 'OrderId' to 'Id' QueryBuilderFunctions.selectFieldsInEditModeExpression(fix, [0], 1); tick(100); fix.detectChanges(); @@ -1891,7 +1898,7 @@ describe('IgxQueryBuilder', () => { QueryBuilderFunctions.verifyEditModeExpressionInputStates(fix, true, true, false, true); // Parent commit button should be enabled QueryBuilderFunctions.clickQueryBuilderExpressionCommitButton(fix); fix.detectChanges(); - + //Verify that expressionTree is correct const exprTree = JSON.stringify(fix.componentInstance.queryBuilder.expressionTree, null, 2); expect(exprTree).toBe(`{ @@ -2166,7 +2173,7 @@ describe('IgxQueryBuilder', () => { QueryBuilderFunctions.verifyExpressionChipContent(fix, [0], 'Id', 'Equals', '1', 1); QueryBuilderFunctions.verifyExpressionChipContent(fix, [1], 'Released', 'True', undefined, 1); - // close chip + // close chip queryBuilder.discard(); tick(100); fix.detectChanges(); @@ -2511,88 +2518,24 @@ describe('IgxQueryBuilder', () => { expect(chipComponents[1].nativeElement.getBoundingClientRect().height).toBe(0); }); - it('Should render drop ghost properly when mouse dragged.', fakeAsync(() => { + it('Should render drop ghost properly when mouse dragged down on the left.', fakeAsync(() => { const draggedChip = chipComponents[1].componentInstance; - const draggedChipCenter = QueryBuilderFunctions.getElementCenter(draggedChip.chipArea.nativeElement); - const dragDir = draggedChip.dragDirective; - - let X = 100, Y = 75; - - //pickup chip - dragDir.onPointerDown({ pointerId: 1, pageX: draggedChipCenter.X, pageY: draggedChipCenter.Y }); - fix.detectChanges(); - - //trigger ghost - QueryBuilderFunctions.dragMove(dragDir, draggedChipCenter.X + 10, draggedChipCenter.Y + 10); - fix.detectChanges(); - - spyOn(dragDir.ghostElement, 'dispatchEvent').and.callThrough(); - - const ghostPositionVisits: boolean[] = [false, false, false, false, false, false, false, false] - - let i = 0, pass = 1, inc = 1; - - //Drag ghost up and down four times and check if drop ghost is rendered in the expected positions - while (pass <= 4) { - i += inc; - Y += inc; - - QueryBuilderFunctions.dragMove(dragDir, X, Y); - tick(); - fix.detectChanges(); - - const [dropGhost, prevElement, nextElement] = QueryBuilderFunctions.getDropGhostAndItsSiblings(fix); - - if (i < 40 && !ghostPositionVisits[0]) { - if (i <= 42) tick(50); - if (!dropGhost) ghostPositionVisits[0] = true; - } - - if (i > 35 && i < 122 && !ghostPositionVisits[1]) { - if (dropGhost && !prevElement && nextElement == 'OrderName Equals foo') ghostPositionVisits[1] = true; - } - - if (i > 120 && i < 165 && !ghostPositionVisits[2]) { - if (dropGhost && prevElement == 'OrderName Equals foo' && nextElement === 'or OrderName Ends With a OrderDate Today') ghostPositionVisits[2] = true; - } - - if (i > 166 && i < 201 && !ghostPositionVisits[3]) { - if (dropGhost && !prevElement && nextElement == 'OrderName Ends With a') ghostPositionVisits[3] = true; - } - - if (i > 202 && i < 241 && !ghostPositionVisits[4]) { - if (dropGhost && prevElement == 'OrderName Ends With a' && nextElement === 'OrderDate Today') ghostPositionVisits[4] = true; - } - - if (i > 240 && i < 273 && !ghostPositionVisits[5]) { - if (dropGhost && prevElement == 'OrderDate Today' && !nextElement) ghostPositionVisits[5] = true; - } - - if (i > 256 && i < 316 && !ghostPositionVisits[6]) { - if (pass > 2 || (dropGhost && prevElement == 'or OrderName Ends With a OrderDate Today' && !nextElement)) ghostPositionVisits[6] = true; - } - - if (i > 320 && !ghostPositionVisits[7]) { - if (i >= 340) tick(50); - if (!dropGhost) ghostPositionVisits[7] = true; - } - - //When dragged to the end, check results and reverse direction for next pass - if (i === 350 || i === 0) { - expect(ghostPositionVisits).not.toContain(false, - `Ghost was not rendered on position(s) ${ghostPositionVisits.reduce((arr, e, ix) => ((e == false) && arr.push(ix), arr), []).toString()} on pass:${pass}`); + QueryBuilderFunctions.verifyGhostPositionOnMouseDrag(fix, draggedChip, 100, 75, true); + })); - ghostPositionVisits.fill(false); - pass++; - inc *= -1; - if (pass % 2 === 0) Y -= ROW_HEIGHT; - if (pass % 2 !== 0) Y += ROW_HEIGHT; + it('Should render drop ghost properly when mouse dragged up on the left.', fakeAsync(() => { + const draggedChip = chipComponents[1].componentInstance; + QueryBuilderFunctions.verifyGhostPositionOnMouseDrag(fix, draggedChip, 100, 75 + 350, false); + })); - //go to the left and test the whole chip div as well(blank space to the right) - if (pass == 3) X += 400; - } - } + it('Should render drop ghost properly when mouse dragged down on the right.', fakeAsync(() => { + const draggedChip = chipComponents[1].componentInstance; + QueryBuilderFunctions.verifyGhostPositionOnMouseDrag(fix, draggedChip, 500, 75, true); + })); + it('Should render drop ghost properly when mouse dragged up on the right.', fakeAsync(() => { + const draggedChip = chipComponents[1].componentInstance; + QueryBuilderFunctions.verifyGhostPositionOnMouseDrag(fix, draggedChip, 500, 75 + 350, false); })); it('Should position drop ghost below the target condition on dragging down.', () => { @@ -3149,7 +3092,6 @@ describe('IgxQueryBuilder', () => { draggedIndicator.nativeElement.focus(); spyOn(tree.nativeElement, 'dispatchEvent').and.callThrough(); - const dropGhostContent = QueryBuilderFunctions.GetChipsContentAsArray(fix)[1]; tree.nativeElement.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' })); tick(20); @@ -3257,7 +3199,6 @@ describe('IgxQueryBuilder', () => { draggedIndicator.nativeElement.focus(); spyOn(tree.nativeElement, 'dispatchEvent').and.callThrough(); - const dropGhostContent = QueryBuilderFunctions.GetChipsContentAsArray(fix)[1]; tree.nativeElement.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' })); tick(20); @@ -3309,8 +3250,7 @@ export class IgxQueryBuilderSampleTestComponent implements OnInit {

{{selectedField.field}}

{{selectedCondition}}

} @else if (selectedField?.field === 'OrderId' && selectedCondition === 'equals') { - + } @else { @@ -3339,6 +3279,7 @@ export class IgxQueryBuilderCustomTemplateSampleTestComponent implements OnInit public ngOnInit(): void { this.entities = SampleEntities.map(a => ({ ...a })); + this.entities[1].fields[0].formatter = (value: any, rowData: any) => rowData === 'equals' ? (Array.from(value)[0] as any).id : value; const tree = new FilteringExpressionsTree(FilteringLogic.And, null, 'Orders', ['*']); tree.filteringOperands.push({ @@ -3356,11 +3297,4 @@ export class IgxQueryBuilderCustomTemplateSampleTestComponent implements OnInit { id: 1, field: 'B' } ]; } - - public handleChange(ev, selectedField, searchVal) { - if (selectedField.field === 'OrderId') { - searchVal.value = ev.newValue[0]; - selectedField.formatter = (value: any, rowData: any) => rowData === 'equals' ? (Array.from(value)[0] as any).id : value; - } - } } diff --git a/projects/igniteui-angular/src/lib/select/select.component.spec.ts b/projects/igniteui-angular/src/lib/select/select.component.spec.ts index 9b5c517e8d7..dad83f3273b 100644 --- a/projects/igniteui-angular/src/lib/select/select.component.spec.ts +++ b/projects/igniteui-angular/src/lib/select/select.component.spec.ts @@ -3133,7 +3133,7 @@ class IgxSelectCDRComponent { } `, - imports: [IgxSelectComponent, IgxSelectItemComponent, IgxLabelDirective] + imports: [IgxSelectComponent, IgxSelectItemComponent] }) class IgxSelectWithIdComponent { @ViewChild(IgxSelectComponent, { read: IgxSelectComponent, static: true }) diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts index 3be8c13201f..a4d0b762765 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts @@ -215,7 +215,7 @@ describe('igxOverlay', () => { }; describe('Pure Unit Test', () => { - configureTestSuite(); + configureTestSuite({ checkLeaks: true }); let mockElement: any; let mockElementRef: any; let mockApplicationRef: any; @@ -297,6 +297,9 @@ describe('igxOverlay', () => { overlay = new IgxOverlayService( mockApplicationRef, mockDocument, mockNgZone, mockPlatformUtil, mockAnimationService); }); + afterEach(() => { + overlay.ngOnDestroy(); + }); it('Should set cursor to pointer on iOS', () => { mockPlatformUtil.isIOS = true; @@ -365,7 +368,7 @@ describe('igxOverlay', () => { }); describe('Unit Tests: ', () => { - configureTestSuite(); + configureTestSuite({ checkLeaks: true }); beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [NoopAnimationsModule, SimpleDynamicWithDirectiveComponent] @@ -1412,14 +1415,12 @@ describe('igxOverlay', () => { }); describe('Unit Tests - Scroll Strategies: ', () => { + configureTestSuite({ checkLeaks: true }); beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [NoopAnimationsModule, SimpleDynamicWithDirectiveComponent] }); })); - afterAll(() => { - TestBed.resetTestingModule(); - }); it('Should properly initialize Scroll Strategy - Block.', fakeAsync(async () => { TestBed.overrideComponent(EmptyPageComponent, { set: { @@ -1589,7 +1590,7 @@ describe('igxOverlay', () => { }); describe('Integration tests: ', () => { - configureTestSuite(); + configureTestSuite({ checkLeaks: true }); beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [NoopAnimationsModule, SimpleDynamicWithDirectiveComponent] @@ -3577,6 +3578,7 @@ describe('igxOverlay', () => { }); describe('Integration tests - Scroll Strategies: ', () => { + configureTestSuite({ checkLeaks: true }); beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [NoopAnimationsModule, SimpleDynamicWithDirectiveComponent] @@ -4441,6 +4443,7 @@ describe('igxOverlay', () => { }); describe('Integration tests p3 (IgniteUI components): ', () => { + configureTestSuite({ checkLeaks: true }); beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [NoopAnimationsModule, SimpleDynamicWithDirectiveComponent] diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts index e3ad0c029ae..44ad8b997c0 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts @@ -416,9 +416,19 @@ export class IgxOverlayService implements OnDestroy { return; } if (settings) { + const newScrollStrategy = settings.scrollStrategy && info.settings.scrollStrategy !== settings.scrollStrategy; + if (newScrollStrategy && info.settings.scrollStrategy) { + info.settings.scrollStrategy.detach(); + } + settings.positionStrategy ??= info.settings.positionStrategy; settings.scrollStrategy ??= info.settings.scrollStrategy; info.settings = { ...info.settings, ...settings }; + + if (newScrollStrategy) { + info.settings.scrollStrategy.initialize(this._document, this, info.id); + info.settings.scrollStrategy.attach(); + } } this.updateSize(info); info.settings.positionStrategy.position( @@ -538,6 +548,8 @@ export class IgxOverlayService implements OnDestroy { /** @hidden */ public ngOnDestroy(): void { + this.detachAll(); + this.removeCloseOnEscapeListener(); this.destroy$.next(true); this.destroy$.complete(); } diff --git a/projects/igniteui-angular/src/lib/splitter/splitter.component.spec.ts b/projects/igniteui-angular/src/lib/splitter/splitter.component.spec.ts index 07e6dabb7b5..5bfb346d615 100644 --- a/projects/igniteui-angular/src/lib/splitter/splitter.component.spec.ts +++ b/projects/igniteui-angular/src/lib/splitter/splitter.component.spec.ts @@ -21,7 +21,7 @@ describe('IgxSplitter', () => { }).compileComponents())); let fixture: ComponentFixture; let splitter: IgxSplitterComponent; - + beforeEach(waitForAsync(() => { fixture = TestBed.createComponent(SplitterTestComponent); fixture.detectChanges(); @@ -462,6 +462,74 @@ describe('IgxSplitter pane collapse', () => { }); }); +describe('IgxSplitter resizing with minSize and browser window is shrinked', () => { + configureTestSuite(); + beforeAll(waitForAsync(() => TestBed.configureTestingModule({ + imports: [ + SplitterMinSiezComponent + ] + }).compileComponents())); + + let fixture; let splitter; + beforeEach(waitForAsync(() => { + fixture = TestBed.createComponent(SplitterMinSiezComponent); + fixture.detectChanges(); + splitter = fixture.componentInstance.splitter; + })); + + it('should set the correct sizes when the user drags one pane to the end of another', () => { + const pane1 = splitter.panes.toArray()[0]; + const pane2 = splitter.panes.toArray()[1]; + const splitterBarComponent = fixture.debugElement.query(By.css(SPLITTERBAR_CLASS)).context; + const minSize = parseInt(pane1.minSize); + spyOn(splitter, 'onMoveEnd').and.callThrough(); + + pane1.size = (splitter.getTotalSize() - parseInt(pane2.size)) + 'px'; + fixture.detectChanges(); + + splitterBarComponent.moveStart.emit(pane1); + fixture.detectChanges(); + splitterBarComponent.movingEnd.emit(splitter.getTotalSize() -minSize); + fixture.detectChanges(); + + splitter.elementRef.nativeElement.style.width = '500px'; + pane2.size = (splitter.getTotalSize() - minSize) + 'px'; + fixture.detectChanges(); + + splitterBarComponent.moveStart.emit(pane1); + fixture.detectChanges(); + splitterBarComponent.movingEnd.emit(-400); + fixture.detectChanges(); + + const isFullSize = pane1.size === '100%' || pane1.size === (splitter.getTotalSize() + 'px'); + + expect(splitter.onMoveEnd).toHaveBeenCalled(); + expect(isFullSize).toBeTruthy(); + }); +}); + +@Component({ + template: ` + + +
+ Pane 1 +
+
+ +
+ Pane 2 +
+
+
+ `, + imports: [IgxSplitterComponent, IgxSplitterPaneComponent] +}) +export class SplitterMinSiezComponent { + @ViewChild(IgxSplitterComponent, { static: true }) + public splitter: IgxSplitterComponent; +} + @Component({ template: ` diff --git a/projects/igniteui-angular/src/lib/splitter/splitter.component.ts b/projects/igniteui-angular/src/lib/splitter/splitter.component.ts index ca1f7f15878..cf4dc267c46 100644 --- a/projects/igniteui-angular/src/lib/splitter/splitter.component.ts +++ b/projects/igniteui-angular/src/lib/splitter/splitter.component.ts @@ -239,7 +239,15 @@ export class IgxSplitterComponent implements AfterContentInit { } public onMoveEnd(delta: number) { - const [ paneSize, siblingSize ] = this.calcNewSizes(delta); + let [ paneSize, siblingSize ] = this.calcNewSizes(delta); + + if (paneSize + siblingSize > this.getTotalSize() && delta < 0) { + paneSize = this.getTotalSize(); + siblingSize = 0; + } else if(paneSize + siblingSize > this.getTotalSize() && delta > 0) { + paneSize = 0; + siblingSize = this.getTotalSize(); + } if (this.pane.isPercentageSize) { // handle % resizes diff --git a/projects/igniteui-angular/src/lib/stepper/stepper.component.ts b/projects/igniteui-angular/src/lib/stepper/stepper.component.ts index 3c5329a1821..e2801515b46 100644 --- a/projects/igniteui-angular/src/lib/stepper/stepper.component.ts +++ b/projects/igniteui-angular/src/lib/stepper/stepper.component.ts @@ -385,7 +385,8 @@ export class IgxStepperComponent extends IgxCarouselComponentBase implements Igx } /** @hidden @internal */ - public ngOnDestroy(): void { + public override ngOnDestroy(): void { + super.ngOnDestroy(); this.destroy$.next(); this.destroy$.complete(); } diff --git a/projects/igniteui-angular/src/lib/tabs/tabs.directive.ts b/projects/igniteui-angular/src/lib/tabs/tabs.directive.ts index 3e554a22ad4..6e955ccc8cf 100644 --- a/projects/igniteui-angular/src/lib/tabs/tabs.directive.ts +++ b/projects/igniteui-angular/src/lib/tabs/tabs.directive.ts @@ -149,7 +149,8 @@ export abstract class IgxTabsDirective extends IgxCarouselComponentBase implemen } /** @hidden */ - public ngOnDestroy(): void { + public override ngOnDestroy(): void { + super.ngOnDestroy(); if (this._itemChanges$) { this._itemChanges$.unsubscribe(); } 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 acefcbf1c44..f4441d67dbb 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 @@ -10,7 +10,7 @@ import { Router } from '@angular/router'; import { Location } from '@angular/common'; import { AddingSelectedTabComponent, TabsContactsComponent, TabsDisabledTestComponent, TabsRoutingDisabledTestComponent, - TabsRoutingGuardTestComponent, TabsRoutingTestComponent, TabsRtlComponent, TabsTabsOnlyModeTest1Component, TabsTabsOnlyModeTest2Component, + TabsRoutingGuardTestComponent, TabsRoutingTestComponent, TabsRtlComponent, TabsTabsOnlyModeTest1Component, TabsTest2Component, TabsTestBug4420Component, TabsTestComponent, TabsTestCustomStylesComponent, TabsTestHtmlAttributesComponent, TabsTestSelectedTabComponent, TabsWithPrefixSuffixTestComponent, TemplatedTabsTestComponent @@ -29,7 +29,7 @@ const KEY_ENTER_EVENT = new KeyboardEvent('keydown', { key: 'Enter', bubbles: tr const KEY_SPACE_EVENT = new KeyboardEvent('keydown', { key: ' ', bubbles: true }); describe('IgxTabs', () => { - configureTestSuite(); + configureTestSuite({ checkLeaks: true }); const tabItemNormalCssClass = 'igx-tabs__header-item'; const tabItemSelectedCssClass = 'igx-tabs__header-item--selected'; @@ -58,7 +58,6 @@ describe('IgxTabs', () => { TabsTestBug4420Component, TabsRoutingTestComponent, TabsTabsOnlyModeTest1Component, - TabsTabsOnlyModeTest2Component, TabsDisabledTestComponent, TabsRoutingGuardTestComponent, TabsWithPrefixSuffixTestComponent, @@ -877,8 +876,9 @@ describe('IgxTabs', () => { let headerElements; beforeEach(waitForAsync(() => { - fixture = TestBed.createComponent(TabsTabsOnlyModeTest2Component); + fixture = TestBed.createComponent(TabsTabsOnlyModeTest1Component); tabsComp = fixture.componentInstance.tabs; + tabsComp.selectedIndex = 2; fixture.detectChanges(); tabItems = tabsComp.items.toArray(); headerElements = tabItems.map(item => item.headerComponent.nativeElement); diff --git a/projects/igniteui-angular/src/lib/test-utils/bottom-nav-components.spec.ts b/projects/igniteui-angular/src/lib/test-utils/bottom-nav-components.spec.ts index 5972d957232..b0889ca9b86 100644 --- a/projects/igniteui-angular/src/lib/test-utils/bottom-nav-components.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/bottom-nav-components.spec.ts @@ -284,7 +284,7 @@ export class BottomNavRoutingGuardTestComponent {
`, - imports: [IgxBottomNavComponent, IgxBottomNavItemComponent, IgxBottomNavHeaderComponent, IgxTabHeaderIconDirective, IgxTabHeaderLabelDirective, IgxBottomNavContentComponent] + imports: [IgxBottomNavComponent, IgxBottomNavItemComponent, IgxBottomNavHeaderComponent, IgxTabHeaderLabelDirective, IgxBottomNavContentComponent] }) export class BottomNavTestHtmlAttributesComponent { @ViewChild(IgxBottomNavComponent, { static: true }) public bottomNav: IgxBottomNavComponent; diff --git a/projects/igniteui-angular/src/lib/test-utils/configure-suite.ts b/projects/igniteui-angular/src/lib/test-utils/configure-suite.ts index 656236777cd..f6e68b677f5 100644 --- a/projects/igniteui-angular/src/lib/test-utils/configure-suite.ts +++ b/projects/igniteui-angular/src/lib/test-utils/configure-suite.ts @@ -1,5 +1,29 @@ +import { NgModuleRef } from '@angular/core'; import { TestBed, getTestBed, ComponentFixture, waitForAsync } from '@angular/core/testing'; +const checkLeaksAvailable = typeof window.gc === 'function'; + +const debug = false; +function debugLog(...args) { + if (debug) { + console.log(...args); + } +} + +let _skipLeakCheck = false; +const throwOnLeak = true; + +interface ConfigureOptions { + /** + * Check for memory leaks when the tests finishes. + * Note, this only works in Chrome configurations with expose the gc. + * Caveats: + * * if there are pending (non-cancelled) timers or animation frames it may report false positives. + * * if there's a beforeEach create it must be cleaned up in an afterEach to avoid being detected as a leak + */ + checkLeaks?: boolean; +} + /** * Per https://github.com/angular/angular/issues/12409#issuecomment-391087831 * Destroy fixtures after each, reset testing module after all @@ -7,9 +31,19 @@ import { TestBed, getTestBed, ComponentFixture, waitForAsync } from '@angular/co * @hidden */ -export const configureTestSuite = (configureAction?: () => TestBed) => { +export const configureTestSuite = (configureActionOrOptions?: (() => TestBed) | ConfigureOptions, options: ConfigureOptions = {}) => { + setupJasmineCurrentTest(); + + const configureAction = typeof configureActionOrOptions === 'function' ? configureActionOrOptions : undefined; + options = (configureActionOrOptions && typeof configureActionOrOptions === 'object') ? configureActionOrOptions : options; + options.checkLeaks = options.checkLeaks && checkLeaksAvailable; + + let componentRefs: { test: string, ref: WeakRef<{}> }[]; + const moduleRefs = new Set>(); + const testBed = getTestBed(); const originReset = testBed.resetTestingModule; + const originCreateComponent = testBed.createComponent; const clearStyles = () => { document.querySelectorAll('style').forEach(tag => tag.remove()); @@ -21,7 +55,22 @@ export const configureTestSuite = (configureAction?: () => TestBed) => { beforeAll(() => { testBed.resetTestingModule(); - testBed.resetTestingModule = () => testBed; + testBed.resetTestingModule = () => { + softResetTestingModule(); + return testBed; + }; + + if (options.checkLeaks) { + componentRefs = []; + testBed.createComponent = function () { + const fixture = originCreateComponent.apply(testBed, arguments); + if (!_skipLeakCheck) { + componentRefs.push({ test: jasmine['currentTest'].fullName, ref: new WeakRef(fixture.componentInstance) }); + } + return fixture; + }; + } + jasmine.getEnv().allowRespy(true); }); @@ -31,27 +80,96 @@ export const configureTestSuite = (configureAction?: () => TestBed) => { })); } - afterEach(() => { + function reportLeaks() { + gc(); + const leaks = componentRefs.map(({test, ref}) => ({ test, instance: ref.deref()})).filter(item => !!item.instance); + if (leaks.length > 0) { + console.warn(`Detected ${leaks.length} leaks:`); + for (const test of new Set(leaks.map(l => l.test))) { + const testLeaks = leaks.filter(l => l.test === test).map(l => l.instance); + const classNames = new Set(testLeaks.map(i => i.constructor.name)); + for (const name of classNames) { + const count = testLeaks.filter(i => i.constructor.name === name).length; + console.warn(` · ${name}: ${count} - ${test}`); + } + } + if (throwOnLeak) { + throw new Error(`Detected ${leaks.length} leaks`); + } + } else { + debugLog('No leaks detected'); + } + } + + function softResetTestingModule() { + debugLog("Soft-reset testing module"); clearStyles(); clearSVGContainer(); (testBed as any)._activeFixtures.forEach((fixture: ComponentFixture) => { const element = fixture.debugElement.nativeElement as HTMLElement; fixture.destroy(); + debugLog("Destroying fixture for component:", fixture.componentInstance.constructor.name); // If the fixture element ID changes, then it's not properly disposed element?.remove(); }); + (testBed as any)._activeFixtures = []; + // reset ViewEngine TestBed (testBed as any)._instantiated = false; + // reset Ivy TestBed - (testBed as any)._testModuleRef = null; - }); + const moduleRef = testBed['_testModuleRef']; + moduleRefs.add(moduleRef); + testBed['_testModuleRef'] = null; + } afterAll(() => { testBed.resetTestingModule = originReset; - testBed.resetTestingModule(); + debugLog(`Destroying ${moduleRefs.size} module refs`); + for (const moduleRef of moduleRefs) { + testBed['_testModuleRef'] = moduleRef; + testBed.resetTestingModule(); + } + moduleRefs.clear(); + + testBed.createComponent = originCreateComponent; + if (options.checkLeaks) { + reportLeaks(); + } }); }; +/** Calls to Testbed.createComponent() inside this wrapper wont be tracked for leaks */ +export function skipLeakCheck(fn: () => void | Promise) { + return function() { + _skipLeakCheck = true; + const res = fn(); + if (res instanceof Promise) { + return res.finally(() => { + _skipLeakCheck = false; + }); + } else { + _skipLeakCheck = false; + return res; + } + } +} + +let setupJasmineCurrentTestDone = false; +function setupJasmineCurrentTest() { + if (!setupJasmineCurrentTestDone) { + jasmine.getEnv().addReporter({ + specStarted(result) { + jasmine['currentTest'] = result; + }, + specDone(result) { + jasmine['currentTest'] = result; + }, + }); + setupJasmineCurrentTestDone = true; + } +} + // TODO: enable on re-run by selecting enable debug logging // https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/troubleshooting-workflows/enabling-debug-logging const shardLogging = false; diff --git a/projects/igniteui-angular/src/lib/test-utils/grid-base-components.spec.ts b/projects/igniteui-angular/src/lib/test-utils/grid-base-components.spec.ts index 621964458e2..8ac162068a9 100644 --- a/projects/igniteui-angular/src/lib/test-utils/grid-base-components.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/grid-base-components.spec.ts @@ -3,7 +3,6 @@ import { SampleTestData } from './sample-test-data.spec'; import { ColumnDefinitions, GridTemplateStrings } from './template-strings.spec'; import { IgxGridComponent } from '../grids/grid/grid.component'; import { IgxColumnActionsComponent } from '../grids/column-actions/column-actions.component'; -import { GridPagingMode } from '../grids/common/enums'; import { IgxColumnComponent } from '../grids/columns/column.component'; import { IgxGridToolbarComponent } from '../grids/toolbar/grid-toolbar.component'; import { IgxGridToolbarHidingComponent } from '../grids/toolbar/grid-toolbar-hiding.component'; @@ -123,7 +122,7 @@ export class PagingComponent extends GridWithSizeComponent { imports: [IgxGridComponent, IgxColumnComponent, IgxPaginatorComponent] }) export class RemotePagingComponent extends GridWithSizeComponent { - public pagingMode = GridPagingMode.Remote; + public pagingMode = 'remote'; public perPage = 3; public totalRecords = 10; public override data = SampleTestData.personJobDataFull(); diff --git a/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts b/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts index e4ebe0c5ef7..784f63e9965 100644 --- a/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts @@ -1192,7 +1192,7 @@ export class IgxGridAdvancedFilteringDynamicColumnsComponent extends BasicGridCo `, - imports: [IgxGridComponent, IgxColumnComponent, IgxGridToolbarComponent, IgxGridToolbarHidingComponent, IgxGridToolbarAdvancedFilteringComponent] + imports: [IgxGridComponent, IgxColumnComponent, IgxGridToolbarComponent, IgxGridToolbarAdvancedFilteringComponent] }) export class IgxGridAdvancedFilteringOverlaySettingsComponent extends BasicGridComponent { public customFilter = CustomFilter.instance(); @@ -1748,7 +1748,7 @@ export class IgxGridGroupByComponent extends DataParent implements OnInit { `, - imports: [IgxGridComponent, IgxColumnComponent, IgxCellTemplateDirective, IgxCellEditorTemplateDirective, IgxFocusDirective] + imports: [IgxGridComponent, IgxColumnComponent, IgxCellEditorTemplateDirective, IgxFocusDirective] }) export class CellEditingCustomEditorTestComponent extends BasicGridComponent { @ViewChild('cellEdit', { read: TemplateRef }) public templateCell; @@ -2070,6 +2070,7 @@ export class IgxGridFilteringBindingComponent extends BasicGridComponent impleme } @Component({ + selector: 'test-grid-advanced-filtering-binding', template: ` @@ -2101,6 +2102,7 @@ export class IgxGridAdvancedFilteringBindingComponent extends BasicGridComponent } @Component({ + selector: 'test-grid-advanced-filtering-serialized-tree', template: ` @@ -2120,7 +2122,7 @@ export class IgxGridAdvancedFilteringSerializedTreeComponent extends BasicGridCo public override data = SampleTestData.excelFilteringData(); public ngOnInit(): void { - this.filterTree = JSON.parse(`{ + this.filterTree = JSON.parse(`{ "filteringOperands": [ { "conditionName": "greaterThan", @@ -2626,6 +2628,7 @@ class CustomSummaryWithDate { } @Component({ + selector: 'test-grid-custom-summary', template: ` @@ -2645,6 +2648,7 @@ export class GridCustomSummaryComponent extends BasicGridComponent implements On } @Component({ + selector: 'test-grid-custom-summary-with-null-and-zero', template: ` @@ -2664,6 +2668,7 @@ export class GridCustomSummaryWithNullAndZeroComponent extends BasicGridComponen } @Component({ + selector: 'test-grid-custom-summary-with-undefined-zero-and-valid-number', template: ` @@ -2683,6 +2688,7 @@ export class GridCustomSummaryWithUndefinedZeroAndValidNumberComponent extends B } @Component({ + selector: 'test-grid-custom-summary-with-undefined-and-null', template: ` @@ -2702,6 +2708,7 @@ export class GridCustomSummaryWithUndefinedAndNullComponent extends BasicGridCom } @Component({ + selector: 'test-grid-custom-summary-with-date', template: ` diff --git a/projects/igniteui-angular/src/lib/test-utils/hierarchical-grid-components.spec.ts b/projects/igniteui-angular/src/lib/test-utils/hierarchical-grid-components.spec.ts index 17260327997..4e5afe2ca3f 100644 --- a/projects/igniteui-angular/src/lib/test-utils/hierarchical-grid-components.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/hierarchical-grid-components.spec.ts @@ -382,7 +382,7 @@ export class IgxHierarchicalGridTestCustomToolbarComponent extends IgxHierarchic `, - imports: [IgxHierarchicalGridComponent, IgxGridToolbarComponent, IgxGridToolbarDirective, IgxRowIslandComponent, IgxButtonDirective] + imports: [IgxHierarchicalGridComponent, IgxGridToolbarComponent, IgxRowIslandComponent, IgxButtonDirective] }) export class IgxHierarchicalGridTestInputToolbarComponent extends IgxHierarchicalGridTestBaseComponent { } @@ -444,7 +444,7 @@ export class IgxHierarchicalGridActionStripComponent extends IgxHierarchicalGrid @Component({ template: ` - + @@ -459,13 +459,13 @@ export class IgxHierarchicalGridActionStripComponent extends IgxHierarchicalGrid - + `, imports: [IgxHierarchicalGridComponent, IgxColumnComponent, IgxRowIslandComponent, IgxAdvancedFilteringDialogComponent] }) export class IgxHierGridExternalAdvancedFilteringComponent extends IgxHierarchicalGridTestBaseComponent { - // @ViewChild('hierarchicalGrid', { read: IgxHierarchicalGridComponent, static: true }) - // public hgrid: IgxHierarchicalGridComponent; + @ViewChild('hierarchicalGrid', { read: IgxHierarchicalGridComponent, static: true }) + public override hgrid: IgxHierarchicalGridComponent; public override data = SampleTestData.generateHGridData(5, 3); } @@ -484,6 +484,9 @@ export class IgxHierGridExternalAdvancedFilteringComponent extends IgxHierarchic + @if(shouldDisplayArtist) { + + } @@ -510,6 +513,7 @@ export class IgxHierGridExternalAdvancedFilteringComponent extends IgxHierarchic export class IgxHierarchicalGridExportComponent { @ViewChild('hierarchicalGrid', { read: IgxHierarchicalGridComponent, static: true }) public hGrid: IgxHierarchicalGridComponent; public data = SampleTestData.hierarchicalGridExportData(); + public shouldDisplayArtist = false; } diff --git a/projects/igniteui-angular/src/lib/test-utils/tabs-components.spec.ts b/projects/igniteui-angular/src/lib/test-utils/tabs-components.spec.ts index 6e3ed047f34..293d8d0d8c8 100644 --- a/projects/igniteui-angular/src/lib/test-utils/tabs-components.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/tabs-components.spec.ts @@ -377,29 +377,6 @@ export class TabsTabsOnlyModeTest1Component { public tabs: IgxTabsComponent; } -@Component({ - template: ` -
- - - Tab 1 - - - Tab 2 - - - Tab 3 - - -
- `, - imports: [IgxTabsComponent, IgxTabItemComponent, IgxTabHeaderComponent, IgxTabHeaderLabelDirective] -}) -export class TabsTabsOnlyModeTest2Component { - @ViewChild(IgxTabsComponent, { static: true }) - public tabs: IgxTabsComponent; -} - @Component({ template: `
diff --git a/src/app/action-strip/action-strip.sample.ts b/src/app/action-strip/action-strip.sample.ts index d9cbf04f0cc..79ea1196fc5 100644 --- a/src/app/action-strip/action-strip.sample.ts +++ b/src/app/action-strip/action-strip.sample.ts @@ -15,6 +15,7 @@ import { IRowDataCancelableEventArgs } from 'igniteui-angular'; +import { SAMPLE_DATA } from '../shared/sample-data'; class MyClone implements IDataCloneStrategy { @@ -148,34 +149,6 @@ export class ActionStripSampleComponent implements OnInit { this.userData.push(user); } - this.data = [ - { ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative', Address: 'Obere Str. 57', City: 'Berlin', Region: null, PostalCode: '12209', Country: 'Germany', Phone: '030-0074321', Fax: '030-0076545' }, - { ID: 'ANATR', CompanyName: 'Ana Trujillo Emparedados y helados', ContactName: 'Ana Trujillo', ContactTitle: 'Owner', Address: 'Avda. de la Constitución 2222', City: 'México D.F.', Region: null, PostalCode: '05021', Country: 'Mexico', Phone: '(5) 555-4729', Fax: '(5) 555-3745' }, - { ID: 'ANTON', CompanyName: 'Antonio Moreno Taquería', ContactName: 'Antonio Moreno', ContactTitle: 'Owner', Address: 'Mataderos 2312', City: 'México D.F.', Region: null, PostalCode: '05023', Country: 'Mexico', Phone: '(5) 555-3932', Fax: null }, - { ID: 'AROUT', CompanyName: 'Around the Horn', ContactName: 'Thomas Hardy', ContactTitle: 'Sales Representative', Address: '120 Hanover Sq.', City: 'London', Region: null, PostalCode: 'WA1 1DP', Country: 'UK', Phone: '(171) 555-7788', Fax: '(171) 555-6750' }, - { ID: 'BERGS', CompanyName: 'Berglunds snabbköp', ContactName: 'Christina Berglund', ContactTitle: 'Order Administrator', Address: 'Berguvsvägen 8', City: 'Luleå', Region: null, PostalCode: 'S-958 22', Country: 'Sweden', Phone: '0921-12 34 65', Fax: '0921-12 34 67' }, - { ID: 'BLAUS', CompanyName: 'Blauer See Delikatessen', ContactName: 'Hanna Moos', ContactTitle: 'Sales Representative', Address: 'Forsterstr. 57', City: 'Mannheim', Region: null, PostalCode: '68306', Country: 'Germany', Phone: '0621-08460', Fax: '0621-08924' }, - { ID: 'BLONP', CompanyName: 'Blondesddsl père et fils', ContactName: 'Frédérique Citeaux', ContactTitle: 'Marketing Manager', Address: '24, place Kléber', City: 'Strasbourg', Region: null, PostalCode: '67000', Country: 'France', Phone: '88.60.15.31', Fax: '88.60.15.32' }, - { ID: 'BOLID', CompanyName: 'Bólido Comidas preparadas', ContactName: 'Martín Sommer', ContactTitle: 'Owner', Address: 'C/ Araquil, 67', City: 'Madrid', Region: null, PostalCode: '28023', Country: 'Spain', Phone: '(91) 555 22 82', Fax: '(91) 555 91 99' }, - { ID: 'BONAP', CompanyName: 'Bon app\'', ContactName: 'Laurence Lebihan', ContactTitle: 'Owner', Address: '12, rue des Bouchers', City: 'Marseille', Region: null, PostalCode: '13008', Country: 'France', Phone: '91.24.45.40', Fax: '91.24.45.41' }, - { ID: 'BOTTM', CompanyName: 'Bottom-Dollar Markets', ContactName: 'Elizabeth Lincoln', ContactTitle: 'Accounting Manager', Address: '23 Tsawassen Blvd.', City: 'Tsawassen', Region: 'BC', PostalCode: 'T2F 8M4', Country: 'Canada', Phone: '(604) 555-4729', Fax: '(604) 555-3745' }, - { ID: 'BSBEV', CompanyName: 'B\'s Beverages', ContactName: 'Victoria Ashworth', ContactTitle: 'Sales Representative', Address: 'Fauntleroy Circus', City: 'London', Region: null, PostalCode: 'EC2 5NT', Country: 'UK', Phone: '(171) 555-1212', Fax: null }, - { ID: 'CACTU', CompanyName: 'Cactus Comidas para llevar', ContactName: 'Patricio Simpson', ContactTitle: 'Sales Agent', Address: 'Cerrito 333', City: 'Buenos Aires', Region: null, PostalCode: '1010', Country: 'Argentina', Phone: '(1) 135-5555', Fax: '(1) 135-4892' }, - { ID: 'CENTC', CompanyName: 'Centro comercial Moctezuma', ContactName: 'Francisco Chang', ContactTitle: 'Marketing Manager', Address: 'Sierras de Granada 9993', City: 'México D.F.', Region: null, PostalCode: '05022', Country: 'Mexico', Phone: '(5) 555-3392', Fax: '(5) 555-7293' }, - { ID: 'CHOPS', CompanyName: 'Chop-suey Chinese', ContactName: 'Yang Wang', ContactTitle: 'Owner', Address: 'Hauptstr. 29', City: 'Bern', Region: null, PostalCode: '3012', Country: 'Switzerland', Phone: '0452-076545', Fax: null }, - { ID: 'COMMI', CompanyName: 'Comércio Mineiro', ContactName: 'Pedro Afonso', ContactTitle: 'Sales Associate', Address: 'Av. dos Lusíadas, 23', City: 'Sao Paulo', Region: 'SP', PostalCode: '05432-043', Country: 'Brazil', Phone: '(11) 555-7647', Fax: null }, - { ID: 'CONSH', CompanyName: 'Consolidated Holdings', ContactName: 'Elizabeth Brown', ContactTitle: 'Sales Representative', Address: 'Berkeley Gardens 12 Brewery', City: 'London', Region: null, PostalCode: 'WX1 6LT', Country: 'UK', Phone: '(171) 555-2282', Fax: '(171) 555-9199' }, - { ID: 'DRACD', CompanyName: 'Drachenblut Delikatessen', ContactName: 'Sven Ottlieb', ContactTitle: 'Order Administrator', Address: 'Walserweg 21', City: 'Aachen', Region: null, PostalCode: '52066', Country: 'Germany', Phone: '0241-039123', Fax: '0241-059428' }, - { ID: 'DUMON', CompanyName: 'Du monde entier', ContactName: 'Janine Labrune', ContactTitle: 'Owner', Address: '67, rue des Cinquante Otages', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.67.88.88', Fax: '40.67.89.89' }, - { ID: 'EASTC', CompanyName: 'Eastern Connection', ContactName: 'Ann Devon', ContactTitle: 'Sales Agent', Address: '35 King George', City: 'London', Region: null, PostalCode: 'WX3 6FW', Country: 'UK', Phone: '(171) 555-0297', Fax: '(171) 555-3373' }, - { ID: 'ERNSH', CompanyName: 'Ernst Handel', ContactName: 'Roland Mendel', ContactTitle: 'Sales Manager', Address: 'Kirchgasse 6', City: 'Graz', Region: null, PostalCode: '8010', Country: 'Austria', Phone: '7675-3425', Fax: '7675-3426' }, - { ID: 'FAMIA', CompanyName: 'Familia Arquibaldo', ContactName: 'Aria Cruz', ContactTitle: 'Marketing Assistant', Address: 'Rua Orós, 92', City: 'Sao Paulo', Region: 'SP', PostalCode: '05442-030', Country: 'Brazil', Phone: '(11) 555-9857', Fax: null }, - { ID: 'FISSA', CompanyName: 'FISSA Fabrica Inter. Salchichas S.A.', ContactName: 'Diego Roel', ContactTitle: 'Accounting Manager', Address: 'C/ Moralzarzal, 86', City: 'Madrid', Region: null, PostalCode: '28034', Country: 'Spain', Phone: '(91) 555 94 44', Fax: '(91) 555 55 93' }, - { ID: 'FOLIG', CompanyName: 'Folies gourmandes', ContactName: 'Martine Rancé', ContactTitle: 'Assistant Sales Agent', Address: '184, chaussée de Tournai', City: 'Lille', Region: null, PostalCode: '59000', Country: 'France', Phone: '20.16.10.16', Fax: '20.16.10.17' }, - { ID: 'FOLKO', CompanyName: 'Folk och fä HB', ContactName: 'Maria Larsson', ContactTitle: 'Owner', Address: 'Åkergatan 24', City: 'Bräcke', Region: null, PostalCode: 'S-844 67', Country: 'Sweden', Phone: '0695-34 67 21', Fax: null }, - { ID: 'FRANK', CompanyName: 'Frankenversand', ContactName: 'Peter Franken', ContactTitle: 'Marketing Manager', Address: 'Berliner Platz 43', City: 'München', Region: null, PostalCode: '80805', Country: 'Germany', Phone: '089-0877310', Fax: '089-0877451' }, - { ID: 'FRANR', CompanyName: 'France restauration', ContactName: 'Carine Schmitt', ContactTitle: 'Marketing Manager', Address: '54, rue Royale', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.32.21.21', Fax: '40.32.21.20' }, - { ID: 'FRANS', CompanyName: 'Franchi S.p.A.', ContactName: 'Paolo Accorti', ContactTitle: 'Sales Representative', Address: 'Via Monte Bianco 34', City: 'Torino', Region: null, PostalCode: '10100', Country: 'Italy', Phone: '011-4988260', Fax: '011-4988261' } - ]; + this.data = SAMPLE_DATA; } } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 4b1626262d1..c4637552c6b 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -576,6 +576,10 @@ export class AppComponent implements OnInit { link: '/hierarchicalGrid', icon: 'view_column', name: 'Hierarchical Grid' + }, { + link: '/hierarchicalGridAdvancedFiltering', + icon: 'view_column', + name: 'Hierarchical Grid Advanced Filtering' }, { link: '/hierarchicalGridRemote', icon: 'swap_vert', diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 9ec076b2b3e..992516f1574 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -146,6 +146,7 @@ import { GridDockManagerSampleComponent } from './dockmanager-grid/dockmanager-g import { HoundComponent } from './hound/hound.component'; import { LabelSampleComponent } from "./label/label.sample"; import { GridRecreateSampleComponent } from './grid-re-create/grid-re-create.sample'; +import { HierarchicalGridAdvancedFilteringSampleComponent } from './hierarchical-grid-advanced-filtering/hierarchical-grid-advanced-filtering.sample'; export const appRoutes: Routes = [ { @@ -616,6 +617,9 @@ export const appRoutes: Routes = [ }, { path: 'hierarchicalGrid', component: HierarchicalGridSampleComponent + }, { + path: 'hierarchicalGridAdvancedFiltering', + component: HierarchicalGridAdvancedFilteringSampleComponent }, { path: 'hierarchicalGridRemote', component: HierarchicalGridRemoteSampleComponent diff --git a/src/app/buttonGroup/buttonGroup.sample.ts b/src/app/buttonGroup/buttonGroup.sample.ts index d78573ebda4..bf51787ac5a 100644 --- a/src/app/buttonGroup/buttonGroup.sample.ts +++ b/src/app/buttonGroup/buttonGroup.sample.ts @@ -94,7 +94,7 @@ export class ButtonGroupSampleComponent { selection: { control: { type: 'select', - options: ['single', 'single-required', 'multi'], + options: ['single', 'singleRequired', 'multi'], defaultValue: 'single' } }, @@ -127,7 +127,7 @@ export class ButtonGroupSampleComponent { private selectionMap = new Map( Object.entries({ single: 'single', - 'single-required': 'singleRequired', + 'singleRequired': 'single-required', multi: 'multiple', }) ); diff --git a/src/app/card/card.sample.html b/src/app/card/card.sample.html index 9cf9441a603..2ed8ed22b4b 100644 --- a/src/app/card/card.sample.html +++ b/src/app/card/card.sample.html @@ -3,8 +3,7 @@

Angular Card

-
- + @for(section of sectionOrder; track section) { @if(section === 'media' && !properties.hideMedia) { @@ -33,27 +32,27 @@

{{ cards[0].subtitle }}

@if(section === 'actions' && !properties.hideActions) { + @for(icon of cards[0].icons; track icon) { - - {{icon}} - + + {{icon}} + } }
}
-
-
- + @if(!properties.hideActions) { - + + @for(icon of cards[1].icons; track icon) {

} - -
- - - @if(!properties.hideHeader && !hideTitle) { -
{{cards[1].title}}
- } - @if(!properties.hideHeader && !hideSubtitle) { -
{{cards[1].subtitle}}
- } - @if(!properties.hideMedia) { - - - - } -
+ + @if(!properties.hideHeader) { + + @if(!hideTitle) { +
{{cards[1].title}}
+ } + @if(!hideSubtitle) { +
{{cards[1].subtitle}}
+ } + @if(!properties.hideMedia) { + + + + } +
+ } @if(!properties.hideActions) { - + @for(icon of cards[1].icons; track icon) {
-
- +
- - -

{{ cards[2].title }}

-
{{ cards[2].subtitle }}
-
- - @for(button of cards[2].buttons; track button){ - - } - + @if(!properties.hideHeader) { + + @if(!hideThumbnail) { + + } + + @if(!hideTitle) { +

{{ cards[2].title }}

+ } + + @if(!hideSubtitle) { +
{{ cards[2].subtitle }}
+ } +
+ } + + @if(!properties.hideActions) { + + @for(button of cards[2].buttons; track button){ + + } + + }
- + @if(!properties.hideMedia) { + + }
-
@@ -166,8 +177,7 @@
{{ cards[2].subtitle }}

WC Card

-
- + @for(section of sectionOrder; track section) { @if(section === 'media' && !properties.hideMedia) { @@ -217,11 +227,9 @@

WC Card

}
-
-
- + @if(!properties.hideActions) { @for(icon of cards[1].icons; track icon) { @@ -256,30 +264,38 @@

WC Card

}
-
- -
- - - @if(!properties.hideMedia) { - - - - } - @if(!properties.hideHeader) { @if(!hideTitle) { - {{cards[1].title}} - } - @if(!hideSubtitle) { - {{cards[1].subtitle}} + + +
+ @if(!properties.hideHeader) { + + @if(!properties.hideMedia) { +
+ + + +
+ } + + @if(!properties.hideHeader) { @if(!hideTitle) { + {{cards[1].title}} + } + @if(!hideSubtitle) { + {{cards[1].subtitle}} + } + } +
} - } - +
+ @if(!properties.hideActions) { - + @for(icon of cards[1].icons; track icon) {
-
- +
WC Card flex: 1 1 auto; " > - - - {{ cards[2].title }} - {{ cards[2].subtitle }} - + @if(!properties.hideHeader) { + + @if(!hideThumbnail) { + + } + @if(!hideTitle) { + {{ cards[2].title }} + } - + @if(!hideSubtitle) { + {{ cards[2].subtitle }} + } + + } + + @if(!properties.hideActions) { + @for(button of cards[2].buttons; track button){ {{ button }} } + }
- - - + @if(!properties.hideMedia) { + + + + }
-
diff --git a/src/app/card/card.sample.scss b/src/app/card/card.sample.scss index d16b00ad973..20d5693a185 100644 --- a/src/app/card/card.sample.scss +++ b/src/app/card/card.sample.scss @@ -1,29 +1,42 @@ .cards-wrapper { display: grid; - grid-template-columns: repeat(2, 1fr); + grid-template-columns: repeat(2, minmax(340px, 1fr)); justify-items: center; padding-block-start: 2rem; + gap: 1rem; } -.angular-cards, .wc-cards { - justify-items: center; +.angular-cards, +.wc-cards { display: grid; - grid-auto-flow: row; - grid-template-rows: subgrid; - grid-row: span 5; gap: 1rem; + grid-row: 1; } -.card { - min-width: 320px; - max-width: 320px; - h4 { - margin-bottom: 1rem; - } +.angular-cards:dir(rtl) { + grid-column: 2; +} + +.wc-cards:dir(rtl) { + grid-column: 1; } + .custom-controls { display: grid; gap: 1rem; } + +#igniteui-demo-app .sample-title { + margin-bottom: 0; + justify-self: center; +} + +#igniteui-demo-app .sample-wrapper { + height: auto; +} + +#igniteui-demo-app .content { + padding-bottom: 1rem; +} diff --git a/src/app/card/card.sample.ts b/src/app/card/card.sample.ts index b544e8d3f23..629acf4db5c 100644 --- a/src/app/card/card.sample.ts +++ b/src/app/card/card.sample.ts @@ -152,6 +152,13 @@ export class CardSampleComponent implements OnInit { defaultValue: false } }, + justifyActions: { + label: 'Justify actions(Angular Only)', + control: { + type: 'boolean', + defaultValue: true + } + }, }; public properties: Properties; diff --git a/src/app/drag-drop/drag-drop.sample.ts b/src/app/drag-drop/drag-drop.sample.ts index 5227c8bd1e2..ee4f7874798 100644 --- a/src/app/drag-drop/drag-drop.sample.ts +++ b/src/app/drag-drop/drag-drop.sample.ts @@ -100,7 +100,7 @@ export class DragDropSampleComponent { public toggleStartPageY; // Multi selection row drag - public sourceRows: any[] = Array.from(Array(10)).map((e, i) => { + public sourceRows: any[] = Array.from(Array(10)).map((_e, i) => { return {name: "Item " + i, selected: false} }); public targetRows: any[] = []; @@ -330,7 +330,7 @@ export class DragDropSampleComponent { item.dragged = false; } - public listItemEnter(event, itemIndex) { + public listItemEnter(_event, itemIndex) { const moveDown = this.draggedIndex < itemIndex; const listNotesDirsArray = this.listNotesDirs.toArray(); @@ -391,7 +391,7 @@ export class DragDropSampleComponent { } } - public listItemOver(event, itemIndex) { + public listItemOver(_event, itemIndex) { const moveDown = itemIndex > this.draggedIndex; const itemDragDir = this.listNotesDirs.toArray()[itemIndex]; diff --git a/src/app/drag-drop/shadow-dom-grid/shadow-grid-sample.scss b/src/app/drag-drop/shadow-dom-grid/shadow-grid-sample.scss index e69de29bb2d..9f90f2ef130 100644 --- a/src/app/drag-drop/shadow-dom-grid/shadow-grid-sample.scss +++ b/src/app/drag-drop/shadow-dom-grid/shadow-grid-sample.scss @@ -0,0 +1,3 @@ +@use '../../../styles/demo-theme' as *; +@import url('https://fonts.googleapis.com/icon?family=Material+Icons'); +@import url('https://fonts.googleapis.com/css?family=Titillium+Web:300,400,600,700'); diff --git a/src/app/drop-down/drop-down.sample.html b/src/app/drop-down/drop-down.sample.html index f78f2137fd1..255bd3bcac6 100644 --- a/src/app/drop-down/drop-down.sample.html +++ b/src/app/drop-down/drop-down.sample.html @@ -108,8 +108,8 @@
Angular Dropdown With Action directive
- @for(item of items; track item) { -
{{ item.field }}
+ @for(item of items; track item.field) { +
{{ item.field }}
}
diff --git a/src/app/drop-down/drop-down.sample.ts b/src/app/drop-down/drop-down.sample.ts index decbd135a56..582819db69f 100644 --- a/src/app/drop-down/drop-down.sample.ts +++ b/src/app/drop-down/drop-down.sample.ts @@ -94,7 +94,7 @@ export class DropDownSampleComponent implements OnInit { @ViewChild(IgxOverlayOutletDirective, { static: true }) private igxOverlayOutlet: IgxOverlayOutletDirective; - public items: any[] = []; + public items: { field: string, header?: string, disabled?: boolean, selected?: boolean }[] = []; public foods = foods; public panelConfig: PropertyPanelConfig = { @@ -261,7 +261,7 @@ export class DropDownSampleComponent implements OnInit { this.items.push(item); } - this.items[3]['selected'] = true; + this.items[3].selected = true; } public clearSelection() { diff --git a/src/app/grid-cell-api/grid-cell-api.sample.ts b/src/app/grid-cell-api/grid-cell-api.sample.ts index b0352720395..6959ea29f40 100644 --- a/src/app/grid-cell-api/grid-cell-api.sample.ts +++ b/src/app/grid-cell-api/grid-cell-api.sample.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Renderer2, ViewChild } from '@angular/core'; +import { Component, OnInit, Renderer2 } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { IgxGridComponent, @@ -16,7 +16,7 @@ import { IgxIconComponent, IgxRowIslandComponent } from 'igniteui-angular'; -import { HIERARCHICAL_SAMPLE_DATA } from '../shared/sample-data'; +import { HIERARCHICAL_SAMPLE_DATA, SAMPLE_DATA } from '../shared/sample-data'; @Component({ selector: 'app-grid-cell-api-sample', @@ -26,9 +26,6 @@ import { HIERARCHICAL_SAMPLE_DATA } from '../shared/sample-data'; }) export class GridCellAPISampleComponent implements OnInit { - @ViewChild('grid', { static: true }) - private grid: IgxGridComponent; - public data2: any; public data: any[]; public treeGridHierData: any[]; @@ -98,35 +95,7 @@ export class GridCellAPISampleComponent implements OnInit { ]; this.treeGridHierData = HIERARCHICAL_SAMPLE_DATA.slice(0); - this.data = [ - { ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative', Address: 'Obere Str. 57', City: 'Berlin', Region: null, PostalCode: '12209', Country: 'Germany', Phone: '030-0074321', Fax: '030-0076545' }, - { ID: 'ANATR', CompanyName: 'Ana Trujillo Emparedados y helados', ContactName: 'Ana Trujillo', ContactTitle: 'Owner', Address: 'Avda. de la Constitución 2222', City: 'México D.F.', Region: null, PostalCode: '05021', Country: 'Mexico', Phone: '(5) 555-4729', Fax: '(5) 555-3745' }, - { ID: 'ANTON', CompanyName: 'Antonio Moreno Taquería', ContactName: 'Antonio Moreno', ContactTitle: 'Owner', Address: 'Mataderos 2312', City: 'México D.F.', Region: null, PostalCode: '05023', Country: 'Mexico', Phone: '(5) 555-3932', Fax: null }, - { ID: 'AROUT', CompanyName: 'Around the Horn', ContactName: 'Thomas Hardy', ContactTitle: 'Sales Representative', Address: '120 Hanover Sq.', City: 'London', Region: null, PostalCode: 'WA1 1DP', Country: 'UK', Phone: '(171) 555-7788', Fax: '(171) 555-6750' }, - { ID: 'BERGS', CompanyName: 'Berglunds snabbköp', ContactName: 'Christina Berglund', ContactTitle: 'Order Administrator', Address: 'Berguvsvägen 8', City: 'Luleå', Region: null, PostalCode: 'S-958 22', Country: 'Sweden', Phone: '0921-12 34 65', Fax: '0921-12 34 67' }, - { ID: 'BLAUS', CompanyName: 'Blauer See Delikatessen', ContactName: 'Hanna Moos', ContactTitle: 'Sales Representative', Address: 'Forsterstr. 57', City: 'Mannheim', Region: null, PostalCode: '68306', Country: 'Germany', Phone: '0621-08460', Fax: '0621-08924' }, - { ID: 'BLONP', CompanyName: 'Blondesddsl père et fils', ContactName: 'Frédérique Citeaux', ContactTitle: 'Marketing Manager', Address: '24, place Kléber', City: 'Strasbourg', Region: null, PostalCode: '67000', Country: 'France', Phone: '88.60.15.31', Fax: '88.60.15.32' }, - { ID: 'BOLID', CompanyName: 'Bólido Comidas preparadas', ContactName: 'Martín Sommer', ContactTitle: 'Owner', Address: 'C/ Araquil, 67', City: 'Madrid', Region: null, PostalCode: '28023', Country: 'Spain', Phone: '(91) 555 22 82', Fax: '(91) 555 91 99' }, - { ID: 'BONAP', CompanyName: 'Bon app\'', ContactName: 'Laurence Lebihan', ContactTitle: 'Owner', Address: '12, rue des Bouchers', City: 'Marseille', Region: null, PostalCode: '13008', Country: 'France', Phone: '91.24.45.40', Fax: '91.24.45.41' }, - { ID: 'BOTTM', CompanyName: 'Bottom-Dollar Markets', ContactName: 'Elizabeth Lincoln', ContactTitle: 'Accounting Manager', Address: '23 Tsawassen Blvd.', City: 'Tsawassen', Region: 'BC', PostalCode: 'T2F 8M4', Country: 'Canada', Phone: '(604) 555-4729', Fax: '(604) 555-3745' }, - { ID: 'BSBEV', CompanyName: 'B\'s Beverages', ContactName: 'Victoria Ashworth', ContactTitle: 'Sales Representative', Address: 'Fauntleroy Circus', City: 'London', Region: null, PostalCode: 'EC2 5NT', Country: 'UK', Phone: '(171) 555-1212', Fax: null }, - { ID: 'CACTU', CompanyName: 'Cactus Comidas para llevar', ContactName: 'Patricio Simpson', ContactTitle: 'Sales Agent', Address: 'Cerrito 333', City: 'Buenos Aires', Region: null, PostalCode: '1010', Country: 'Argentina', Phone: '(1) 135-5555', Fax: '(1) 135-4892' }, - { ID: 'CENTC', CompanyName: 'Centro comercial Moctezuma', ContactName: 'Francisco Chang', ContactTitle: 'Marketing Manager', Address: 'Sierras de Granada 9993', City: 'México D.F.', Region: null, PostalCode: '05022', Country: 'Mexico', Phone: '(5) 555-3392', Fax: '(5) 555-7293' }, - { ID: 'CHOPS', CompanyName: 'Chop-suey Chinese', ContactName: 'Yang Wang', ContactTitle: 'Owner', Address: 'Hauptstr. 29', City: 'Bern', Region: null, PostalCode: '3012', Country: 'Switzerland', Phone: '0452-076545', Fax: null }, - { ID: 'COMMI', CompanyName: 'Comércio Mineiro', ContactName: 'Pedro Afonso', ContactTitle: 'Sales Associate', Address: 'Av. dos Lusíadas, 23', City: 'Sao Paulo', Region: 'SP', PostalCode: '05432-043', Country: 'Brazil', Phone: '(11) 555-7647', Fax: null }, - { ID: 'CONSH', CompanyName: 'Consolidated Holdings', ContactName: 'Elizabeth Brown', ContactTitle: 'Sales Representative', Address: 'Berkeley Gardens 12 Brewery', City: 'London', Region: null, PostalCode: 'WX1 6LT', Country: 'UK', Phone: '(171) 555-2282', Fax: '(171) 555-9199' }, - { ID: 'DRACD', CompanyName: 'Drachenblut Delikatessen', ContactName: 'Sven Ottlieb', ContactTitle: 'Order Administrator', Address: 'Walserweg 21', City: 'Aachen', Region: null, PostalCode: '52066', Country: 'Germany', Phone: '0241-039123', Fax: '0241-059428' }, - { ID: 'DUMON', CompanyName: 'Du monde entier', ContactName: 'Janine Labrune', ContactTitle: 'Owner', Address: '67, rue des Cinquante Otages', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.67.88.88', Fax: '40.67.89.89' }, - { ID: 'EASTC', CompanyName: 'Eastern Connection', ContactName: 'Ann Devon', ContactTitle: 'Sales Agent', Address: '35 King George', City: 'London', Region: null, PostalCode: 'WX3 6FW', Country: 'UK', Phone: '(171) 555-0297', Fax: '(171) 555-3373' }, - { ID: 'ERNSH', CompanyName: 'Ernst Handel', ContactName: 'Roland Mendel', ContactTitle: 'Sales Manager', Address: 'Kirchgasse 6', City: 'Graz', Region: null, PostalCode: '8010', Country: 'Austria', Phone: '7675-3425', Fax: '7675-3426' }, - { ID: 'FAMIA', CompanyName: 'Familia Arquibaldo', ContactName: 'Aria Cruz', ContactTitle: 'Marketing Assistant', Address: 'Rua Orós, 92', City: 'Sao Paulo', Region: 'SP', PostalCode: '05442-030', Country: 'Brazil', Phone: '(11) 555-9857', Fax: null }, - { ID: 'FISSA', CompanyName: 'FISSA Fabrica Inter. Salchichas S.A.', ContactName: 'Diego Roel', ContactTitle: 'Accounting Manager', Address: 'C/ Moralzarzal, 86', City: 'Madrid', Region: null, PostalCode: '28034', Country: 'Spain', Phone: '(91) 555 94 44', Fax: '(91) 555 55 93' }, - { ID: 'FOLIG', CompanyName: 'Folies gourmandes', ContactName: 'Martine Rancé', ContactTitle: 'Assistant Sales Agent', Address: '184, chaussée de Tournai', City: 'Lille', Region: null, PostalCode: '59000', Country: 'France', Phone: '20.16.10.16', Fax: '20.16.10.17' }, - { ID: 'FOLKO', CompanyName: 'Folk och fä HB', ContactName: 'Maria Larsson', ContactTitle: 'Owner', Address: 'Åkergatan 24', City: 'Bräcke', Region: null, PostalCode: 'S-844 67', Country: 'Sweden', Phone: '0695-34 67 21', Fax: null }, - { ID: 'FRANK', CompanyName: 'Frankenversand', ContactName: 'Peter Franken', ContactTitle: 'Marketing Manager', Address: 'Berliner Platz 43', City: 'München', Region: null, PostalCode: '80805', Country: 'Germany', Phone: '089-0877310', Fax: '089-0877451' }, - { ID: 'FRANR', CompanyName: 'France restauration', ContactName: 'Carine Schmitt', ContactTitle: 'Marketing Manager', Address: '54, rue Royale', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.32.21.21', Fax: '40.32.21.20' }, - { ID: 'FRANS', CompanyName: 'Franchi S.p.A.', ContactName: 'Paolo Accorti', ContactTitle: 'Sales Representative', Address: 'Via Monte Bianco 34', City: 'Torino', Region: null, PostalCode: '10100', Country: 'Italy', Phone: '011-4988260', Fax: '011-4988261' } - ]; + this.data = SAMPLE_DATA; this.hierarchicalData = this.generateDataUneven(100, 3); // treegrid cols and data diff --git a/src/app/grid-column-actions/grid-column-actions.sample.ts b/src/app/grid-column-actions/grid-column-actions.sample.ts index fa906822c99..38898d7477e 100644 --- a/src/app/grid-column-actions/grid-column-actions.sample.ts +++ b/src/app/grid-column-actions/grid-column-actions.sample.ts @@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { IgxColumnGroupingDirective } from './custom-action-directive'; import { IColumnToggledEventArgs, IGX_GRID_DIRECTIVES } from 'igniteui-angular'; +import { SAMPLE_DATA } from '../shared/sample-data'; @Component({ providers: [], @@ -32,34 +33,6 @@ export class GridColumnActionsSampleComponent implements OnInit { { field: 'Fax', width: '200px' } ]; - this.data = [ - { ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative', Address: 'Obere Str. 57', City: 'Berlin', Region: null, PostalCode: '12209', Country: 'Germany', Phone: '030-0074321', Fax: '030-0076545' }, - { ID: 'ANATR', CompanyName: 'Ana Trujillo Emparedados y helados', ContactName: 'Ana Trujillo', ContactTitle: 'Owner', Address: 'Avda. de la Constitución 2222', City: 'México D.F.', Region: null, PostalCode: '05021', Country: 'Mexico', Phone: '(5) 555-4729', Fax: '(5) 555-3745' }, - { ID: 'ANTON', CompanyName: 'Antonio Moreno Taquería', ContactName: 'Antonio Moreno', ContactTitle: 'Owner', Address: 'Mataderos 2312', City: 'México D.F.', Region: null, PostalCode: '05023', Country: 'Mexico', Phone: '(5) 555-3932', Fax: null }, - { ID: 'AROUT', CompanyName: 'Around the Horn', ContactName: 'Thomas Hardy', ContactTitle: 'Sales Representative', Address: '120 Hanover Sq.', City: 'London', Region: null, PostalCode: 'WA1 1DP', Country: 'UK', Phone: '(171) 555-7788', Fax: '(171) 555-6750' }, - { ID: 'BERGS', CompanyName: 'Berglunds snabbköp', ContactName: 'Christina Berglund', ContactTitle: 'Order Administrator', Address: 'Berguvsvägen 8', City: 'Luleå', Region: null, PostalCode: 'S-958 22', Country: 'Sweden', Phone: '0921-12 34 65', Fax: '0921-12 34 67' }, - { ID: 'BLAUS', CompanyName: 'Blauer See Delikatessen', ContactName: 'Hanna Moos', ContactTitle: 'Sales Representative', Address: 'Forsterstr. 57', City: 'Mannheim', Region: null, PostalCode: '68306', Country: 'Germany', Phone: '0621-08460', Fax: '0621-08924' }, - { ID: 'BLONP', CompanyName: 'Blondesddsl père et fils', ContactName: 'Frédérique Citeaux', ContactTitle: 'Marketing Manager', Address: '24, place Kléber', City: 'Strasbourg', Region: null, PostalCode: '67000', Country: 'France', Phone: '88.60.15.31', Fax: '88.60.15.32' }, - { ID: 'BOLID', CompanyName: 'Bólido Comidas preparadas', ContactName: 'Martín Sommer', ContactTitle: 'Owner', Address: 'C/ Araquil, 67', City: 'Madrid', Region: null, PostalCode: '28023', Country: 'Spain', Phone: '(91) 555 22 82', Fax: '(91) 555 91 99' }, - { ID: 'BONAP', CompanyName: 'Bon app\'', ContactName: 'Laurence Lebihan', ContactTitle: 'Owner', Address: '12, rue des Bouchers', City: 'Marseille', Region: null, PostalCode: '13008', Country: 'France', Phone: '91.24.45.40', Fax: '91.24.45.41' }, - { ID: 'BOTTM', CompanyName: 'Bottom-Dollar Markets', ContactName: 'Elizabeth Lincoln', ContactTitle: 'Accounting Manager', Address: '23 Tsawassen Blvd.', City: 'Tsawassen', Region: 'BC', PostalCode: 'T2F 8M4', Country: 'Canada', Phone: '(604) 555-4729', Fax: '(604) 555-3745' }, - { ID: 'BSBEV', CompanyName: 'B\'s Beverages', ContactName: 'Victoria Ashworth', ContactTitle: 'Sales Representative', Address: 'Fauntleroy Circus', City: 'London', Region: null, PostalCode: 'EC2 5NT', Country: 'UK', Phone: '(171) 555-1212', Fax: null }, - { ID: 'CACTU', CompanyName: 'Cactus Comidas para llevar', ContactName: 'Patricio Simpson', ContactTitle: 'Sales Agent', Address: 'Cerrito 333', City: 'Buenos Aires', Region: null, PostalCode: '1010', Country: 'Argentina', Phone: '(1) 135-5555', Fax: '(1) 135-4892' }, - { ID: 'CENTC', CompanyName: 'Centro comercial Moctezuma', ContactName: 'Francisco Chang', ContactTitle: 'Marketing Manager', Address: 'Sierras de Granada 9993', City: 'México D.F.', Region: null, PostalCode: '05022', Country: 'Mexico', Phone: '(5) 555-3392', Fax: '(5) 555-7293' }, - { ID: 'CHOPS', CompanyName: 'Chop-suey Chinese', ContactName: 'Yang Wang', ContactTitle: 'Owner', Address: 'Hauptstr. 29', City: 'Bern', Region: null, PostalCode: '3012', Country: 'Switzerland', Phone: '0452-076545', Fax: null }, - { ID: 'COMMI', CompanyName: 'Comércio Mineiro', ContactName: 'Pedro Afonso', ContactTitle: 'Sales Associate', Address: 'Av. dos Lusíadas, 23', City: 'Sao Paulo', Region: 'SP', PostalCode: '05432-043', Country: 'Brazil', Phone: '(11) 555-7647', Fax: null }, - { ID: 'CONSH', CompanyName: 'Consolidated Holdings', ContactName: 'Elizabeth Brown', ContactTitle: 'Sales Representative', Address: 'Berkeley Gardens 12 Brewery', City: 'London', Region: null, PostalCode: 'WX1 6LT', Country: 'UK', Phone: '(171) 555-2282', Fax: '(171) 555-9199' }, - { ID: 'DRACD', CompanyName: 'Drachenblut Delikatessen', ContactName: 'Sven Ottlieb', ContactTitle: 'Order Administrator', Address: 'Walserweg 21', City: 'Aachen', Region: null, PostalCode: '52066', Country: 'Germany', Phone: '0241-039123', Fax: '0241-059428' }, - { ID: 'DUMON', CompanyName: 'Du monde entier', ContactName: 'Janine Labrune', ContactTitle: 'Owner', Address: '67, rue des Cinquante Otages', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.67.88.88', Fax: '40.67.89.89' }, - { ID: 'EASTC', CompanyName: 'Eastern Connection', ContactName: 'Ann Devon', ContactTitle: 'Sales Agent', Address: '35 King George', City: 'London', Region: null, PostalCode: 'WX3 6FW', Country: 'UK', Phone: '(171) 555-0297', Fax: '(171) 555-3373' }, - { ID: 'ERNSH', CompanyName: 'Ernst Handel', ContactName: 'Roland Mendel', ContactTitle: 'Sales Manager', Address: 'Kirchgasse 6', City: 'Graz', Region: null, PostalCode: '8010', Country: 'Austria', Phone: '7675-3425', Fax: '7675-3426' }, - { ID: 'FAMIA', CompanyName: 'Familia Arquibaldo', ContactName: 'Aria Cruz', ContactTitle: 'Marketing Assistant', Address: 'Rua Orós, 92', City: 'Sao Paulo', Region: 'SP', PostalCode: '05442-030', Country: 'Brazil', Phone: '(11) 555-9857', Fax: null }, - { ID: 'FISSA', CompanyName: 'FISSA Fabrica Inter. Salchichas S.A.', ContactName: 'Diego Roel', ContactTitle: 'Accounting Manager', Address: 'C/ Moralzarzal, 86', City: 'Madrid', Region: null, PostalCode: '28034', Country: 'Spain', Phone: '(91) 555 94 44', Fax: '(91) 555 55 93' }, - { ID: 'FOLIG', CompanyName: 'Folies gourmandes', ContactName: 'Martine Rancé', ContactTitle: 'Assistant Sales Agent', Address: '184, chaussée de Tournai', City: 'Lille', Region: null, PostalCode: '59000', Country: 'France', Phone: '20.16.10.16', Fax: '20.16.10.17' }, - { ID: 'FOLKO', CompanyName: 'Folk och fä HB', ContactName: 'Maria Larsson', ContactTitle: 'Owner', Address: 'Åkergatan 24', City: 'Bräcke', Region: null, PostalCode: 'S-844 67', Country: 'Sweden', Phone: '0695-34 67 21', Fax: null }, - { ID: 'FRANK', CompanyName: 'Frankenversand', ContactName: 'Peter Franken', ContactTitle: 'Marketing Manager', Address: 'Berliner Platz 43', City: 'München', Region: null, PostalCode: '80805', Country: 'Germany', Phone: '089-0877310', Fax: '089-0877451' }, - { ID: 'FRANR', CompanyName: 'France restauration', ContactName: 'Carine Schmitt', ContactTitle: 'Marketing Manager', Address: '54, rue Royale', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.32.21.21', Fax: '40.32.21.20' }, - { ID: 'FRANS', CompanyName: 'Franchi S.p.A.', ContactName: 'Paolo Accorti', ContactTitle: 'Sales Representative', Address: 'Via Monte Bianco 34', City: 'Torino', Region: null, PostalCode: '10100', Country: 'Italy', Phone: '011-4988260', Fax: '011-4988261' } - ]; + this.data = SAMPLE_DATA; } } diff --git a/src/app/grid-column-pinning/grid-column-pinning.sample.ts b/src/app/grid-column-pinning/grid-column-pinning.sample.ts index 4f078e97196..78cb96eda90 100644 --- a/src/app/grid-column-pinning/grid-column-pinning.sample.ts +++ b/src/app/grid-column-pinning/grid-column-pinning.sample.ts @@ -1,6 +1,7 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { ColumnPinningPosition, GridSelectionMode, IPinningConfig, IgxButtonDirective, IgxColumnComponent, IgxGridComponent, IgxGridToolbarActionsComponent, IgxGridToolbarComponent, IgxGridToolbarPinningComponent, IgxGridToolbarTitleComponent, IgxSwitchComponent, RowPinningPosition, RowType } from 'igniteui-angular'; +import { SAMPLE_DATA } from '../shared/sample-data'; @@ -63,35 +64,7 @@ export class GridColumnPinningSampleComponent implements OnInit { { field: 'Fax', width: '200px' } ]; - this.data = [ - { ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative', Address: 'Obere Str. 57', City: 'Berlin', Region: null, PostalCode: '12209', Country: 'Germany', Phone: '030-0074321', Fax: '030-0076545' }, - { ID: 'ANATR', CompanyName: 'Ana Trujillo Emparedados y helados', ContactName: 'Ana Trujillo', ContactTitle: 'Owner', Address: 'Avda. de la Constitución 2222', City: 'México D.F.', Region: null, PostalCode: '05021', Country: 'Mexico', Phone: '(5) 555-4729', Fax: '(5) 555-3745' }, - { ID: 'ANTON', CompanyName: 'Antonio Moreno Taquería', ContactName: 'Antonio Moreno', ContactTitle: 'Owner', Address: 'Mataderos 2312', City: 'México D.F.', Region: null, PostalCode: '05023', Country: 'Mexico', Phone: '(5) 555-3932', Fax: null }, - { ID: 'AROUT', CompanyName: 'Around the Horn', ContactName: 'Thomas Hardy', ContactTitle: 'Sales Representative', Address: '120 Hanover Sq.', City: 'London', Region: null, PostalCode: 'WA1 1DP', Country: 'UK', Phone: '(171) 555-7788', Fax: '(171) 555-6750' }, - { ID: 'BERGS', CompanyName: 'Berglunds snabbköp', ContactName: 'Christina Berglund', ContactTitle: 'Order Administrator', Address: 'Berguvsvägen 8', City: 'Luleå', Region: null, PostalCode: 'S-958 22', Country: 'Sweden', Phone: '0921-12 34 65', Fax: '0921-12 34 67' }, - { ID: 'BLAUS', CompanyName: 'Blauer See Delikatessen', ContactName: 'Hanna Moos', ContactTitle: 'Sales Representative', Address: 'Forsterstr. 57', City: 'Mannheim', Region: null, PostalCode: '68306', Country: 'Germany', Phone: '0621-08460', Fax: '0621-08924' }, - { ID: 'BLONP', CompanyName: 'Blondesddsl père et fils', ContactName: 'Frédérique Citeaux', ContactTitle: 'Marketing Manager', Address: '24, place Kléber', City: 'Strasbourg', Region: null, PostalCode: '67000', Country: 'France', Phone: '88.60.15.31', Fax: '88.60.15.32' }, - { ID: 'BOLID', CompanyName: 'Bólido Comidas preparadas', ContactName: 'Martín Sommer', ContactTitle: 'Owner', Address: 'C/ Araquil, 67', City: 'Madrid', Region: null, PostalCode: '28023', Country: 'Spain', Phone: '(91) 555 22 82', Fax: '(91) 555 91 99' }, - { ID: 'BONAP', CompanyName: 'Bon app\'', ContactName: 'Laurence Lebihan', ContactTitle: 'Owner', Address: '12, rue des Bouchers', City: 'Marseille', Region: null, PostalCode: '13008', Country: 'France', Phone: '91.24.45.40', Fax: '91.24.45.41' }, - { ID: 'BOTTM', CompanyName: 'Bottom-Dollar Markets', ContactName: 'Elizabeth Lincoln', ContactTitle: 'Accounting Manager', Address: '23 Tsawassen Blvd.', City: 'Tsawassen', Region: 'BC', PostalCode: 'T2F 8M4', Country: 'Canada', Phone: '(604) 555-4729', Fax: '(604) 555-3745' }, - { ID: 'BSBEV', CompanyName: 'B\'s Beverages', ContactName: 'Victoria Ashworth', ContactTitle: 'Sales Representative', Address: 'Fauntleroy Circus', City: 'London', Region: null, PostalCode: 'EC2 5NT', Country: 'UK', Phone: '(171) 555-1212', Fax: null }, - { ID: 'CACTU', CompanyName: 'Cactus Comidas para llevar', ContactName: 'Patricio Simpson', ContactTitle: 'Sales Agent', Address: 'Cerrito 333', City: 'Buenos Aires', Region: null, PostalCode: '1010', Country: 'Argentina', Phone: '(1) 135-5555', Fax: '(1) 135-4892' }, - { ID: 'CENTC', CompanyName: 'Centro comercial Moctezuma', ContactName: 'Francisco Chang', ContactTitle: 'Marketing Manager', Address: 'Sierras de Granada 9993', City: 'México D.F.', Region: null, PostalCode: '05022', Country: 'Mexico', Phone: '(5) 555-3392', Fax: '(5) 555-7293' }, - { ID: 'CHOPS', CompanyName: 'Chop-suey Chinese', ContactName: 'Yang Wang', ContactTitle: 'Owner', Address: 'Hauptstr. 29', City: 'Bern', Region: null, PostalCode: '3012', Country: 'Switzerland', Phone: '0452-076545', Fax: null }, - { ID: 'COMMI', CompanyName: 'Comércio Mineiro', ContactName: 'Pedro Afonso', ContactTitle: 'Sales Associate', Address: 'Av. dos Lusíadas, 23', City: 'Sao Paulo', Region: 'SP', PostalCode: '05432-043', Country: 'Brazil', Phone: '(11) 555-7647', Fax: null }, - { ID: 'CONSH', CompanyName: 'Consolidated Holdings', ContactName: 'Elizabeth Brown', ContactTitle: 'Sales Representative', Address: 'Berkeley Gardens 12 Brewery', City: 'London', Region: null, PostalCode: 'WX1 6LT', Country: 'UK', Phone: '(171) 555-2282', Fax: '(171) 555-9199' }, - { ID: 'DRACD', CompanyName: 'Drachenblut Delikatessen', ContactName: 'Sven Ottlieb', ContactTitle: 'Order Administrator', Address: 'Walserweg 21', City: 'Aachen', Region: null, PostalCode: '52066', Country: 'Germany', Phone: '0241-039123', Fax: '0241-059428' }, - { ID: 'DUMON', CompanyName: 'Du monde entier', ContactName: 'Janine Labrune', ContactTitle: 'Owner', Address: '67, rue des Cinquante Otages', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.67.88.88', Fax: '40.67.89.89' }, - { ID: 'EASTC', CompanyName: 'Eastern Connection', ContactName: 'Ann Devon', ContactTitle: 'Sales Agent', Address: '35 King George', City: 'London', Region: null, PostalCode: 'WX3 6FW', Country: 'UK', Phone: '(171) 555-0297', Fax: '(171) 555-3373' }, - { ID: 'ERNSH', CompanyName: 'Ernst Handel', ContactName: 'Roland Mendel', ContactTitle: 'Sales Manager', Address: 'Kirchgasse 6', City: 'Graz', Region: null, PostalCode: '8010', Country: 'Austria', Phone: '7675-3425', Fax: '7675-3426' }, - { ID: 'FAMIA', CompanyName: 'Familia Arquibaldo', ContactName: 'Aria Cruz', ContactTitle: 'Marketing Assistant', Address: 'Rua Orós, 92', City: 'Sao Paulo', Region: 'SP', PostalCode: '05442-030', Country: 'Brazil', Phone: '(11) 555-9857', Fax: null }, - { ID: 'FISSA', CompanyName: 'FISSA Fabrica Inter. Salchichas S.A.', ContactName: 'Diego Roel', ContactTitle: 'Accounting Manager', Address: 'C/ Moralzarzal, 86', City: 'Madrid', Region: null, PostalCode: '28034', Country: 'Spain', Phone: '(91) 555 94 44', Fax: '(91) 555 55 93' }, - { ID: 'FOLIG', CompanyName: 'Folies gourmandes', ContactName: 'Martine Rancé', ContactTitle: 'Assistant Sales Agent', Address: '184, chaussée de Tournai', City: 'Lille', Region: null, PostalCode: '59000', Country: 'France', Phone: '20.16.10.16', Fax: '20.16.10.17' }, - { ID: 'FOLKO', CompanyName: 'Folk och fä HB', ContactName: 'Maria Larsson', ContactTitle: 'Owner', Address: 'Åkergatan 24', City: 'Bräcke', Region: null, PostalCode: 'S-844 67', Country: 'Sweden', Phone: '0695-34 67 21', Fax: null }, - { ID: 'FRANK', CompanyName: 'Frankenversand', ContactName: 'Peter Franken', ContactTitle: 'Marketing Manager', Address: 'Berliner Platz 43', City: 'München', Region: null, PostalCode: '80805', Country: 'Germany', Phone: '089-0877310', Fax: '089-0877451' }, - { ID: 'FRANR', CompanyName: 'France restauration', ContactName: 'Carine Schmitt', ContactTitle: 'Marketing Manager', Address: '54, rue Royale', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.32.21.21', Fax: '40.32.21.20' }, - { ID: 'FRANS', CompanyName: 'Franchi S.p.A.', ContactName: 'Paolo Accorti', ContactTitle: 'Sales Representative', Address: 'Via Monte Bianco 34', City: 'Torino', Region: null, PostalCode: '10100', Country: 'Italy', Phone: '011-4988260', Fax: '011-4988261' } - ]; + this.data = SAMPLE_DATA; this.selectionMode = GridSelectionMode.none; } diff --git a/src/app/grid-column-resizing/grid-column-resizing.sample.ts b/src/app/grid-column-resizing/grid-column-resizing.sample.ts index 169b6b8d187..ad060344e22 100644 --- a/src/app/grid-column-resizing/grid-column-resizing.sample.ts +++ b/src/app/grid-column-resizing/grid-column-resizing.sample.ts @@ -1,5 +1,6 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { IgxButtonDirective, IgxColumnComponent, IgxGridComponent } from 'igniteui-angular'; +import { SAMPLE_DATA } from '../shared/sample-data'; @Component({ providers: [], @@ -32,35 +33,7 @@ export class GridColumnResizingSampleComponent implements OnInit { { field: 'Phone', width: 150, resizable: true }, { field: 'Fax', width: 150, resizable: true } ]; - this.data = [ - { ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative', Address: 'Obere Str. 57', City: 'Berlin', Region: null, PostalCode: '12209', Country: 'Germany', Phone: '030-0074321', Fax: '030-0076545' }, - { ID: 'ANATR', CompanyName: 'Ana Trujillo Emparedados y helados', ContactName: 'Ana Trujillo', ContactTitle: 'Owner', Address: 'Avda. de la Constitución 2222', City: 'México D.F.', Region: null, PostalCode: '05021', Country: 'Mexico', Phone: '(5) 555-4729', Fax: '(5) 555-3745' }, - { ID: 'ANTON', CompanyName: 'Antonio Moreno Taquería', ContactName: 'Antonio Moreno', ContactTitle: 'Owner', Address: 'Mataderos 2312', City: 'México D.F.', Region: null, PostalCode: '05023', Country: 'Mexico', Phone: '(5) 555-3932', Fax: null }, - { ID: 'AROUT', CompanyName: 'Around the Horn', ContactName: 'Thomas Hardy', ContactTitle: 'Sales Representative', Address: '120 Hanover Sq.', City: 'London', Region: null, PostalCode: 'WA1 1DP', Country: 'UK', Phone: '(171) 555-7788', Fax: '(171) 555-6750' }, - { ID: 'BERGS', CompanyName: 'Berglunds snabbköp', ContactName: 'Christina Berglund', ContactTitle: 'Order Administrator', Address: 'Berguvsvägen 8', City: 'Luleå', Region: null, PostalCode: 'S-958 22', Country: 'Sweden', Phone: '0921-12 34 65', Fax: '0921-12 34 67' }, - { ID: 'BLAUS', CompanyName: 'Blauer See Delikatessen', ContactName: 'Hanna Moos', ContactTitle: 'Sales Representative', Address: 'Forsterstr. 57', City: 'Mannheim', Region: null, PostalCode: '68306', Country: 'Germany', Phone: '0621-08460', Fax: '0621-08924' }, - { ID: 'BLONP', CompanyName: 'Blondesddsl père et fils', ContactName: 'Frédérique Citeaux', ContactTitle: 'Marketing Manager', Address: '24, place Kléber', City: 'Strasbourg', Region: null, PostalCode: '67000', Country: 'France', Phone: '88.60.15.31', Fax: '88.60.15.32' }, - { ID: 'BOLID', CompanyName: 'Bólido Comidas preparadas', ContactName: 'Martín Sommer', ContactTitle: 'Owner', Address: 'C/ Araquil, 67', City: 'Madrid', Region: null, PostalCode: '28023', Country: 'Spain', Phone: '(91) 555 22 82', Fax: '(91) 555 91 99' }, - { ID: 'BONAP', CompanyName: 'Bon app\'', ContactName: 'Laurence Lebihan', ContactTitle: 'Owner', Address: '12, rue des Bouchers', City: 'Marseille', Region: null, PostalCode: '13008', Country: 'France', Phone: '91.24.45.40', Fax: '91.24.45.41' }, - { ID: 'BOTTM', CompanyName: 'Bottom-Dollar Markets', ContactName: 'Elizabeth Lincoln', ContactTitle: 'Accounting Manager', Address: '23 Tsawassen Blvd.', City: 'Tsawassen', Region: 'BC', PostalCode: 'T2F 8M4', Country: 'Canada', Phone: '(604) 555-4729', Fax: '(604) 555-3745' }, - { ID: 'BSBEV', CompanyName: 'B\'s Beverages', ContactName: 'Victoria Ashworth', ContactTitle: 'Sales Representative', Address: 'Fauntleroy Circus', City: 'London', Region: null, PostalCode: 'EC2 5NT', Country: 'UK', Phone: '(171) 555-1212', Fax: null }, - { ID: 'CACTU', CompanyName: 'Cactus Comidas para llevar', ContactName: 'Patricio Simpson', ContactTitle: 'Sales Agent', Address: 'Cerrito 333', City: 'Buenos Aires', Region: null, PostalCode: '1010', Country: 'Argentina', Phone: '(1) 135-5555', Fax: '(1) 135-4892' }, - { ID: 'CENTC', CompanyName: 'Centro comercial Moctezuma', ContactName: 'Francisco Chang', ContactTitle: 'Marketing Manager', Address: 'Sierras de Granada 9993', City: 'México D.F.', Region: null, PostalCode: '05022', Country: 'Mexico', Phone: '(5) 555-3392', Fax: '(5) 555-7293' }, - { ID: 'CHOPS', CompanyName: 'Chop-suey Chinese', ContactName: 'Yang Wang', ContactTitle: 'Owner', Address: 'Hauptstr. 29', City: 'Bern', Region: null, PostalCode: '3012', Country: 'Switzerland', Phone: '0452-076545', Fax: null }, - { ID: 'COMMI', CompanyName: 'Comércio Mineiro', ContactName: 'Pedro Afonso', ContactTitle: 'Sales Associate', Address: 'Av. dos Lusíadas, 23', City: 'Sao Paulo', Region: 'SP', PostalCode: '05432-043', Country: 'Brazil', Phone: '(11) 555-7647', Fax: null }, - { ID: 'CONSH', CompanyName: 'Consolidated Holdings', ContactName: 'Elizabeth Brown', ContactTitle: 'Sales Representative', Address: 'Berkeley Gardens 12 Brewery', City: 'London', Region: null, PostalCode: 'WX1 6LT', Country: 'UK', Phone: '(171) 555-2282', Fax: '(171) 555-9199' }, - { ID: 'DRACD', CompanyName: 'Drachenblut Delikatessen', ContactName: 'Sven Ottlieb', ContactTitle: 'Order Administrator', Address: 'Walserweg 21', City: 'Aachen', Region: null, PostalCode: '52066', Country: 'Germany', Phone: '0241-039123', Fax: '0241-059428' }, - { ID: 'DUMON', CompanyName: 'Du monde entier', ContactName: 'Janine Labrune', ContactTitle: 'Owner', Address: '67, rue des Cinquante Otages', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.67.88.88', Fax: '40.67.89.89' }, - { ID: 'EASTC', CompanyName: 'Eastern Connection', ContactName: 'Ann Devon', ContactTitle: 'Sales Agent', Address: '35 King George', City: 'London', Region: null, PostalCode: 'WX3 6FW', Country: 'UK', Phone: '(171) 555-0297', Fax: '(171) 555-3373' }, - { ID: 'ERNSH', CompanyName: 'Ernst Handel', ContactName: 'Roland Mendel', ContactTitle: 'Sales Manager', Address: 'Kirchgasse 6', City: 'Graz', Region: null, PostalCode: '8010', Country: 'Austria', Phone: '7675-3425', Fax: '7675-3426' }, - { ID: 'FAMIA', CompanyName: 'Familia Arquibaldo', ContactName: 'Aria Cruz', ContactTitle: 'Marketing Assistant', Address: 'Rua Orós, 92', City: 'Sao Paulo', Region: 'SP', PostalCode: '05442-030', Country: 'Brazil', Phone: '(11) 555-9857', Fax: null }, - { ID: 'FISSA', CompanyName: 'FISSA Fabrica Inter. Salchichas S.A.', ContactName: 'Diego Roel', ContactTitle: 'Accounting Manager', Address: 'C/ Moralzarzal, 86', City: 'Madrid', Region: null, PostalCode: '28034', Country: 'Spain', Phone: '(91) 555 94 44', Fax: '(91) 555 55 93' }, - { ID: 'FOLIG', CompanyName: 'Folies gourmandes', ContactName: 'Martine Rancé', ContactTitle: 'Assistant Sales Agent', Address: '184, chaussée de Tournai', City: 'Lille', Region: null, PostalCode: '59000', Country: 'France', Phone: '20.16.10.16', Fax: '20.16.10.17' }, - { ID: 'FOLKO', CompanyName: 'Folk och fä HB', ContactName: 'Maria Larsson', ContactTitle: 'Owner', Address: 'Åkergatan 24', City: 'Bräcke', Region: null, PostalCode: 'S-844 67', Country: 'Sweden', Phone: '0695-34 67 21', Fax: null }, - { ID: 'FRANK', CompanyName: 'Frankenversand', ContactName: 'Peter Franken', ContactTitle: 'Marketing Manager', Address: 'Berliner Platz 43', City: 'München', Region: null, PostalCode: '80805', Country: 'Germany', Phone: '089-0877310', Fax: '089-0877451' }, - { ID: 'FRANR', CompanyName: 'France restauration', ContactName: 'Carine Schmitt', ContactTitle: 'Marketing Manager', Address: '54, rue Royale', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.32.21.21', Fax: '40.32.21.20' }, - { ID: 'FRANS', CompanyName: 'Franchi S.p.A.', ContactName: 'Paolo Accorti', ContactTitle: 'Sales Representative', Address: 'Via Monte Bianco 34', City: 'Torino', Region: null, PostalCode: '10100', Country: 'Italy', Phone: '011-4988260', Fax: '011-4988261' } - ]; + this.data = SAMPLE_DATA; } public toggleColumn(name: string) { diff --git a/src/app/grid-remote-paging/grid-remote-paging.sample.ts b/src/app/grid-remote-paging/grid-remote-paging.sample.ts index 8a2da80baa0..e0b82c52574 100644 --- a/src/app/grid-remote-paging/grid-remote-paging.sample.ts +++ b/src/app/grid-remote-paging/grid-remote-paging.sample.ts @@ -15,7 +15,7 @@ import { GridPagingMode, IgxButtonDirective, IgxCardComponent, IgxCardContentDir export class GridRemotePagingSampleComponent implements OnInit, AfterViewInit, OnDestroy { @ViewChild('grid1', { static: true }) public grid1: IgxGridComponent; - public mode: GridPagingMode = GridPagingMode.Remote; + public mode: GridPagingMode = 'remote'; public page = 0; public totalCount = 0; public pages = []; diff --git a/src/app/grid-row-api/grid-row-api.sample.ts b/src/app/grid-row-api/grid-row-api.sample.ts index 4d7b9828aaa..468a82af5b2 100644 --- a/src/app/grid-row-api/grid-row-api.sample.ts +++ b/src/app/grid-row-api/grid-row-api.sample.ts @@ -1,7 +1,7 @@ import { Component, OnInit, Renderer2, ViewChild } from '@angular/core'; import { FormsModule } from '@angular/forms'; -import { HIERARCHICAL_SAMPLE_DATA } from '../shared/sample-data'; +import { HIERARCHICAL_SAMPLE_DATA, SAMPLE_DATA } from '../shared/sample-data'; import { GridSummaryCalculationMode, GridSummaryPosition, IPinningConfig, IgxButtonDirective, IgxColumnComponent, IgxGridComponent, IgxGridDetailTemplateDirective, IgxGridToolbarActionsComponent, IgxGridToolbarComponent, IgxGridToolbarHidingComponent, IgxGridToolbarPinningComponent, IgxHierarchicalGridComponent, IgxIconComponent, IgxPaginatorComponent, IgxPaginatorDirective, IgxRowDragGhostDirective, IgxRowIslandComponent, IgxTreeGridComponent, RowPinningPosition, RowType } from 'igniteui-angular'; @Component({ @@ -93,35 +93,7 @@ export class GridRowAPISampleComponent implements OnInit { ]; this.treeGridHierData = HIERARCHICAL_SAMPLE_DATA.slice(0); - this.data = [ - { ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative', Address: 'Obere Str. 57', City: 'Berlin', Region: null, PostalCode: '12209', Country: 'Germany', Phone: '030-0074321', Fax: '030-0076545' }, - { ID: 'ANATR', CompanyName: 'Ana Trujillo Emparedados y helados', ContactName: 'Ana Trujillo', ContactTitle: 'Owner', Address: 'Avda. de la Constitución 2222', City: 'México D.F.', Region: null, PostalCode: '05021', Country: 'Mexico', Phone: '(5) 555-4729', Fax: '(5) 555-3745' }, - { ID: 'ANTON', CompanyName: 'Antonio Moreno Taquería', ContactName: 'Antonio Moreno', ContactTitle: 'Owner', Address: 'Mataderos 2312', City: 'México D.F.', Region: null, PostalCode: '05023', Country: 'Mexico', Phone: '(5) 555-3932', Fax: null }, - { ID: 'AROUT', CompanyName: 'Around the Horn', ContactName: 'Thomas Hardy', ContactTitle: 'Sales Representative', Address: '120 Hanover Sq.', City: 'London', Region: null, PostalCode: 'WA1 1DP', Country: 'UK', Phone: '(171) 555-7788', Fax: '(171) 555-6750' }, - { ID: 'BERGS', CompanyName: 'Berglunds snabbköp', ContactName: 'Christina Berglund', ContactTitle: 'Order Administrator', Address: 'Berguvsvägen 8', City: 'Luleå', Region: null, PostalCode: 'S-958 22', Country: 'Sweden', Phone: '0921-12 34 65', Fax: '0921-12 34 67' }, - { ID: 'BLAUS', CompanyName: 'Blauer See Delikatessen', ContactName: 'Hanna Moos', ContactTitle: 'Sales Representative', Address: 'Forsterstr. 57', City: 'Mannheim', Region: null, PostalCode: '68306', Country: 'Germany', Phone: '0621-08460', Fax: '0621-08924' }, - { ID: 'BLONP', CompanyName: 'Blondesddsl père et fils', ContactName: 'Frédérique Citeaux', ContactTitle: 'Marketing Manager', Address: '24, place Kléber', City: 'Strasbourg', Region: null, PostalCode: '67000', Country: 'France', Phone: '88.60.15.31', Fax: '88.60.15.32' }, - { ID: 'BOLID', CompanyName: 'Bólido Comidas preparadas', ContactName: 'Martín Sommer', ContactTitle: 'Owner', Address: 'C/ Araquil, 67', City: 'Madrid', Region: null, PostalCode: '28023', Country: 'Spain', Phone: '(91) 555 22 82', Fax: '(91) 555 91 99' }, - { ID: 'BONAP', CompanyName: 'Bon app\'', ContactName: 'Laurence Lebihan', ContactTitle: 'Owner', Address: '12, rue des Bouchers', City: 'Marseille', Region: null, PostalCode: '13008', Country: 'France', Phone: '91.24.45.40', Fax: '91.24.45.41' }, - { ID: 'BOTTM', CompanyName: 'Bottom-Dollar Markets', ContactName: 'Elizabeth Lincoln', ContactTitle: 'Accounting Manager', Address: '23 Tsawassen Blvd.', City: 'Tsawassen', Region: 'BC', PostalCode: 'T2F 8M4', Country: 'Canada', Phone: '(604) 555-4729', Fax: '(604) 555-3745' }, - { ID: 'BSBEV', CompanyName: 'B\'s Beverages', ContactName: 'Victoria Ashworth', ContactTitle: 'Sales Representative', Address: 'Fauntleroy Circus', City: 'London', Region: null, PostalCode: 'EC2 5NT', Country: 'UK', Phone: '(171) 555-1212', Fax: null }, - { ID: 'CACTU', CompanyName: 'Cactus Comidas para llevar', ContactName: 'Patricio Simpson', ContactTitle: 'Sales Agent', Address: 'Cerrito 333', City: 'Buenos Aires', Region: null, PostalCode: '1010', Country: 'Argentina', Phone: '(1) 135-5555', Fax: '(1) 135-4892' }, - { ID: 'CENTC', CompanyName: 'Centro comercial Moctezuma', ContactName: 'Francisco Chang', ContactTitle: 'Marketing Manager', Address: 'Sierras de Granada 9993', City: 'México D.F.', Region: null, PostalCode: '05022', Country: 'Mexico', Phone: '(5) 555-3392', Fax: '(5) 555-7293' }, - { ID: 'CHOPS', CompanyName: 'Chop-suey Chinese', ContactName: 'Yang Wang', ContactTitle: 'Owner', Address: 'Hauptstr. 29', City: 'Bern', Region: null, PostalCode: '3012', Country: 'Switzerland', Phone: '0452-076545', Fax: null }, - { ID: 'COMMI', CompanyName: 'Comércio Mineiro', ContactName: 'Pedro Afonso', ContactTitle: 'Sales Associate', Address: 'Av. dos Lusíadas, 23', City: 'Sao Paulo', Region: 'SP', PostalCode: '05432-043', Country: 'Brazil', Phone: '(11) 555-7647', Fax: null }, - { ID: 'CONSH', CompanyName: 'Consolidated Holdings', ContactName: 'Elizabeth Brown', ContactTitle: 'Sales Representative', Address: 'Berkeley Gardens 12 Brewery', City: 'London', Region: null, PostalCode: 'WX1 6LT', Country: 'UK', Phone: '(171) 555-2282', Fax: '(171) 555-9199' }, - { ID: 'DRACD', CompanyName: 'Drachenblut Delikatessen', ContactName: 'Sven Ottlieb', ContactTitle: 'Order Administrator', Address: 'Walserweg 21', City: 'Aachen', Region: null, PostalCode: '52066', Country: 'Germany', Phone: '0241-039123', Fax: '0241-059428' }, - { ID: 'DUMON', CompanyName: 'Du monde entier', ContactName: 'Janine Labrune', ContactTitle: 'Owner', Address: '67, rue des Cinquante Otages', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.67.88.88', Fax: '40.67.89.89' }, - { ID: 'EASTC', CompanyName: 'Eastern Connection', ContactName: 'Ann Devon', ContactTitle: 'Sales Agent', Address: '35 King George', City: 'London', Region: null, PostalCode: 'WX3 6FW', Country: 'UK', Phone: '(171) 555-0297', Fax: '(171) 555-3373' }, - { ID: 'ERNSH', CompanyName: 'Ernst Handel', ContactName: 'Roland Mendel', ContactTitle: 'Sales Manager', Address: 'Kirchgasse 6', City: 'Graz', Region: null, PostalCode: '8010', Country: 'Austria', Phone: '7675-3425', Fax: '7675-3426' }, - { ID: 'FAMIA', CompanyName: 'Familia Arquibaldo', ContactName: 'Aria Cruz', ContactTitle: 'Marketing Assistant', Address: 'Rua Orós, 92', City: 'Sao Paulo', Region: 'SP', PostalCode: '05442-030', Country: 'Brazil', Phone: '(11) 555-9857', Fax: null }, - { ID: 'FISSA', CompanyName: 'FISSA Fabrica Inter. Salchichas S.A.', ContactName: 'Diego Roel', ContactTitle: 'Accounting Manager', Address: 'C/ Moralzarzal, 86', City: 'Madrid', Region: null, PostalCode: '28034', Country: 'Spain', Phone: '(91) 555 94 44', Fax: '(91) 555 55 93' }, - { ID: 'FOLIG', CompanyName: 'Folies gourmandes', ContactName: 'Martine Rancé', ContactTitle: 'Assistant Sales Agent', Address: '184, chaussée de Tournai', City: 'Lille', Region: null, PostalCode: '59000', Country: 'France', Phone: '20.16.10.16', Fax: '20.16.10.17' }, - { ID: 'FOLKO', CompanyName: 'Folk och fä HB', ContactName: 'Maria Larsson', ContactTitle: 'Owner', Address: 'Åkergatan 24', City: 'Bräcke', Region: null, PostalCode: 'S-844 67', Country: 'Sweden', Phone: '0695-34 67 21', Fax: null }, - { ID: 'FRANK', CompanyName: 'Frankenversand', ContactName: 'Peter Franken', ContactTitle: 'Marketing Manager', Address: 'Berliner Platz 43', City: 'München', Region: null, PostalCode: '80805', Country: 'Germany', Phone: '089-0877310', Fax: '089-0877451' }, - { ID: 'FRANR', CompanyName: 'France restauration', ContactName: 'Carine Schmitt', ContactTitle: 'Marketing Manager', Address: '54, rue Royale', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.32.21.21', Fax: '40.32.21.20' }, - { ID: 'FRANS', CompanyName: 'Franchi S.p.A.', ContactName: 'Paolo Accorti', ContactTitle: 'Sales Representative', Address: 'Via Monte Bianco 34', City: 'Torino', Region: null, PostalCode: '10100', Country: 'Italy', Phone: '011-4988260', Fax: '011-4988261' } - ]; + this.data = SAMPLE_DATA; this.hierarchicalData = this.generateDataUneven(100, 3); // treegrid cols and data diff --git a/src/app/grid-row-pinning/grid-row-pinning.sample.ts b/src/app/grid-row-pinning/grid-row-pinning.sample.ts index 12928cb8ecd..bf67ad8bbab 100644 --- a/src/app/grid-row-pinning/grid-row-pinning.sample.ts +++ b/src/app/grid-row-pinning/grid-row-pinning.sample.ts @@ -19,6 +19,7 @@ import { } from 'igniteui-angular'; import { pinLeft, unpinLeft } from '@igniteui/material-icons-extended'; import { GridSearchBoxComponent } from '../grid-search-box/grid-search-box.component'; +import { SAMPLE_DATA } from '../shared/sample-data'; @Component({ selector: 'app-grid-row-pinning-sample', @@ -111,35 +112,7 @@ export class GridRowPinningSampleComponent implements OnInit, AfterViewInit { { field: 'hasChild', width: '200px' } ]; - this.data = [ - { ID: 'ALFKI', CompanyName: 'Alfreds Futterkiste', ContactName: 'Maria Anders', ContactTitle: 'Sales Representative', Address: 'Obere Str. 57', City: 'Berlin', Region: null, PostalCode: '12209', Country: 'Germany', Phone: '030-0074321', Fax: '030-0076545' }, - { ID: 'ANATR', CompanyName: 'Ana Trujillo Emparedados y helados', ContactName: 'Ana Trujillo', ContactTitle: 'Owner', Address: 'Avda. de la Constitución 2222', City: 'México D.F.', Region: null, PostalCode: '05021', Country: 'Mexico', Phone: '(5) 555-4729', Fax: '(5) 555-3745' }, - { ID: 'ANTON', CompanyName: 'Antonio Moreno Taquería', ContactName: 'Antonio Moreno', ContactTitle: 'Owner', Address: 'Mataderos 2312', City: 'México D.F.', Region: null, PostalCode: '05023', Country: 'Mexico', Phone: '(5) 555-3932', Fax: null }, - { ID: 'AROUT', CompanyName: 'Around the Horn', ContactName: 'Thomas Hardy', ContactTitle: 'Sales Representative', Address: '120 Hanover Sq.', City: 'London', Region: null, PostalCode: 'WA1 1DP', Country: 'UK', Phone: '(171) 555-7788', Fax: '(171) 555-6750' }, - { ID: 'BERGS', CompanyName: 'Berglunds snabbköp', ContactName: 'Christina Berglund', ContactTitle: 'Order Administrator', Address: 'Berguvsvägen 8', City: 'Luleå', Region: null, PostalCode: 'S-958 22', Country: 'Sweden', Phone: '0921-12 34 65', Fax: '0921-12 34 67' }, - { ID: 'BLAUS', CompanyName: 'Blauer See Delikatessen', ContactName: 'Hanna Moos', ContactTitle: 'Sales Representative', Address: 'Forsterstr. 57', City: 'Mannheim', Region: null, PostalCode: '68306', Country: 'Germany', Phone: '0621-08460', Fax: '0621-08924' }, - { ID: 'BLONP', CompanyName: 'Blondesddsl père et fils', ContactName: 'Frédérique Citeaux', ContactTitle: 'Marketing Manager', Address: '24, place Kléber', City: 'Strasbourg', Region: null, PostalCode: '67000', Country: 'France', Phone: '88.60.15.31', Fax: '88.60.15.32' }, - { ID: 'BOLID', CompanyName: 'Bólido Comidas preparadas', ContactName: 'Martín Sommer', ContactTitle: 'Owner', Address: 'C/ Araquil, 67', City: 'Madrid', Region: null, PostalCode: '28023', Country: 'Spain', Phone: '(91) 555 22 82', Fax: '(91) 555 91 99' }, - { ID: 'BONAP', CompanyName: 'Bon app\'', ContactName: 'Laurence Lebihan', ContactTitle: 'Owner', Address: '12, rue des Bouchers', City: 'Marseille', Region: null, PostalCode: '13008', Country: 'France', Phone: '91.24.45.40', Fax: '91.24.45.41' }, - { ID: 'BOTTM', CompanyName: 'Bottom-Dollar Markets', ContactName: 'Elizabeth Lincoln', ContactTitle: 'Accounting Manager', Address: '23 Tsawassen Blvd.', City: 'Tsawassen', Region: 'BC', PostalCode: 'T2F 8M4', Country: 'Canada', Phone: '(604) 555-4729', Fax: '(604) 555-3745' }, - { ID: 'BSBEV', CompanyName: 'B\'s Beverages', ContactName: 'Victoria Ashworth', ContactTitle: 'Sales Representative', Address: 'Fauntleroy Circus', City: 'London', Region: null, PostalCode: 'EC2 5NT', Country: 'UK', Phone: '(171) 555-1212', Fax: null }, - { ID: 'CACTU', CompanyName: 'Cactus Comidas para llevar', ContactName: 'Patricio Simpson', ContactTitle: 'Sales Agent', Address: 'Cerrito 333', City: 'Buenos Aires', Region: null, PostalCode: '1010', Country: 'Argentina', Phone: '(1) 135-5555', Fax: '(1) 135-4892' }, - { ID: 'CENTC', CompanyName: 'Centro comercial Moctezuma', ContactName: 'Francisco Chang', ContactTitle: 'Marketing Manager', Address: 'Sierras de Granada 9993', City: 'México D.F.', Region: null, PostalCode: '05022', Country: 'Mexico', Phone: '(5) 555-3392', Fax: '(5) 555-7293' }, - { ID: 'CHOPS', CompanyName: 'Chop-suey Chinese', ContactName: 'Yang Wang', ContactTitle: 'Owner', Address: 'Hauptstr. 29', City: 'Bern', Region: null, PostalCode: '3012', Country: 'Switzerland', Phone: '0452-076545', Fax: null }, - { ID: 'COMMI', CompanyName: 'Comércio Mineiro', ContactName: 'Pedro Afonso', ContactTitle: 'Sales Associate', Address: 'Av. dos Lusíadas, 23', City: 'Sao Paulo', Region: 'SP', PostalCode: '05432-043', Country: 'Brazil', Phone: '(11) 555-7647', Fax: null }, - { ID: 'CONSH', CompanyName: 'Consolidated Holdings', ContactName: 'Elizabeth Brown', ContactTitle: 'Sales Representative', Address: 'Berkeley Gardens 12 Brewery', City: 'London', Region: null, PostalCode: 'WX1 6LT', Country: 'UK', Phone: '(171) 555-2282', Fax: '(171) 555-9199' }, - { ID: 'DRACD', CompanyName: 'Drachenblut Delikatessen', ContactName: 'Sven Ottlieb', ContactTitle: 'Order Administrator', Address: 'Walserweg 21', City: 'Aachen', Region: null, PostalCode: '52066', Country: 'Germany', Phone: '0241-039123', Fax: '0241-059428' }, - { ID: 'DUMON', CompanyName: 'Du monde entier', ContactName: 'Janine Labrune', ContactTitle: 'Owner', Address: '67, rue des Cinquante Otages', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.67.88.88', Fax: '40.67.89.89' }, - { ID: 'EASTC', CompanyName: 'Eastern Connection', ContactName: 'Ann Devon', ContactTitle: 'Sales Agent', Address: '35 King George', City: 'London', Region: null, PostalCode: 'WX3 6FW', Country: 'UK', Phone: '(171) 555-0297', Fax: '(171) 555-3373' }, - { ID: 'ERNSH', CompanyName: 'Ernst Handel', ContactName: 'Roland Mendel', ContactTitle: 'Sales Manager', Address: 'Kirchgasse 6', City: 'Graz', Region: null, PostalCode: '8010', Country: 'Austria', Phone: '7675-3425', Fax: '7675-3426' }, - { ID: 'FAMIA', CompanyName: 'Familia Arquibaldo', ContactName: 'Aria Cruz', ContactTitle: 'Marketing Assistant', Address: 'Rua Orós, 92', City: 'Sao Paulo', Region: 'SP', PostalCode: '05442-030', Country: 'Brazil', Phone: '(11) 555-9857', Fax: null }, - { ID: 'FISSA', CompanyName: 'FISSA Fabrica Inter. Salchichas S.A.', ContactName: 'Diego Roel', ContactTitle: 'Accounting Manager', Address: 'C/ Moralzarzal, 86', City: 'Madrid', Region: null, PostalCode: '28034', Country: 'Spain', Phone: '(91) 555 94 44', Fax: '(91) 555 55 93' }, - { ID: 'FOLIG', CompanyName: 'Folies gourmandes', ContactName: 'Martine Rancé', ContactTitle: 'Assistant Sales Agent', Address: '184, chaussée de Tournai', City: 'Lille', Region: null, PostalCode: '59000', Country: 'France', Phone: '20.16.10.16', Fax: '20.16.10.17' }, - { ID: 'FOLKO', CompanyName: 'Folk och fä HB', ContactName: 'Maria Larsson', ContactTitle: 'Owner', Address: 'Åkergatan 24', City: 'Bräcke', Region: null, PostalCode: 'S-844 67', Country: 'Sweden', Phone: '0695-34 67 21', Fax: null }, - { ID: 'FRANK', CompanyName: 'Frankenversand', ContactName: 'Peter Franken', ContactTitle: 'Marketing Manager', Address: 'Berliner Platz 43', City: 'München', Region: null, PostalCode: '80805', Country: 'Germany', Phone: '089-0877310', Fax: '089-0877451' }, - { ID: 'FRANR', CompanyName: 'France restauration', ContactName: 'Carine Schmitt', ContactTitle: 'Marketing Manager', Address: '54, rue Royale', City: 'Nantes', Region: null, PostalCode: '44000', Country: 'France', Phone: '40.32.21.21', Fax: '40.32.21.20' }, - { ID: 'FRANS', CompanyName: 'Franchi S.p.A.', ContactName: 'Paolo Accorti', ContactTitle: 'Sales Representative', Address: 'Via Monte Bianco 34', City: 'Torino', Region: null, PostalCode: '10100', Country: 'Italy', Phone: '011-4988260', Fax: '011-4988261' } - ]; + this.data = SAMPLE_DATA; this.hierarchicalData = this.generateDataUneven(100, 3); // treegrid cols and data diff --git a/src/app/hierarchical-grid-advanced-filtering/data.ts b/src/app/hierarchical-grid-advanced-filtering/data.ts new file mode 100644 index 00000000000..9e002d38df9 --- /dev/null +++ b/src/app/hierarchical-grid-advanced-filtering/data.ts @@ -0,0 +1,1925 @@ + +/* eslint-disable id-blacklist */ +/* eslint-disable @typescript-eslint/naming-convention */ +export interface Song { + Number: number; + Title: string; + Released: Date; + Genre: string; + Album: string; +} +export interface Tour { + Tour: string; + StartedOn: string; + Location: string; + Headliner: string; + TouredBy: string; +} +export interface Album { + Album: string; + LaunchDate: Date; + BillboardReview: number; + USBillboard200: number; + Artist: string; + Songs?: Song[]; +} + +export interface Singer { + ID: number; + Artist: string; + // Photo?: string; + Debut: number; + GrammyNominations: number; + GrammyAwards: number; + HasGrammyAward: boolean; + Tours?: Tour[]; + Albums?: Album[]; +} + +// tslint:disable:object-literal-sort-keys +export const SINGERS: Singer[] = [ + { + ID: 0, + Artist: 'Naomí Yepes', + // Photo: 'assets/images/hgrid/naomi.jpg', + Debut: 2011, + GrammyNominations: 6, + GrammyAwards: 0, + HasGrammyAward: false, + Tours: [ + { + Tour: 'Faithful Tour', + StartedOn: 'Sep 12', + Location: 'Worldwide', + Headliner: 'NO', + TouredBy: 'Naomí Yepes' + }, + { + Tour: 'City Jam Sessions', + StartedOn: 'Aug 13', + Location: 'North America', + Headliner: 'YES', + TouredBy: 'Naomí Yepes' + }, + { + Tour: 'Christmas NYC 2013', + StartedOn: 'Dec 13', + Location: 'United States', + Headliner: 'NO', + TouredBy: 'Naomí Yepes' + }, + { + Tour: 'Christmas NYC 2014', + StartedOn: 'Dec 14', + Location: 'North America', + Headliner: 'NO', + TouredBy: 'Naomí Yepes' + }, + { + Tour: 'Watermelon Tour', + StartedOn: 'Feb 15', + Location: 'Worldwide', + Headliner: 'YES', + TouredBy: 'Naomí Yepes' + }, + { + Tour: 'Christmas NYC 2016', + StartedOn: 'Dec 16', + Location: 'United States', + Headliner: 'NO', + TouredBy: 'Naomí Yepes' + }, + { + Tour: 'The Dragon Tour', + StartedOn: 'Feb 17', + Location: 'Worldwide', + Headliner: 'NO', + TouredBy: 'Naomí Yepes' + }, + { + Tour: 'Organic Sessions', + StartedOn: 'Aug 18', + Location: 'United States, England', + Headliner: 'YES', + TouredBy: 'Naomí Yepes' + }, + { + Tour: 'Hope World Tour', + StartedOn: 'Mar 19', + Location: 'Worldwide', + Headliner: 'NO', + TouredBy: 'Naomí Yepes' + } + ], + Albums: [ + { + Album: 'Initiation', + LaunchDate: new Date('September 3, 2013'), + BillboardReview: 86, + USBillboard200: 1, + Artist: 'Naomí Yepes', + Songs: [{ + Number: 1, + Title: 'Ambitious', + Released: new Date('28 Apr 2015'), + Genre: 'Dance-pop R&B', + Album: 'Initiation' + }, + { + Number: 2, + Title: 'My heart will go on', + Released: new Date('24 May 2015'), + Genre: 'Dance-pop R&B', + Album: 'Initiation' + }, + { + Number: 3, + Title: 'Sing to me', + Released: new Date('28 May 2015'), + Genre: 'Dance-pop R&B', + Album: 'Initiation' + }, + { + Number: 4, + Title: 'Want to dance with somebody', + Released: new Date('03 Jun 2015'), + Genre: 'Dance-pop R&B', + Album: 'Initiation' + }] + }, + { + Album: 'Dream Driven', + LaunchDate: new Date('August 25, 2014'), + BillboardReview: 81, + USBillboard200: 1, + Artist: 'Naomí Yepes', + Songs: [{ + Number: 1, + Title: 'Intro', + Released: null, + Genre: '*', + Album: 'Dream Driven' + }, + { + Number: 2, + Title: 'Ferocious', + Released: new Date('28 Apr 2014'), + Genre: 'Dance-pop R&B', + Album: 'Dream Driven' + }, + { + Number: 3, + Title: 'Going crazy', + Released: new Date('10 Feb 2015'), + Genre: 'Dance-pop EDM', + Album: 'Dream Driven' + }, + { + Number: 4, + Title: 'Future past', + Released: null, + Genre: '*', + Album: 'Dream Driven' + }, + { + Number: 5, + Title: 'Roaming like them', + Released: new Date('2 Jul 2014'), + Genre: 'Electro house Electropop', + Album: 'Dream Driven' + }, + { + Number: 6, + Title: 'Last Wishes', + Released: new Date('12 Aug 2014'), + Genre: 'R&B', + Album: 'Dream Driven' + }, + { + Number: 7, + Title: 'Stay where you are', + Released: null, + Genre: '*', + Album: 'Dream Driven' + }, + { + Number: 8, + Title: 'Imaginarium', + Released: null, + Genre: '*', + Album: 'Dream Driven' + }, + { + Number: 9, + Title: 'Tell me', + Released: new Date('30 Sep 2014'), + Genre: 'Synth-pop R&B', + Album: 'Dream Driven' + }, + { + Number: 10, + Title: 'Shredded into pieces', + Released: null, + Genre: '*', + Album: 'Dream Driven' + }, + { + Number: 11, + Title: 'Capture this moment', + Released: null, + Genre: '*', + Album: 'Dream Driven' + }, + { + Number: 12, + Title: 'Dream Driven', + Released: null, + Genre: '*', + Album: 'Dream Driven' + }] + }, + { + Album: 'The dragon journey', + LaunchDate: new Date('May 20, 2016'), + BillboardReview: 60, + USBillboard200: 2, + Artist: 'Naomí Yepes', + Songs: [{ + Number: 1, + Title: 'My dream', + Released: new Date('13 Jan 2017'), + Genre: 'Dance-pop EDM', + Album: 'The dragon journey' + }, + { + Number: 2, + Title: 'My passion', + Released: new Date('23 Sep 2017'), + Genre: 'Crunk reggaeton', + Album: 'The dragon journey' + }, + { + Number: 3, + Title: 'What is love', + Released: new Date('28 Nov 2018'), + Genre: 'Dance-pop R&B', + Album: 'The dragon journey' + }, + { + Number: 4, + Title: 'Negative', + Released: new Date('01 Dec 2018'), + Genre: 'Dance-pop EDM', + Album: 'The dragon journey' + }] + }, + { + Album: 'Organic me', + LaunchDate: new Date('August 17, 2018'), + BillboardReview: 82, + USBillboard200: 1, + Artist: 'Naomí Yepes', + Songs: [{ + Number: 1, + Title: 'I Love', + Released: new Date('11 May 2019'), + Genre: 'Crunk reggaeton', + Album: 'Organic me' + }, + { + Number: 2, + Title: 'Early Morning Compass', + Released: new Date('15 Jan 2020'), + Genre: 'mystical parody-bap ', + Album: 'Organic me' + }, + { + Number: 3, + Title: 'Key Fields Forever', + Released: new Date('2 Jan 2020'), + Genre: 'Dance-pop EDM', + Album: 'Organic me' + }, + { + Number: 4, + Title: 'Stand by Your Goblins', + Released: new Date('20 Nov 2019'), + Genre: '*', + Album: 'Organic me' + }, + { + Number: 5, + Title: 'Mad to Walk', + Released: new Date('12 May 2019'), + Genre: 'Electro house Electropop', + Album: 'Organic me' + }, + { + Number: 6, + Title: 'Alice\'s Waiting', + Released: new Date('28 Jan 2020'), + Genre: 'R&B', + Album: 'Organic me' + }, + { + Number: 7, + Title: 'We Shall Kiss', + Released: new Date('30 Oct 2019'), + Genre: '*', + Album: 'Organic me' + }, + { + Number: 8, + Title: 'Behind Single Ants', + Released: new Date('2 Oct 2019'), + Genre: '*', + Album: 'Organic me' + }, + { + Number: 9, + Title: 'Soap Autopsy', + Released: new Date('8 Aug 2019'), + Genre: 'Synth-pop R&B', + Album: 'Organic me' + }, + { + Number: 10, + Title: 'Have You Met Rich?', + Released: new Date('1 Jul 2019'), + Genre: 'ethno-tunes', + Album: 'Organic me' + }, + { + Number: 11, + Title: 'Livin\' on a Banana', + Released: new Date('22 Nov 2019'), + Genre: 'Crunk reggaeton', + Album: 'Organic me' + }] + }, + { + Album: 'Curiosity', + LaunchDate: new Date('December 7, 2019'), + BillboardReview: 75, + USBillboard200: 12, + Artist: 'Naomí Yepes', + Songs: [{ + Number: 1, + Title: 'Goals', + Released: new Date('07 Dec 2019'), + Genre: '*', + Album: 'Curiosity' + }, + { + Number: 2, + Title: 'Explorer', + Released: new Date('08 Dec 2019'), + Genre: 'Crunk reggaeton', + Album: 'Curiosity' + }, + { + Number: 3, + Title: 'I need to know', + Released: new Date('09 Dec 2019'), + Genre: 'Dance-pop R&B', + Album: 'Curiosity' + }, + { + Number: 4, + Title: 'Finding my purpose', + Released: new Date('10 Dec 2019'), + Genre: 'Heavy metal', + Album: 'Curiosity' + }, + { + Number: 5, + Title: 'Faster than the speed of love', + Released: new Date('21 Dec 2019'), + Genre: 'Dance-pop EDM', + Album: 'Curiosity' + }, + { + Number: 6, + Title: 'I like it', + Released: new Date('01 Jan 2020'), + Genre: 'Dance-pop EDM', + Album: 'Curiosity' + }] + } + ] + }, + { + ID: 1, + Artist: 'Babila Ebwélé', + // Photo: 'assets/images/hgrid/babila.jpg', + Debut: 2009, + GrammyNominations: 0, + GrammyAwards: 11, + HasGrammyAward: true, + Tours: [ + { + Tour: 'The last straw', + StartedOn: 'May 09', + Location: 'Europe, Asia', + Headliner: 'NO', + TouredBy: 'Babila Ebwélé' + }, + { + Tour: 'No foundations', + StartedOn: 'Jun 04', + Location: 'United States, Europe', + Headliner: 'YES', + TouredBy: 'Babila Ebwélé' + }, + { + Tour: 'Crazy eyes', + StartedOn: 'Jun 08', + Location: 'North America', + Headliner: 'NO', + TouredBy: 'Babila Ebwélé' + }, + { + Tour: 'Zero gravity', + StartedOn: 'Apr 19', + Location: 'United States', + Headliner: 'NO', + TouredBy: 'Babila Ebwélé' + }, + { + Tour: 'Battle with myself', + StartedOn: 'Mar 08', + Location: 'North America', + Headliner: 'YES', + TouredBy: 'Babila Ebwélé' + }], + Albums: [ + { + Album: 'Pushing up daisies', + LaunchDate: new Date('May 31, 2000'), + BillboardReview: 86, + USBillboard200: 42, + Artist: 'Babila Ebwélé', + Songs: [{ + Number: 1, + Title: 'Wood Shavings Forever', + Released: new Date('9 Jun 2019'), + Genre: '*', + Album: 'Pushing up daisies' + }, + { + Number: 2, + Title: 'Early Morning Drive', + Released: new Date('20 May 2019'), + Genre: '*', + Album: 'Pushing up daisies' + }, + { + Number: 3, + Title: 'Don\'t Natter', + Released: new Date('10 Jun 2019'), + Genre: 'adult calypso-industrial', + Album: 'Pushing up daisies' + }, + { + Number: 4, + Title: 'Stairway to Balloons', + Released: new Date('18 Jun 2019'), + Genre: 'calypso and mariachi', + Album: 'Pushing up daisies' + }, + { + Number: 5, + Title: 'The Number of your Apple', + Released: new Date('29 Oct 2019'), + Genre: '*', + Album: 'Pushing up daisies' + }, + { + Number: 6, + Title: 'Your Delightful Heart', + Released: new Date('24 Feb 2019'), + Genre: '*', + Album: 'Pushing up daisies' + }, + { + Number: 7, + Title: 'Nice Weather For Balloons', + Released: new Date('1 Aug 2019'), + Genre: 'rap-hop', + Album: 'Pushing up daisies' + }, + { + Number: 8, + Title: 'The Girl From Cornwall', + Released: new Date('4 May 2019'), + Genre: 'enigmatic rock-and-roll', + Album: 'Pushing up daisies' + }, + { + Number: 9, + Title: 'Here Without Jack', + Released: new Date('24 Oct 2019'), + Genre: '*', + Album: 'Pushing up daisies' + }, + { + Number: 10, + Title: 'Born Rancid', + Released: new Date('19 Mar 2019'), + Genre: '*', + Album: 'Pushing up daisies' + }] + }, + { + Album: 'Death\'s dead', + LaunchDate: new Date('June 8, 2016'), + BillboardReview: 85, + USBillboard200: 95, + Artist: 'Babila Ebwélé', + Songs: [{ + Number: 1, + Title: 'Men Sound Better With You', + Released: new Date('20 Oct 2016'), + Genre: 'rap-hop', + Album: 'Death\'s dead' + }, + { + Number: 2, + Title: 'Ghost in My Rod', + Released: new Date('5 Oct 2016'), + Genre: 'enigmatic rock-and-roll', + Album: 'Death\'s dead' + }, + { + Number: 3, + Title: 'Bed of Men', + Released: new Date('14 Nov 2016'), + Genre: 'whimsical comedy-grass ', + Album: 'Death\'s dead' + }, + { + Number: 4, + Title: 'Don\'t Push', + Released: new Date('2 Jan 2017'), + Genre: 'unblack electronic-trip-hop', + Album: 'Death\'s dead' + }, + { + Number: 5, + Title: 'Nice Weather For Men', + Released: new Date('18 Dec 2017'), + Genre: '*', + Album: 'Death\'s dead' + }, + { + Number: 6, + Title: 'Rancid Rhapsody', + Released: new Date('10 Mar 2017'), + Genre: '*', + Album: 'Death\'s dead' + }, + { + Number: 7, + Title: 'Push, Push, Push!', + Released: new Date('21 Feb 2017'), + Genre: '*', + Album: 'Death\'s dead' + }, + { + Number: 8, + Title: 'My Name is Sarah', + Released: new Date('15 Nov 2017'), + Genre: '*', + Album: 'Death\'s dead' + }, + { + Number: 9, + Title: 'The Girl From My Hotel', + Released: new Date('6 Nov 2017'), + Genre: '*', + Album: 'Death\'s dead' + }, + { + Number: 10, + Title: 'Free Box', + Released: new Date('18 Apr 2017'), + Genre: 'splitter-funk', + Album: 'Death\'s dead' + }, + { + Number: 11, + Title: 'Hotel Cardiff', + Released: new Date('30 Dec 2017'), + Genre: 'guilty pleasure ebm', + Album: 'Death\'s dead' + }] + }] + }, + { + ID: 2, + Artist: 'Ahmad Nazeri', + // Photo: 'assets/images/hgrid/ahmad.jpg', + Debut: 2004, + GrammyNominations: 3, + GrammyAwards: 1, + HasGrammyAward: true, + Tours: [], + Albums: [ + { + Album: 'Emergency', + LaunchDate: new Date('March 6, 2004'), + BillboardReview: 98, + USBillboard200: 69, + Artist: 'Ahmad Nazeri', + Songs: [{ + Number: 1, + Title: 'I am machine', + Released: new Date('20 Oct 2004'), + Genre: 'Heavy metal', + Album: 'Emergency' + }, + { + Number: 2, + Title: 'I wish I knew', + Released: new Date('21 Oct 2004'), + Genre: 'rap-hop', + Album: 'Emergency' + }, + { + Number: 3, + Title: 'How I feel', + Released: new Date('22 Oct 2004'), + Genre: 'Heavy metal', + Album: 'Emergency' + }, + { + Number: 4, + Title: 'I am machine', + Released: new Date('30 Oct 2004'), + Genre: 'Heavy metal', + Album: 'Emergency' + }, + { + Number: 5, + Title: 'Monsters under my bed', + Released: new Date('01 Nov 2004'), + Genre: 'rap-hop', + Album: 'Emergency' + }, + { + Number: 6, + Title: 'I know what you want', + Released: new Date('20 Nov 2004'), + Genre: 'rap-hop', + Album: 'Emergency' + }, + { + Number: 7, + Title: 'Lies', + Released: new Date('21 Nov 2004'), + Genre: 'Heavy metal', + Album: 'Emergency' + }, + { + Number: 8, + Title: 'I did it for you', + Released: new Date('22 Nov 2004'), + Genre: 'rap-hop', + Album: 'Emergency' + }] + }, + { + Album: 'Bursting bubbles', + LaunchDate: new Date('April 17, 2006'), + BillboardReview: 69, + USBillboard200: 39, + Artist: 'Ahmad Nazeri', + Songs: [{ + Number: 1, + Title: 'Ghosts', + Released: new Date('20 Apr 2006'), + Genre: 'Hip-hop', + Album: 'Bursting bubbles' + }, + { + Number: 2, + Title: 'What goes around comes around', + Released: new Date('20 Apr 2006'), + Genre: 'Heavy metal', + Album: 'Bursting bubbles' + }, + { + Number: 3, + Title: 'I want nothing', + Released: new Date('21 Apr 2006'), + Genre: 'Heavy metal', + Album: 'Bursting bubbles' + }, + { + Number: 4, + Title: 'Me and you', + Released: new Date('22 Apr 2006'), + Genre: 'Rock', + Album: 'Bursting bubbles' + }] + } + ] + }, + { + ID: 3, + Artist: 'Kimmy McIlmorie', + // Photo: 'assets/images/hgrid/kimmy.jpg', + Debut: 2007, + GrammyNominations: 21, + GrammyAwards: 3, + HasGrammyAward: true, + Albums: [ + { + Album: 'Here we go again', + LaunchDate: new Date('November 18, 2017'), + BillboardReview: 68, + USBillboard200: 1, + Artist: 'Kimmy McIlmorie', + Songs: [{ + Number: 1, + Title: 'Same old love', + Released: new Date('20 Nov 2017'), + Genre: 'Hip-hop', + Album: 'Here we go again' + }, + { + Number: 2, + Title: 'Sick of it', + Released: new Date('20 Nov 2017'), + Genre: 'Hip-hop', + Album: 'Here we go again' + }, + { + Number: 3, + Title: 'No one', + Released: new Date('21 Nov 2017'), + Genre: 'Metal', + Album: 'Here we go again' + }, + { + Number: 4, + Title: 'Circles', + Released: new Date('22 Nov 2017'), + Genre: 'Heavy metal', + Album: 'Here we go again' + }, + { + Number: 5, + Title: 'Coming for you', + Released: new Date('30 Nov 2017'), + Genre: 'Hip-hop', + Album: 'Here we go again' + }] + } + ] + }, + { + ID: 4, + Artist: 'Mar Rueda', + // Photo: 'assets/images/hgrid/mar.jpg', + Debut: 1996, + GrammyNominations: 14, + GrammyAwards: 2, + HasGrammyAward: true, + Albums: [ + { + Album: 'Trouble', + LaunchDate: new Date('November 18, 2017'), + BillboardReview: 65, + USBillboard200: 2, + Artist: 'Mar Rueda', + Songs: [{ + Number: 1, + Title: 'You knew I was trouble', + Released: new Date('20 Nov 2017'), + Genre: 'Pop', + Album: 'Trouble' + }, + { + Number: 2, + Title: 'Cannot live without you', + Released: new Date('20 Nov 2017'), + Genre: 'Pop', + Album: 'Trouble' + }, + { + Number: 3, + Title: 'Lost you', + Released: new Date('21 Nov 2017'), + Genre: 'Metal', + Album: 'Trouble' + }, + { + Number: 4, + Title: 'Happiness starts with you', + Released: new Date('22 Nov 2017'), + Genre: '*', + Album: 'Trouble' + }, + { + Number: 5, + Title: 'I saw it coming', + Released: new Date('30 Dec 2017'), + Genre: 'Hip-hop', + Album: 'Trouble' + }] + } + ] + }, + { + ID: 5, + Artist: 'Izabella Tabakova', + // Photo: 'assets/images/hgrid/izabella.jpg', + Debut: 2017, + GrammyNominations: 7, + GrammyAwards: 11, + HasGrammyAward: true, + Tours: [ + { + Tour: 'Final breath', + StartedOn: 'Jun 13', + Location: 'Europe', + Headliner: 'YES', + TouredBy: 'Izabella Tabakova' + }, + { + Tour: 'Once bitten', + StartedOn: 'Dec 18', + Location: 'Australia, United States', + Headliner: 'NO', + TouredBy: 'Izabella Tabakova' + }, + { + Tour: 'Code word', + StartedOn: 'Sep 19', + Location: 'United States, Europe', + Headliner: 'NO', + TouredBy: 'Izabella Tabakova' + }, + { + Tour: 'Final draft', + StartedOn: 'Sep 17', + Location: 'United States, Europe', + Headliner: 'YES', + TouredBy: 'Izabella Tabakova' + } + ], + Albums: [ + { + Album: 'Once bitten', + LaunchDate: new Date('July 16, 2007'), + BillboardReview: 79, + USBillboard200: 53, + Artist: 'Izabella Tabakova', + Songs: [{ + Number: 1, + Title: 'Whole Lotta Super Cats', + Released: new Date('21 May 2019'), + Genre: '*', + Album: 'Once bitten' + }, + { + Number: 2, + Title: 'Enter Becky', + Released: new Date('16 Jan 2020'), + Genre: '*', + Album: 'Once bitten' + }, + { + Number: 3, + Title: 'Your Cheatin\' Flamingo', + Released: new Date('14 Jan 2020'), + Genre: '*', + Album: 'Once bitten' + }, + { + Number: 4, + Title: 'Mad to Kiss', + Released: new Date('6 Nov 2019'), + Genre: 'Synth-pop R&B', + Album: 'Once bitten' + }, + { + Number: 5, + Title: 'Hotel Prague', + Released: new Date('20 Oct 2019'), + Genre: 'ethno-tunes', + Album: 'Once bitten' + }, + { + Number: 6, + Title: 'Jail on My Mind', + Released: new Date('31 May 2019'), + Genre: 'Crunk reggaeton', + Album: 'Once bitten' + }, + { + Number: 7, + Title: 'Amazing Blues', + Released: new Date('29 May 2019'), + Genre: 'mystical parody-bap ', + Album: 'Once bitten' + }, + { + Number: 8, + Title: 'Goody Two Iron Filings', + Released: new Date('4 Jul 2019'), + Genre: 'Electro house Electropop', + Album: 'Once bitten' + }, + { + Number: 9, + Title: 'I Love in Your Arms', + Released: new Date('7 Jun 2019'), + Genre: 'R&B', + Album: 'Once bitten' + }, + { + Number: 10, + Title: 'Truly Madly Amazing', + Released: new Date('12 Sep 2019'), + Genre: 'ethno-tunes', + Album: 'Once bitten' + } + ] + }, + { + Album: 'Your graciousness', + LaunchDate: new Date('November 17, 2004'), + BillboardReview: 69, + USBillboard200: 30, + Artist: 'Izabella Tabakova', + Songs: [ + { + Number: 1, + Title: 'We Shall Tickle', + Released: new Date('31 Aug 2019'), + Genre: 'old emo-garage ', + Album: 'Your graciousness' + }, + { + Number: 2, + Title: 'Snail Boogie', + Released: new Date('14 Jun 2019'), + Genre: '*', + Album: 'Your graciousness' + }, + { + Number: 3, + Title: 'Amazing Liz', + Released: new Date('15 Oct 2019'), + Genre: '*', + Album: 'Your graciousness' + }, + { + Number: 4, + Title: 'When Sexy Aardvarks Cry', + Released: new Date('1 Oct 2019'), + Genre: 'whimsical comedy-grass ', + Album: 'Your graciousness' + }, + { + Number: 5, + Title: 'Stand By Dave', + Released: new Date('18 Aug 2019'), + Genre: 'unblack electronic-trip-hop', + Album: 'Your graciousness' + }, + { + Number: 6, + Title: 'The Golf Course is Your Land', + Released: new Date('2 Apr 2019'), + Genre: '*', + Album: 'Your graciousness' + }, + { + Number: 7, + Title: 'Where Have All the Men Gone?', + Released: new Date('29 Apr 2019'), + Genre: '*', + Album: 'Your graciousness' + }, + { + Number: 8, + Title: 'Rhythm of the Leg', + Released: new Date('5 Aug 2019'), + Genre: 'ethno-tunes', + Album: 'Your graciousness' + }, + { + Number: 9, + Title: 'Baby, I Need Your Hats', + Released: new Date('5 Dec 2019'), + Genre: 'neuro-tunes', + Album: 'Your graciousness' + }, + { + Number: 10, + Title: 'Stand by Your Cat', + Released: new Date('25 Jul 2019'), + Genre: '*', + Album: 'Your graciousness' + }] + }, + { + Album: 'Dark matters', + LaunchDate: new Date('November 3, 2002'), + BillboardReview: 79, + USBillboard200: 85, + Artist: 'Izabella Tabakova', + Songs: [{ + Number: 1, + Title: 'The Sun', + Released: new Date('31 Oct 2002'), + Genre: 'old emo-garage ', + Album: 'Dark matters' + }, + { + Number: 2, + Title: 'I will survive', + Released: new Date('03 Nov 2002'), + Genre: 'old emo-garage ', + Album: 'Dark matters' + }, + { + Number: 3, + Title: 'Try', + Released: new Date('04 Nov 2002'), + Genre: 'old emo-garage ', + Album: 'Dark matters' + }, + { + Number: 4, + Title: 'Miracle', + Released: new Date('05 Nov 2002'), + Genre: 'old emo-garage ', + Album: 'Dark matters' + }] + } + ] + }, + { + ID: 6, + Artist: 'Nguyễn Diệp Chi', + // Photo: 'assets/images/hgrid/nguyen.jpg', + Debut: 1992, + GrammyNominations: 4, + GrammyAwards: 2, + HasGrammyAward: true, + Albums: [ + { + Album: 'Library of liberty', + LaunchDate: new Date('December 22, 2003'), + BillboardReview: 93, + USBillboard200: 5, + Artist: 'Nguyễn Diệp Chi', + Songs: [{ + Number: 1, + Title: 'Book of love', + Released: new Date('31 Dec 2003'), + Genre: 'Hip-hop', + Album: 'Library of liberty' + }, + { + Number: 2, + Title: 'Commitment', + Released: new Date('01 Jan 2004'), + Genre: 'Hip-hop', + Album: 'Library of liberty' + }, + { + Number: 3, + Title: 'Satisfaction', + Released: new Date('01 Jan 2004'), + Genre: 'Hip-hop', + Album: 'Library of liberty' + }, + { + Number: 4, + Title: 'Obsession', + Released: new Date('01 Jan 2004'), + Genre: 'Hip-hop', + Album: 'Library of liberty' + }, + { + Number: 5, + Title: 'Oblivion', + Released: new Date('02 Jan 2004'), + Genre: 'Hip-hop', + Album: 'Library of liberty' + }, + { + Number: 6, + Title: 'Energy', + Released: new Date('03 Jan 2004'), + Genre: 'Hip-hop', + Album: 'Library of liberty' + }] + } + ] + }, + { + ID: 7, + Artist: 'Eva Lee', + // Photo: 'assets/images/hgrid/eva.jpg', + Debut: 2008, + GrammyNominations: 2, + GrammyAwards: 0, + HasGrammyAward: false, + Albums: [ + { + Album: 'Just a tease', + LaunchDate: new Date('May 3, 2001'), + BillboardReview: 91, + USBillboard200: 29, + Artist: 'Eva Lee', + Songs: [{ + Number: 1, + Title: 'We shall see', + Released: new Date('03 May 2001'), + Genre: 'rap-hop', + Album: 'Just a tease' + }, + { + Number: 2, + Title: 'Hopeless', + Released: new Date('04 May 2001'), + Genre: 'rap-hop', + Album: 'Just a tease' + }, + { + Number: 3, + Title: 'Ignorant', + Released: new Date('04 May 2001'), + Genre: 'rap-hop', + Album: 'Just a tease' + }, + { + Number: 4, + Title: 'Dance', + Released: new Date('05 May 2019'), + Genre: 'Metal', + Album: 'Just a tease' + }, + { + Number: 5, + Title: 'Fire', + Released: new Date('06 May 2019'), + Genre: 'Metal', + Album: 'Just a tease' + }] + } + ] + }, + { + ID: 8, + Artist: 'Siri Jakobsson', + // Photo: 'assets/images/hgrid/siri.jpg', + Debut: 1990, + GrammyNominations: 2, + GrammyAwards: 8, + HasGrammyAward: true, + Tours: [ + { + Tour: 'Basket case', + StartedOn: 'Jan 07', + Location: 'Europe, Asia', + Headliner: 'NO', + TouredBy: 'Siri Jakobsson' + }, + { + Tour: 'The bigger fish', + StartedOn: 'Dec 07', + Location: 'United States, Europe', + Headliner: 'YES', + TouredBy: 'Siri Jakobsson' + }, + { + Tour: 'Missed the boat', + StartedOn: 'Jun 09', + Location: 'Europe, Asia', + Headliner: 'NO', + TouredBy: 'Siri Jakobsson' + }, + { + Tour: 'Equivalent exchange', + StartedOn: 'Feb 06', + Location: 'United States, Europe', + Headliner: 'YES', + TouredBy: 'Siri Jakobsson' + }, + { + Tour: 'Damage control', + StartedOn: 'Oct 11', + Location: 'Australia, United States', + Headliner: 'NO', + TouredBy: 'Siri Jakobsson' + } + ], + Albums: [ + { + Album: 'Under the bus', + LaunchDate: new Date('May 14, 2000'), + BillboardReview: 67, + USBillboard200: 67, + Artist: 'Siri Jakobsson', + Songs: [ + { + Number: 1, + Title: 'Jack Broke My Heart At Tesco\'s', + Released: new Date('19 Jan 2020'), + Genre: '*', + Album: 'Under the bus' + }, + { + Number: 2, + Title: 'Cat Deep, Hats High', + Released: new Date('5 Dec 2019'), + Genre: '*', + Album: 'Under the bus' + }, + { + Number: 3, + Title: 'In Snail We Trust', + Released: new Date('31 May 2019'), + Genre: 'hardcore opera', + Album: 'Under the bus' + }, + { + Number: 4, + Title: 'Liz\'s Waiting', + Released: new Date('22 Jul 2019'), + Genre: 'emotional C-jam ', + Album: 'Under the bus' + }, + { + Number: 5, + Title: 'Lifeless Blues', + Released: new Date('14 Jun 2019'), + Genre: '*', + Album: 'Under the bus' + }, + { + Number: 6, + Title: 'I Spin', + Released: new Date('26 Mar 2019'), + Genre: '*', + Album: 'Under the bus' + }, + { + Number: 7, + Title: 'Ring of Rock', + Released: new Date('12 Dec 2019'), + Genre: '*', + Album: 'Under the bus' + }, + { + Number: 8, + Title: 'Livin\' on a Rock', + Released: new Date('17 Apr 2019'), + Genre: '*', + Album: 'Under the bus' + }, + { + Number: 9, + Title: 'Your Lifeless Heart', + Released: new Date('15 Sep 2019'), + Genre: 'adult calypso-industrial', + Album: 'Under the bus' + }, + { + Number: 10, + Title: 'The High Street on My Mind', + Released: new Date('11 Nov 2019'), + Genre: 'calypso and mariachi', + Album: 'Under the bus' + }, + { + Number: 11, + Title: 'Behind Ugly Curtains', + Released: new Date('8 May 2019'), + Genre: '*', + Album: 'Under the bus' + }, + { + Number: 12, + Title: 'Where Have All the Curtains Gone?', + Released: new Date('28 Jun 2019'), + Genre: '*', + Album: 'Under the bus' + }, + { + Number: 13, + Title: 'Ghost in My Apple', + Released: new Date('14 Dec 2019'), + Genre: '*', + Album: 'Under the bus' + }, + { + Number: 14, + Title: 'I Chatter', + Released: new Date('30 Nov 2019'), + Genre: '*', + Album: 'Under the bus' + } + ] + } + ] + }, + { + ID: 9, + Artist: 'Pablo Cambeiro', + // Photo: 'assets/images/hgrid/pablo.jpg', + Debut: 2011, + GrammyNominations: 5, + GrammyAwards: 0, + HasGrammyAward: false, + Tours: [ + { + Tour: 'Beads', + StartedOn: 'May 11', + Location: 'Worldwide', + Headliner: 'NO', + TouredBy: 'Pablo Cambeiro' + }, + { + Tour: 'Concept art', + StartedOn: 'Dec 18', + Location: 'United States', + Headliner: 'YES', + TouredBy: 'Pablo Cambeiro' + }, + { + Tour: 'Glass shoe', + StartedOn: 'Jan 20', + Location: 'Worldwide', + Headliner: 'YES', + TouredBy: 'Pablo Cambeiro' + }, + { + Tour: 'Pushing buttons', + StartedOn: 'Feb 15', + Location: 'Europe, Asia', + Headliner: 'NO', + TouredBy: 'Pablo Cambeiro' + }, + { + Tour: 'Dark matters', + StartedOn: 'Jan 04', + Location: 'Australia, United States', + Headliner: 'YES', + TouredBy: 'Pablo Cambeiro' + }, + { + Tour: 'Greener grass', + StartedOn: 'Sep 09', + Location: 'United States, Europe', + Headliner: 'NO', + TouredBy: 'Pablo Cambeiro' + }, + { + Tour: 'Apparatus', + StartedOn: 'Nov 16', + Location: 'Europe', + Headliner: 'NO', + TouredBy: 'Pablo Cambeiro' + } + ], + Albums: [ + { + Album: 'Fluke', + LaunchDate: new Date('August 4, 2017'), + BillboardReview: 93, + USBillboard200: 98, + Artist: 'Pablo Cambeiro', + Songs: [{ + Number: 1, + Title: 'Silence', + Released: new Date('25 Aug 2017'), + Genre: 'rap-hop', + Album: 'Fluke' + }, + { + Number: 2, + Title: 'Nothing matters anymore', + Released: new Date('25 Aug 2017'), + Genre: '*', + Album: 'Fluke' + }, + { + Number: 3, + Title: 'Everything wrong with me', + Released: new Date('25 Aug 2017'), + Genre: '*', + Album: 'Fluke' + }] + }, + { + Album: 'Crowd control', + LaunchDate: new Date('August 26, 2003'), + BillboardReview: 68, + USBillboard200: 84, + Artist: 'Pablo Cambeiro', + Songs: [{ + Number: 1, + Title: 'My Bed on My Mind', + Released: new Date('25 Mar 2019'), + Genre: 'ethno-tunes', + Album: 'Crowd control' + }, + { + Number: 2, + Title: 'Bright Blues', + Released: new Date('28 Sep 2019'), + Genre: 'neuro-tunes', + Album: 'Crowd control' + }, + { + Number: 3, + Title: 'Sail, Sail, Sail!', + Released: new Date('5 Mar 2019'), + Genre: '*', + Album: 'Crowd control' + }, + { + Number: 4, + Title: 'Hotel My Bed', + Released: new Date('22 Mar 2019'), + Genre: '*', + Album: 'Crowd control' + }, + { + Number: 5, + Title: 'Gonna Make You Mash', + Released: new Date('18 May 2019'), + Genre: '*', + Album: 'Crowd control' + }, + { + Number: 6, + Title: 'Straight Outta America', + Released: new Date('16 Jan 2020'), + Genre: 'hardcore opera', + Album: 'Crowd control' + }, + { + Number: 7, + Title: 'I Drive', + Released: new Date('23 Feb 2019'), + Genre: 'emotional C-jam ', + Album: 'Crowd control' + }, + { + Number: 8, + Title: 'Like a Teddy', + Released: new Date('31 Aug 2019'), + Genre: '*', + Album: 'Crowd control' + }, + { + Number: 9, + Title: 'Teddy Boogie', + Released: new Date('30 Nov 2019'), + Genre: '*', + Album: 'Crowd control' + }] + }] + }, + { + ID: 10, + Artist: 'Athar Malakooti', + // Photo: 'assets/images/hgrid/athar.jpg', + Debut: 2017, + GrammyNominations: 0, + GrammyAwards: 0, + HasGrammyAward: false, + Albums: [ + { + Album: 'Pushing up daisies', + LaunchDate: new Date('February 24, 2016'), + BillboardReview: 74, + USBillboard200: 77, + Artist: 'Athar Malakooti', + Songs: [{ + Number: 1, + Title: 'Actions', + Released: new Date('25 Feb 2016'), + Genre: 'ethno-tunes', + Album: 'Pushing up daisies' + }, + { + Number: 2, + Title: 'Blinding lights', + Released: new Date('28 Feb 2016'), + Genre: 'neuro-tunes', + Album: 'Pushing up daisies' + }, + { + Number: 3, + Title: 'I want more', + Released: new Date('5 Mar 2016'), + Genre: '*', + Album: 'Pushing up daisies' + }, + { + Number: 4, + Title: 'House by the lake', + Released: new Date('22 Mar 2016'), + Genre: '*', + Album: 'Pushing up daisies' + }] + } + ] + }, + { + ID: 11, + Artist: 'Marti Valencia', + // Photo: 'assets/images/hgrid/marti.jpg', + Debut: 2004, + GrammyNominations: 1, + GrammyAwards: 1, + HasGrammyAward: true, + Tours: [ + { + Tour: 'Cat eat cat world', + StartedOn: 'Sep 00', + Location: 'Worldwide', + Headliner: 'YES', + TouredBy: 'Marti Valencia' + }, + { + Tour: 'Final straw', + StartedOn: 'Sep 06', + Location: 'United States, Europe', + Headliner: 'NO', + TouredBy: 'Marti Valencia' + }], + Albums: [ + { + Album: 'Nemesis', + LaunchDate: new Date('June 30, 2004'), + BillboardReview: 94, + USBillboard200: 9, + Artist: 'Marti Valencia', + Songs: [{ + Number: 1, + Title: 'Love in motion', + Released: new Date('25 Jun 2004'), + Genre: 'ethno-tunes', + Album: 'Nemesis' + }, + { + Number: 2, + Title: 'The picture', + Released: new Date('28 Jun 2004'), + Genre: 'neuro-tunes', + Album: 'Nemesis' + }, + { + Number: 3, + Title: 'Flowers', + Released: new Date('5 Jul 2004'), + Genre: '*', + Album: 'Nemesis' + }, + { + Number: 4, + Title: 'Regret', + Released: new Date('22 Aug 2004'), + Genre: 'Heavy metal', + Album: 'Nemesis' + }] + }, + { + Album: 'First chance', + LaunchDate: new Date('January 7, 2019'), + BillboardReview: 96, + USBillboard200: 19, + Artist: 'Marti Valencia', + Songs: [{ + Number: 1, + Title: 'My Name is Jason', + Released: new Date('12 Jul 2019'), + Genre: '*', + Album: 'First chance' + }, + { + Number: 2, + Title: 'Amazing Andy', + Released: new Date('5 Mar 2019'), + Genre: '*', + Album: 'First chance' + }, + { + Number: 3, + Title: 'The Number of your Knight', + Released: new Date('4 Dec 2019'), + Genre: '*', + Album: 'First chance' + }, + { + Number: 4, + Title: 'I Sail', + Released: new Date('3 Mar 2019'), + Genre: '*', + Album: 'First chance' + }, + { + Number: 5, + Title: 'Goody Two Hands', + Released: new Date('11 Oct 2019'), + Genre: 'Electro house Electropop', + Album: 'First chance' + }, + { + Number: 6, + Title: 'Careful With That Knife', + Released: new Date('18 Dec 2019'), + Genre: 'R&B', + Album: 'First chance' + }, + { + Number: 7, + Title: 'Four Single Ants', + Released: new Date('18 Jan 2020'), + Genre: '*', + Album: 'First chance' + }, + { + Number: 8, + Title: 'Kiss Forever', + Released: new Date('10 Aug 2019'), + Genre: '*', + Album: 'First chance' + }, + { + Number: 9, + Title: 'Rich\'s Waiting', + Released: new Date('15 Mar 2019'), + Genre: 'Synth-pop R&B', + Album: 'First chance' + }, + { + Number: 10, + Title: 'Japan is Your Land', + Released: new Date('7 Mar 2019'), + Genre: 'ethno-tunes', + Album: 'First chance' + }, + { + Number: 11, + Title: 'Pencils in My Banana', + Released: new Date('21 Jun 2019'), + Genre: 'Crunk reggaeton', + Album: 'First chance' + }, + { + Number: 12, + Title: 'I Sail in Your Arms', + Released: new Date('30 Apr 2019'), + Genre: 'Synth-pop R&B', + Album: 'First chance' + }] + }, + { + Album: 'God\'s advocate', + LaunchDate: new Date('April 29, 2007'), + BillboardReview: 66, + USBillboard200: 37, + Artist: 'Marti Valencia', + Songs: [{ + Number: 1, + Title: 'Destiny', + Released: new Date('07 May 2007'), + Genre: '*', + Album: 'God\'s advocate' + }, + { + Number: 2, + Title: 'I am the chosen one', + Released: new Date('08 May 2007'), + Genre: 'Heavy metal', + Album: 'God\'s advocate' + }, + { + Number: 3, + Title: 'New me', + Released: new Date('09 May 2007'), + Genre: 'Dance-pop R&B', + Album: 'God\'s advocate' + }, + { + Number: 4, + Title: 'Miss you', + Released: new Date('10 May 2007'), + Genre: 'Heavy metal', + Album: 'God\'s advocate' + }, + { + Number: 5, + Title: 'Turn back the time', + Released: new Date('21 May 2007'), + Genre: 'Dance-pop EDM', + Album: 'God\'s advocate' + }, + { + Number: 6, + Title: 'Let us have fun', + Released: new Date('01 Jun 2007'), + Genre: 'Dance-pop EDM', + Album: 'God\'s advocate' + }] + } + ] + }, + { + ID: 12, + Artist: 'Alicia Stanger', + // Photo: 'assets/images/hgrid/alicia.jpg', + Debut: 2010, + GrammyNominations: 1, + GrammyAwards: 0, + HasGrammyAward: false, + Albums: [ + { + Album: 'Forever alone', + LaunchDate: new Date('November 3, 2005'), + BillboardReview: 82, + USBillboard200: 7, + Artist: 'Alicia Stanger', + Songs: [{ + Number: 1, + Title: 'Brothers', + Released: new Date('25 Oct 2005'), + Genre: 'Hip-hop', + Album: 'Forever alone' + }, + { + Number: 2, + Title: 'Alone', + Released: new Date('28 Oct 2005'), + Genre: 'Heavy metal', + Album: 'Forever alone' + }, + { + Number: 3, + Title: 'I will go on', + Released: new Date('5 Nov 2005'), + Genre: 'Heavy metal', + Album: 'Forever alone' + }, + { + Number: 4, + Title: 'Horses', + Released: new Date('22 Dec 2005'), + Genre: '*', + Album: 'Forever alone' + }] + } + ] + }, + { + ID: 13, + Artist: 'Peter Taylor', + // Photo: 'assets/images/hgrid/peter.jpg', + Debut: 2005, + GrammyNominations: 0, + GrammyAwards: 2, + HasGrammyAward: true, + Tours: [ + { + Tour: 'Love', + StartedOn: 'Jun 04', + Location: 'Europe, Asia', + Headliner: 'YES', + TouredBy: 'Peter Taylor' + }, + { + Tour: 'Fault of treasures', + StartedOn: 'Oct 13', + Location: 'North America', + Headliner: 'NO', + TouredBy: 'Peter Taylor' + }, + { + Tour: 'For eternity', + StartedOn: 'Mar 05', + Location: 'United States', + Headliner: 'YES', + TouredBy: 'Peter Taylor' + }, + { + Tour: 'Time flies', + StartedOn: 'Jun 03', + Location: 'North America', + Headliner: 'NO', + TouredBy: 'Peter Taylor' + }, + { + Tour: 'Highest difficulty', + StartedOn: 'Nov 01', + Location: 'Worldwide', + Headliner: 'YES', + TouredBy: 'Peter Taylor' + }, + { + Tour: 'Sleeping dogs', + StartedOn: 'May 04', + Location: 'United States, Europe', + Headliner: 'NO', + TouredBy: 'Peter Taylor' + } + ], + Albums: [ + { + Album: 'Decisions decisions', + LaunchDate: new Date('April 10, 2008'), + BillboardReview: 85, + USBillboard200: 35, + Artist: 'Peter Taylor', + Songs: [{ + Number: 1, + Title: 'Now that I am alone', + Released: new Date('25 Apr 2008'), + Genre: '*', + Album: 'Decisions decisions' + }, + { + Number: 2, + Title: 'Hopefully', + Released: new Date('26 Apr 2008'), + Genre: '*', + Album: 'Decisions decisions' + }, + { + Number: 3, + Title: 'Wonderful life', + Released: new Date('5 May 2008'), + Genre: '*', + Album: 'Decisions decisions' + }, + { + Number: 4, + Title: 'Amazing world', + Released: new Date('22 Dec 2008'), + Genre: '*', + Album: 'Decisions decisions' + }] + }, + { + Album: 'Climate changed', + LaunchDate: new Date('June 20, 2015'), + BillboardReview: 66, + USBillboard200: 89, + Artist: 'Peter Taylor', + Songs: [{ + Number: 1, + Title: 'This is how I am now', + Released: new Date('22 Jun 2015'), + Genre: 'Hip-hop', + Album: 'Climate changed' + }, + { + Number: 2, + Title: 'I feel', + Released: new Date('26 Jun 2015'), + Genre: 'rap-hop', + Album: 'Climate changed' + }, + { + Number: 3, + Title: 'Do I want to know', + Released: new Date('5 Jul 2015'), + Genre: 'rap-hop', + Album: 'Climate changed' + }, + { + Number: 4, + Title: 'Natural love', + Released: new Date('22 Jul 2015'), + Genre: '*', + Album: 'Climate changed' + }, + { + Number: 5, + Title: 'I will help', + Released: new Date('22 Jul 2015'), + Genre: '*', + Album: 'Climate changed' + }, + { + Number: 6, + Title: 'No matter what', + Released: new Date('22 Jul 2015'), + Genre: 'hip-hop', + Album: 'Climate changed' + }] + } + ] + } +]; diff --git a/src/app/hierarchical-grid-advanced-filtering/hierarchical-grid-advanced-filtering.sample.html b/src/app/hierarchical-grid-advanced-filtering/hierarchical-grid-advanced-filtering.sample.html new file mode 100644 index 00000000000..b7fe0a8600a --- /dev/null +++ b/src/app/hierarchical-grid-advanced-filtering/hierarchical-grid-advanced-filtering.sample.html @@ -0,0 +1,15 @@ +
+

Sample One

+ + + + + + + + + + +
diff --git a/src/app/hierarchical-grid-advanced-filtering/hierarchical-grid-advanced-filtering.sample.scss b/src/app/hierarchical-grid-advanced-filtering/hierarchical-grid-advanced-filtering.sample.scss new file mode 100644 index 00000000000..493f8cca993 --- /dev/null +++ b/src/app/hierarchical-grid-advanced-filtering/hierarchical-grid-advanced-filtering.sample.scss @@ -0,0 +1,13 @@ +:host::ng-deep { + .activeRow { + background-color: rgb(201, 241, 201); + } +} + +[igxButton="contained"] { + margin: 0.5rem; +} + +h4 { + padding-top: 2rem; +} diff --git a/src/app/hierarchical-grid-advanced-filtering/hierarchical-grid-advanced-filtering.sample.ts b/src/app/hierarchical-grid-advanced-filtering/hierarchical-grid-advanced-filtering.sample.ts new file mode 100644 index 00000000000..5e3eff812c3 --- /dev/null +++ b/src/app/hierarchical-grid-advanced-filtering/hierarchical-grid-advanced-filtering.sample.ts @@ -0,0 +1,54 @@ +import { Component, ViewChild, ChangeDetectorRef, AfterViewInit } from '@angular/core'; +import { + IgxHierarchicalGridComponent, + IGX_HIERARCHICAL_GRID_DIRECTIVES, + FilteringExpressionsTree, + FilteringLogic, + IgxStringFilteringOperand, + IgxDateFilteringOperand +} from 'igniteui-angular'; +import { SINGERS } from './data'; + + +@Component({ + selector: 'app-hierarchical-grid-advanced-filtering-sample', + styleUrls: ['hierarchical-grid-advanced-filtering.sample.scss'], + templateUrl: 'hierarchical-grid-advanced-filtering.sample.html', + imports: [IGX_HIERARCHICAL_GRID_DIRECTIVES] +}) +export class HierarchicalGridAdvancedFilteringSampleComponent implements AfterViewInit { + @ViewChild('hierarchicalGrid', { static: true }) + private hierarchicalGrid: IgxHierarchicalGridComponent; + + public localData = []; + + constructor(private cdr: ChangeDetectorRef) { + this.localData = SINGERS; + } + + public ngAfterViewInit() { + const albumsTree = new FilteringExpressionsTree(FilteringLogic.And, undefined, 'Albums', ['Artist']); + albumsTree.filteringOperands.push({ + fieldName: 'LaunchDate', + condition: IgxDateFilteringOperand.instance().condition('after'), + conditionName: IgxDateFilteringOperand.instance().condition('after').name, + searchVal: new Date(2018, 1, 1) + }); + // const toursTree = new FilteringExpressionsTree(FilteringLogic.And, undefined, 'Tours', ['TouredBy']); + // toursTree.filteringOperands.push({ + // fieldName: 'Headliner', + // condition: IgxStringFilteringOperand.instance().condition('equals'), + // conditionName: IgxStringFilteringOperand.instance().condition('equals').name, + // searchVal: 'YES' + // }); + const artistsTree = new FilteringExpressionsTree(FilteringLogic.And, undefined, 'Artists', ['*']); + artistsTree.filteringOperands.push({ + fieldName: 'Artist', + condition: IgxStringFilteringOperand.instance().condition('inQuery'), + conditionName: IgxStringFilteringOperand.instance().condition('inQuery').name, + searchTree: albumsTree + }); + this.hierarchicalGrid.advancedFilteringExpressionsTree = artistsTree; + this.cdr.detectChanges(); + } +} diff --git a/src/app/hierarchical-grid-remote-virtualization/hierarchical-grid-remote-virtualization.ts b/src/app/hierarchical-grid-remote-virtualization/hierarchical-grid-remote-virtualization.ts index 84ad3c5d662..bd5345ae2a1 100644 --- a/src/app/hierarchical-grid-remote-virtualization/hierarchical-grid-remote-virtualization.ts +++ b/src/app/hierarchical-grid-remote-virtualization/hierarchical-grid-remote-virtualization.ts @@ -3,7 +3,6 @@ import { IGX_HIERARCHICAL_GRID_DIRECTIVES, IgxHierarchicalGridComponent } from 'igniteui-angular'; -import { RemoteService } from '../shared/remote.service'; import { HierarchicalRemoteService } from './hierarchical-remote.service'; import { debounceTime } from 'rxjs/operators'; @@ -11,7 +10,7 @@ import { debounceTime } from 'rxjs/operators'; selector: 'app-hierarchical-grid-remote-virtualization-sample', templateUrl: 'hierarchical-grid-remote-virtualization.html', styleUrls: ['hierarchical-grid-remote-virtualization.scss'], - providers: [RemoteService], + providers: [HierarchicalRemoteService], imports: [IGX_HIERARCHICAL_GRID_DIRECTIVES] }) export class HierarchicalGridRemoteVirtualizationComponent implements AfterViewInit { diff --git a/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.html b/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.html index 2c2d2059def..eca7380d243 100644 --- a/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.html +++ b/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.html @@ -1,42 +1,37 @@ - - + - Parent Toolbar - - - + Customers - - - - - - - + + - Child Toolbar - Level 2 - - - + Orders - - - - - - + + + + + - Child Toolbar - Level 3 - - - - + Order Details - - - - + + + + + diff --git a/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.ts b/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.ts index e3f705c25a4..0c9d4b1c08a 100644 --- a/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.ts +++ b/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.ts @@ -1,85 +1,144 @@ -import { Component, ViewChild, AfterViewInit } from '@angular/core'; +import { Component, ViewChild, OnInit, ChangeDetectorRef, AfterViewInit } from '@angular/core'; import { IgxRowIslandComponent, IgxHierarchicalGridComponent, IGridCreatedEventArgs, - GridSelectionMode, - IGX_HIERARCHICAL_GRID_DIRECTIVES + IGX_HIERARCHICAL_GRID_DIRECTIVES, + FilteringExpressionsTree, + IgxStringFilteringOperand, + EntityType, + IgxNumberFilteringOperand } from 'igniteui-angular'; -import { RemoteService } from '../shared/remote.service'; +import { HttpClient } from '@angular/common/http'; + +const API_ENDPOINT = 'https://data-northwind.indigo.design'; @Component({ selector: 'app-hierarchical-grid-remote-sample', templateUrl: 'hierarchical-grid-remote.sample.html', styleUrls: ['hierarchical-grid-remote.sample.scss'], - providers: [RemoteService], imports: [IGX_HIERARCHICAL_GRID_DIRECTIVES] }) -export class HierarchicalGridRemoteSampleComponent implements AfterViewInit { - @ViewChild('rowIsland1', { static: true }) - private rowIsland1: IgxRowIslandComponent; - +export class HierarchicalGridRemoteSampleComponent implements OnInit, AfterViewInit { @ViewChild('hGrid', { static: true }) private hGrid: IgxHierarchicalGridComponent; public selectionMode; public remoteData = []; public primaryKeys = [ - { name: 'CustomerID', type: 'string', level: 0 }, - { name: 'OrderID', type: 'number', level: 1 }, - { name: 'EmployeeID', type: 'number', level: 2 }, - { name: 'ProductID', type: 'number', level: 2 } + { name: 'Customers', key: 'customerId' }, + { name: 'Orders', key: 'orderId' }, + { name: 'Details', key: 'orderId' } + ]; + public remoteEntities: EntityType[] = [ + { + name: 'Customers', + fields: [ + { field: 'customerId', dataType: 'string' }, + { field: 'companyName', dataType: 'string' }, + { field: 'contactName', dataType: 'string' }, + { field: 'contactTitle', dataType: 'string' } + ], + childEntities: [ + { + name: 'Orders', + fields: [ + { field: 'customerId', dataType: 'string' }, // first field will be treated as foreign key + { field: 'orderId', dataType: 'number' }, + { field: 'employeeId', dataType: 'number' }, + { field: 'shipVia', dataType: 'string' }, + { field: 'freight', dataType: 'number' } + ], + childEntities: [ + { + name: 'Details', + fields: [ + { field: 'orderId', dataType: 'number' }, // first field will be treated as foreign key + { field: 'productId', dataType: 'number' }, + { field: 'unitPrice', dataType: 'number' }, + { field: 'quantity', dataType: 'number' }, + { field: 'discount', dataType: 'number' } + ] + } + ] + } + ] + } ]; - constructor(private remoteService: RemoteService) { - remoteService.url = 'https://services.odata.org/V4/Northwind/Northwind.svc/'; + constructor(private http: HttpClient, private cdr: ChangeDetectorRef) {} - this.remoteService.urlBuilder = (dataState) => this.buildUrl(dataState); - this.selectionMode = GridSelectionMode.none; - } + public ngOnInit() { + const ordersTree = new FilteringExpressionsTree(0, undefined, 'Orders', ['customerId']); + ordersTree.filteringOperands.push({ + fieldName: 'freight', + ignoreCase: false, + condition: IgxNumberFilteringOperand.instance().condition('greaterThanOrEqualTo'), + conditionName: IgxNumberFilteringOperand.instance().condition('greaterThanOrEqualTo').name, + searchVal: '500' + }); - public buildUrl(dataState) { - let qS = ''; - if (dataState) { - qS += `${dataState.key}?`; + const customersTree = new FilteringExpressionsTree(0, undefined, 'Customers', ['customerId', 'companyName', 'contactName', 'contactTitle']); + customersTree.filteringOperands.push({ + fieldName: 'customerId', + condition: IgxStringFilteringOperand.instance().condition('inQuery'), + conditionName: IgxStringFilteringOperand.instance().condition('inQuery').name, + ignoreCase: false, + searchTree: ordersTree + }); + // customersTree.filteringOperands.push({ + // fieldName: 'customerId', + // ignoreCase: false, + // conditionName: IgxStringFilteringOperand.instance().condition('startsWith').name, + // searchVal: 'A' + // }); + this.hGrid.advancedFilteringExpressionsTree = customersTree; + } - const level = dataState.level; - if (level > 0) { - const parentKey = this.primaryKeys.find((key) => key.level === level - 1); - const parentID = typeof dataState.parentID !== 'object' ? dataState.parentID : dataState.parentID[parentKey.name]; + public ngAfterViewInit() { + this.advancedFilteringExprTreeChange(); + } - if (parentKey.type === 'string') { - qS += `$filter=${parentKey.name} eq '${parentID}'`; - } else { - qS += `$filter=${parentKey.name} eq ${parentID}`; - } - } + public advancedFilteringExprTreeChange() { + let tree = this.hGrid.advancedFilteringExpressionsTree; + if (!tree) { + tree = new FilteringExpressionsTree(0, undefined, this.remoteEntities[0].name, this.remoteEntities[0].fields.map(f => f.field)); } - return `${this.remoteService.url}${qS}`; - } - public ngAfterViewInit() { - this.remoteService.getData({ parentID: null, level: 0, key: 'Customers' }, (data) => { - this.remoteData = data['value']; + console.log(tree); + + this.hGrid.isLoading = true; + this.http.post(`${API_ENDPOINT}/QueryBuilder/ExecuteQuery`, tree).subscribe(data =>{ + console.log('data', data); + this.remoteData = Object.values(data)[0]; this.hGrid.isLoading = false; + this.cdr.detectChanges(); + this.calculateColsInView(); }); } - public setterChange() { - this.rowIsland1.rowSelection = this.rowIsland1.rowSelection === GridSelectionMode.multiple - ? GridSelectionMode.none : GridSelectionMode.multiple; - } - - public setterBindingChange() { - this.selectionMode = this.selectionMode === GridSelectionMode.none ? GridSelectionMode.multiple : GridSelectionMode.none; + private calculateColsInView() { + if (this.hGrid.advancedFilteringExpressionsTree) { + this.hGrid.columns.forEach(column => + column.hidden = !this.hGrid.advancedFilteringExpressionsTree.returnFields.includes(column.field)); + } } public gridCreated(event: IGridCreatedEventArgs, rowIsland: IgxRowIslandComponent) { event.grid.isLoading = true; - this.remoteService.getData({ parentID: event.parentID, level: rowIsland.level, key: rowIsland.key }, (data) => { - event.grid.data = data['value']; + const url = this.buildUrl(event, rowIsland); + this.http.get(url).subscribe(data => { + console.log('data', data); + event.grid.data = Object.values(data); event.grid.isLoading = false; - event.grid.cdr.detectChanges(); + this.cdr.detectChanges(); }); } + + private buildUrl(event: IGridCreatedEventArgs, rowIsland: IgxRowIslandComponent) { + const rowIslandKey = this.primaryKeys.find(key => key.name === rowIsland.key).name; + const parentKey = (event.grid.parent as any).key ?? event.grid.parent.advancedFilteringExpressionsTree.entity; + const url = `${API_ENDPOINT}/${parentKey}/${event.parentID}/${rowIslandKey}`; + return url; + } } diff --git a/src/app/list/list.sample.html b/src/app/list/list.sample.html index c58c9218e77..a1e71892699 100644 --- a/src/app/list/list.sample.html +++ b/src/app/list/list.sample.html @@ -2,7 +2,17 @@
Angular List
- + + +
+ deleteDelete +
+
+ +
+ callDial +
+
Employees List @for (employee of employeeItems; track employee) { diff --git a/src/app/list/list.sample.scss b/src/app/list/list.sample.scss index ca19d5bb78c..c28c9cd3c75 100644 --- a/src/app/list/list.sample.scss +++ b/src/app/list/list.sample.scss @@ -1,3 +1,21 @@ .sample-title { text-align: center; } + +.pan { + display: flex; + color: white; + width: 100%; + padding-left: 10px; + align-items: center; +} + +.pan--left { + flex-direction: row-reverse; + background-color:orange; +} + +.pan--right { + flex-direction: row; + background-color:limegreen; +} diff --git a/src/app/list/list.sample.ts b/src/app/list/list.sample.ts index 7e1ca2ae378..5cc31545450 100644 --- a/src/app/list/list.sample.ts +++ b/src/app/list/list.sample.ts @@ -30,6 +30,8 @@ import { PropertyChangeService, PropertyPanelConfig, } from '../properties-panel/property-change.service'; +import { HAMMER_GESTURE_CONFIG, HammerModule } from '@angular/platform-browser'; +import Hammer from 'hammerjs'; defineComponents( IgcListComponent, @@ -79,7 +81,18 @@ interface Employee { IgxAvatarComponent, IgxButtonModule, IgxButtonDirective, - IgSizeDirective + IgSizeDirective, + HammerModule + ], + providers: [ + { + provide: HAMMER_GESTURE_CONFIG, + useClass: class { + public overrides = { + pan: { direction: Hammer.DIRECTION_HORIZONTAL } + } + } + } ] }) export class ListSampleComponent { @@ -87,7 +100,8 @@ export class ListSampleComponent { size: { control: { type: 'button-group', - options: ['small', 'medium', 'large'] + options: ['small', 'medium', 'large'], + defaultValue: 'medium' } }, hideTitle: { @@ -145,6 +159,13 @@ export class ListSampleComponent { type: 'boolean', defaultValue: false } + }, + enablePanning: { + label: 'Item Panning', + control: { + type: 'boolean', + defaultValue: false + } } } diff --git a/src/app/shared/sample-data.ts b/src/app/shared/sample-data.ts index 9f0ee0739e3..cd368679619 100644 --- a/src/app/shared/sample-data.ts +++ b/src/app/shared/sample-data.ts @@ -318,8 +318,7 @@ export const SAMPLE_DATA = [ }, { ID: 'ERNSH', - CompanyName: - 'Ernst Handel', + CompanyName: 'Ernst Handel', ContactName: 'Roland Mendel', ContactTitle: 'Sales Manager', Address: 'Kirchgasse 6', diff --git a/src/app/stepper/stepper.sample.html b/src/app/stepper/stepper.sample.html index 86f246c02de..c5f6f147797 100644 --- a/src/app/stepper/stepper.sample.html +++ b/src/app/stepper/stepper.sample.html @@ -33,6 +33,10 @@ + + phone + + Ex.: +359 888 123 456