diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index efa2465b8c..0000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,278 +0,0 @@ -{ - "root": true, - "ignorePatterns": ["projects/**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": ["tsconfig.json"], - "createDefaultProgram": true - }, - "extends": [ - "plugin:@typescript-eslint/recommended", - "plugin:@angular-eslint/recommended", - "plugin:@angular-eslint/template/process-inline-templates" - ], - "plugins": ["sonarjs"], - "rules": { - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-this-alias": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/no-array-constructor": "off", - "@angular-eslint/component-selector": [ - "error", - { - "type": ["element", "attribute"], - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/directive-class-suffix": "off", - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/no-input-rename": "off", - "@angular-eslint/no-output-rename": "off", - "@angular-eslint/no-output-native": "off", - "@angular-eslint/no-output-on-prefix": "off", - "@angular-eslint/no-conflicting-lifecycle": "off", - "@typescript-eslint/array-type": [ - "error", - { - "default": "generic" - } - ], - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "off", - { - "types": { - "String": { - "message": "Use string instead", - "fixWith": "string" - }, - "Boolean": { - "message": "Use boolean instead", - "fixWith": "boolean" - }, - "Number": { - "message": "Use number instead", - "fixWith": "number" - } - } - } - ], - "@typescript-eslint/consistent-type-assertions": "off", - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/dot-notation": "off", - "@typescript-eslint/explicit-member-accessibility": [ - "off", - { - "accessibility": "explicit" - } - ], - "@typescript-eslint/member-delimiter-style": [ - "off", - { - "multiline": { - "delimiter": "none", - "requireLast": true - }, - "singleline": { - "delimiter": "semi", - "requireLast": false - } - } - ], - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": [ - "off", - { - "ignoreParameters": true - } - ], - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "@typescript-eslint/no-unused-expressions": "off", - "@typescript-eslint/no-var-requires": "error", - "@typescript-eslint/prefer-for-of": "off", - "@typescript-eslint/quotes": [ - "off", - "single", - { - "allowTemplateLiterals": true - } - ], - "@typescript-eslint/require-array-sort-compare": [ - "error", - { - "ignoreStringArrays": true - } - ], - "@typescript-eslint/semi": ["off", null], - "@typescript-eslint/type-annotation-spacing": "off", - "camelcase": "off", - "@typescript-eslint/naming-convention": [ - "error", - { - "selector": "default", - "format": ["camelCase"] - }, - { - "selector": "variable", - "format": ["camelCase", "UPPER_CASE", "snake_case", "PascalCase"], - "leadingUnderscore": "allow" - }, - { - "selector": "import", - "format": ["camelCase", "PascalCase"], - "leadingUnderscore": "allow" - }, - { - "selector": "classProperty", - "format": ["camelCase", "UPPER_CASE", "snake_case", "PascalCase"], - "leadingUnderscore": "allow" - }, - { - "selector": "parameter", - "format": ["camelCase"], - "leadingUnderscore": "allow" - }, - { - "selector": "memberLike", - "modifiers": ["private"], - "format": ["camelCase"], - "leadingUnderscore": "allow" - }, - { - "selector": "typeLike", - "format": ["PascalCase", "camelCase"] - }, - { - "selector": "enumMember", - "format": ["UPPER_CASE", "camelCase", "PascalCase"], - "leadingUnderscore": "allow" - }, - { - "selector": ["objectLiteralMethod"], - "format": ["PascalCase", "camelCase", "snake_case", "UPPER_CASE"], - "leadingUnderscore": "allow" - }, - { - "selector": ["objectLiteralProperty"], - "format": null, - "leadingUnderscore": "allow" - }, - { - "selector": "function", - "format": ["PascalCase", "camelCase"], - "leadingUnderscore": "allow" - } - ], - "@typescript-eslint/member-ordering": [ - "error", - { - "default": ["signature", "field", "constructor", "method"] - } - ], - "arrow-parens": ["off", "always"], - "arrow-body-style": ["error", "as-needed"], - "brace-style": ["off", "off"], - "default-case-last": "error", - "dot-notation": "off", - "eol-last": "off", - "id-blacklist": "off", - "id-match": "off", - "indent": "off", - "linebreak-style": "off", - "max-len": "off", - "max-lines-per-function": [ - "off", - { - "max": 200 - } - ], - "max-params": [ - "error", - { - "max": 8 - } - ], - "new-parens": "off", - "newline-per-chained-call": "off", - "no-empty-function": "off", - "no-empty-pattern": "off", - "no-extra-parens": "off", - "no-extra-semi": "error", - "no-irregular-whitespace": "off", - "no-multi-str": "error", - "no-self-assign": "error", - "no-shadow": "off", - "no-trailing-spaces": "off", - "no-underscore-dangle": "off", - "no-unused-expressions": [ - "error", - { - "allowTernary": true - } - ], - "no-use-before-define": "off", - "object-shorthand": "off", - "padded-blocks": [ - "off", - { - "blocks": "never" - }, - { - "allowSingleLineBlocks": true - } - ], - "prefer-arrow/prefer-arrow-functions": "off", - "quote-props": "off", - "jsdoc/no-types": "off", - "jsdoc/newline-after-description": "off", - "semi": "off", - "sonarjs/cognitive-complexity": "off", - "sonarjs/max-switch-cases": "error", - "sonarjs/no-all-duplicated-branches": "error", - "sonarjs/no-collapsible-if": "error", - "sonarjs/no-collection-size-mischeck": "error", - "sonarjs/no-duplicate-string": "off", - "sonarjs/no-duplicated-branches": "off", - "sonarjs/no-element-overwrite": "error", - "sonarjs/no-identical-conditions": "error", - "sonarjs/no-identical-expressions": "error", - "sonarjs/no-identical-functions": "off", - "sonarjs/no-inverted-boolean-check": "error", - "sonarjs/no-one-iteration-loop": "off", - "sonarjs/no-redundant-boolean": "error", - "sonarjs/no-redundant-jump": "error", - "sonarjs/no-same-line-conditional": "error", - "sonarjs/no-small-switch": "error", - "sonarjs/no-unused-collection": "error", - "sonarjs/no-use-of-empty-return-value": "error", - "sonarjs/no-useless-catch": "error", - "sonarjs/prefer-immediate-return": "error", - "space-before-function-paren": "off", - "space-in-parens": ["off", "never"], - "@angular-eslint/prefer-standalone": "off", - "@typescript-eslint/no-unsafe-function-type": "off", - "@typescript-eslint/no-empty-object-type": "off", - "@angular-eslint/prefer-inject": "off" - } - }, - { - "files": ["*.html"], - "extends": ["plugin:@angular-eslint/template/recommended"], - "rules": { - "@angular-eslint/template/prefer-control-flow": "warn" - } - } - ] -} diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 556f001e5f..c45949889b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -10,7 +10,7 @@ assignees: '' #### Reprodução -Utilize StackBlitz (https://stackblitz.com/edit/po-ui) para reproduzir o bug relatado na issue. +Utilize StackBlitz (https://stackblitz.com/edit/poui-module) para reproduzir o bug relatado na issue. Passos para reproduzir: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e33fb6c51b..eacb97c1cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,6 +94,7 @@ jobs: node-version: 24 - run: npm i + - run: npm run build:schematics - run: npm run build:ui:lite - run: npm run test:templates - run: npm run test:templates:schematics @@ -112,6 +113,7 @@ jobs: node-version: 24 - run: npm i + - run: npm run build:schematics - run: npm run test:code-editor - run: npm run test:code-editor:schematics @@ -178,6 +180,7 @@ jobs: node-version: 24 - run: npm i + - run: npm run build:schematics - run: npm run build:storage:lite - run: npm run test:sync - run: npm run test:sync:schematics diff --git a/.github/workflows/publish_po_angular_ci.yml b/.github/workflows/publish_po_angular_ci.yml index cbd8fa6446..a04ae8a8a7 100644 --- a/.github/workflows/publish_po_angular_ci.yml +++ b/.github/workflows/publish_po_angular_ci.yml @@ -58,7 +58,7 @@ jobs: ;; next) echo "npm_tag=next" >> "$GITHUB_OUTPUT" - echo "required_branch=refs/heads/master" >> "$GITHUB_OUTPUT" + echo "required_branch=refs/heads/22.x.x" >> "$GITHUB_OUTPUT" echo "with_mcp=true" >> "$GITHUB_OUTPUT" ;; latest) diff --git a/CHANGELOG.md b/CHANGELOG.md index e00cb74112..4033c4ea7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,47 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [22.0.0-rc.0](https://github.com/po-ui/po-angular/compare/v22.0.0-next.0...v22.0.0-rc.0) (2026-10-28) + +### Features + +* **schematics:** detecta e preserva o nome da classe do App ([155530f](https://github.com/po-ui/po-angular/commit/155530fe7baa7db5fe958900c98582487979d72c)) + +## [22.0.0-next.0](https://github.com/po-ui/po-angular/compare/v21.33.0...v22.0.0-next.0) (2026-10-09) + + +### ⚠ BREAKING CHANGES + +* **schematics:** removidos os schematics de ng generate de páginas + +Os comandos "ng generate @po-ui/ng-templates:po-page-*" e +"ng generate @po-ui/ng-components:po-page-*" para geração de páginas +deixam de existir. A alternativa recomendada passa a ser o uso do +MCP do PO UI para geração de páginas e componentes, conforme a +documentação em https://po-ui.io/documentation/ia-tools-mcp. + +* **gauge:** removido componente po-gauge + +O componente po-gauge foi removido por completo da biblioteca. +Utilize o po-chart com type=gauge como alternativa. A migração pode +ser aplicada automaticamente via ng update do PO UI para a v22. + +Antes: + + +Depois: + + +### Features + +* **angular:** atualiza projeto para o Angular 22 ([cd1917c](https://github.com/po-ui/po-angular/commit/cd1917c47c9d42a3f38cee3da891282d52746c2e)) +* **gauge:** remove componente po-gauge depreciado ([8166802](https://github.com/po-ui/po-angular/commit/8166802a6571f7631d5aa3e7ad5b96a41a2c7fba)) +* **schematics:** remove ng generate de páginas e templates ([2900b06](https://github.com/po-ui/po-angular/commit/2900b06370dcd9485f0b53ae05d460383b00b563)) + ### [21.35.0](https://github.com/po-ui/po-angular/compare/v21.34.1...v21.35.0) (2026-10-27) Compatibilidade com @totvs/thf-components@21.35.0 diff --git a/README.md b/README.md index 836d8f29c2..1e1d6c255e 100644 --- a/README.md +++ b/README.md @@ -20,16 +20,16 @@ Biblioteca de componentes de UI para Angular. ### Pré-requisitos -Para começar a utilizar o **PO UI** é pré-requisito ter o `Node.js` instalado (versão 20.11.x ou acima) e o seu gerenciador de pacote favorito na versão mais atual. Caso você ainda não tenha instalado o pacote `@angular/cli`, instale-o via `npm` ou `yarn`. +Para começar a utilizar o **PO UI** é pré-requisito ter o `Node.js` instalado (versão 24.22.1 e acima) e o seu gerenciador de pacote favorito na versão mais atual. Caso você ainda não tenha instalado o pacote `@angular/cli`, instale-o via `npm` ou `yarn`. Instalando com npm: ``` -npm i -g @angular/cli@21 +npm i -g @angular/cli@22 ``` Caso prefira instalar com o yarn: ``` -yarn global add @angular/cli@21 +yarn global add @angular/cli@22 ``` ### Passo 1 - Crie o seu primeiro projeto @@ -53,26 +53,24 @@ Veja abaixo a lista de dependências e as versões compatíveis, elas devem ser ```json "dependencies": { - "@angular/animations": "~21.2.17", - "@angular/common": "~21.2.17", - "@angular/compiler": "~21.2.17", - "@angular/core": "~21.2.17", - "@angular/forms": "~21.2.17", - "@angular/platform-browser": "~21.2.17", - "@angular/platform-browser-dynamic": "~21.2.17", - "@angular/router": "~21.2.17", + "@angular/common": "~22.2.1", + "@angular/compiler": "~22.2.1", + "@angular/core": "~22.2.1", + "@angular/forms": "~22.2.1", + "@angular/platform-browser": "~22.2.1", + "@angular/router": "~22.2.1", "rxjs": "~7.8.1", "tslib": "^2.6.2", "zone.js": "~0.15.0" ... }, "devDependencies": { - "@angular-devkit/build-angular": "~21.2.17", - "@angular-devkit/schematics": "~21.2.17", - "@angular/cli": "~21.2.17", - "@angular/compiler-cli": "~21.2.17", + "@angular-devkit/schematics": "~22.2.1", + "@angular/build": "~22.2.1", + "@angular/cli": "~22.2.1", + "@angular/compiler-cli": "~22.2.1", ... - "typescript": "~5.9.3" + "typescript": "~6.0.3" } ``` @@ -90,14 +88,14 @@ Caso prefira instalar com o yarn: yarn install ``` -### Passo 2 - Adiconando o pacote @po-ui/ng-components +### Passo 2 - Adicionando o pacote @po-ui/ng-components Utilizando o comando `ng add` do [Angular CLI](https://cli.angular.io/), vamos adicionar o **Po** em seu projeto e o mesmo se encarregará de configurar o tema, instalar o guia de primeiros passos **Po**. Além de importar também o modulo **HttpClientModule**. Execute o comando abaixo na pasta raiz do seu projeto: ``` -ng add @po-ui/ng-components +ng add @po-ui/ng-components@next ``` > Ao executar o comando acima, será perguntado se deseja incluir uma estrutura inicial em seu projeto com menu lateral, página e toolbar, utilizando componentes do **Po**, **caso desejar, apenas informe: `Y`**. @@ -138,7 +136,7 @@ Agora é só abrir seu **editor / IDE** favorito e começar a trabalhar no seu p Caso você queira utilizar nossos componentes de templates, como o **[po-page-login](https://po-ui.io/documentation/po-page-login)**, **[po-modal-password-recovery](https://po-ui.io/documentation/po-modal-password-recovery)**, **[po-page-blocked-user](https://po-ui.io/documentation/po-page-blocked-user)**, **[po-page-dynamic-table](https://po-ui.io/documentation/po-page-dynamic-table)** entre outros, basta adicionar o pacote `@po-ui/ng-templates` executando o comando abaixo: ``` -ng add @po-ui/ng-templates +ng add @po-ui/ng-templates@next ``` > Ao executar este comando, será instalado o pacote `@po-ui/ng-templates` e configurado o `PoTemplatesModules` no `app.module`. diff --git a/angular.json b/angular.json index fdaee13f89..f532db6c94 100644 --- a/angular.json +++ b/angular.json @@ -10,7 +10,7 @@ "prefix": "po", "architect": { "build": { - "builder": "@angular-devkit/build-angular:ng-packagr", + "builder": "@angular/build:ng-packagr", "options": { "tsConfig": "projects/ui/tsconfig.lib.json", "project": "projects/ui/ng-package.json" @@ -22,11 +22,12 @@ } }, "test": { - "builder": "@angular-devkit/build-angular:karma", + "builder": "@angular/build:karma", "options": { "main": "projects/ui/src/test.ts", "tsConfig": "projects/ui/tsconfig.spec.json", - "karmaConfig": "projects/ui/karma.conf.js" + "karmaConfig": "projects/ui/karma.conf.js", + "codeCoverageExclude": ["projects/ui/src/lib/components/po-grid/**"] } }, "lint": { @@ -45,7 +46,7 @@ "prefix": "app", "architect": { "build": { - "builder": "@angular-devkit/build-angular:application", + "builder": "@angular/build:application", "options": { "outputPath": { "base": "dist/app" @@ -112,7 +113,7 @@ } }, "serve": { - "builder": "@angular-devkit/build-angular:dev-server", + "builder": "@angular/build:dev-server", "options": { "open": true, "host": "0.0.0.0", @@ -138,7 +139,7 @@ "sourceRoot": "projects/storage/src", "architect": { "build": { - "builder": "@angular-devkit/build-angular:ng-packagr", + "builder": "@angular/build:ng-packagr", "options": { "tsConfig": "projects/storage/tsconfig.lib.json", "project": "projects/storage/ng-package.json" @@ -150,7 +151,7 @@ } }, "test": { - "builder": "@angular-devkit/build-angular:karma", + "builder": "@angular/build:karma", "options": { "main": "projects/storage/src/test.ts", "tsConfig": "projects/storage/tsconfig.spec.json", @@ -171,7 +172,7 @@ "sourceRoot": "projects/sync/src", "architect": { "build": { - "builder": "@angular-devkit/build-angular:ng-packagr", + "builder": "@angular/build:ng-packagr", "options": { "tsConfig": "projects/sync/tsconfig.lib.json", "project": "projects/sync/ng-package.json" @@ -183,8 +184,9 @@ } }, "test": { - "builder": "@angular-devkit/build-angular:karma", + "builder": "@angular/build:karma", "options": { + "polyfills": ["zone.js", "zone.js/testing"], "main": "projects/sync/src/test.ts", "tsConfig": "projects/sync/tsconfig.spec.json", "karmaConfig": "projects/sync/karma.conf.js" @@ -205,7 +207,7 @@ "prefix": "po", "architect": { "build": { - "builder": "@angular-devkit/build-angular:ng-packagr", + "builder": "@angular/build:ng-packagr", "options": { "tsConfig": "projects/templates/tsconfig.lib.json", "project": "projects/templates/ng-package.json" @@ -217,8 +219,9 @@ } }, "test": { - "builder": "@angular-devkit/build-angular:karma", + "builder": "@angular/build:karma", "options": { + "polyfills": ["zone.js", "zone.js/testing"], "main": "projects/templates/src/test.ts", "tsConfig": "projects/templates/tsconfig.spec.json", "karmaConfig": "projects/templates/karma.conf.js" @@ -239,7 +242,7 @@ "prefix": "po", "architect": { "build": { - "builder": "@angular-devkit/build-angular:ng-packagr", + "builder": "@angular/build:ng-packagr", "options": { "tsConfig": "projects/code-editor/tsconfig.lib.json", "project": "projects/code-editor/ng-package.json" @@ -251,8 +254,9 @@ } }, "test": { - "builder": "@angular-devkit/build-angular:karma", + "builder": "@angular/build:karma", "options": { + "polyfills": ["zone.js", "zone.js/testing"], "main": "projects/code-editor/src/test.ts", "tsConfig": "projects/code-editor/tsconfig.spec.json", "karmaConfig": "projects/code-editor/karma.conf.js" @@ -274,7 +278,7 @@ "prefix": "app", "architect": { "build": { - "builder": "@angular-devkit/build-angular:application", + "builder": "@angular/build:application", "options": { "outputPath": { "base": "dist/portal" @@ -322,7 +326,8 @@ "sourceMap": true, "optimization": false, "namedChunks": true, - "browser": "projects/portal/src/main.ts" + "browser": "projects/portal/src/main.ts", + "externalDependencies": ["marked-katex-extension", "katex"] }, "configurations": { "production": { @@ -353,7 +358,7 @@ } }, "serve": { - "builder": "@angular-devkit/build-angular:dev-server", + "builder": "@angular/build:dev-server", "options": { "buildTarget": "portal:build" }, @@ -364,7 +369,7 @@ } }, "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", + "builder": "@angular/build:extract-i18n", "options": { "buildTarget": "portal:build" } diff --git a/docs/guides/browser-support.md b/docs/guides/browser-support.md index 360cf8a145..58019c68f0 100644 --- a/docs/guides/browser-support.md +++ b/docs/guides/browser-support.md @@ -15,24 +15,16 @@ Atualmente o PO está homologado para os seguintes navegadores: Chrome - versões mais recentes (latest) + 2 versões mais recentes Firefox - versões mais recentes (latest) + versão mais recente e versão de suporte estendido (ESR) Edge 2 últimas versões principais - - Safari - 2 últimas versões principais - - - IOS - 2 últimas versões principais - Android 2 últimas versões principais @@ -43,10 +35,10 @@ Atualmente o PO está homologado para os seguintes navegadores: > Nossa homologação tem como base os navegadores que o Angular suporta nativamente. Para saber mais, acesse o guia -[*Browser support*](https://angular.io/guide/browser-support) do Angular. +[*Browser support*](https://angular.dev/reference/versions#browser-support) do Angular. > Caso precise de algum *polyfill* em sua aplicação ou precisa de mais informação sobre como funciona um *polyfill* -acesse a documentação [*Browser support*](https://angular.io/guide/browser-support) do Angular. +acesse a documentação [*Browser support*](https://angular.dev/reference/versions#browser-support) do Angular. ## Executando a aplicação localmente diff --git a/docs/guides/deprecations.md b/docs/guides/deprecations.md index e6318ac55f..d56d183f32 100644 --- a/docs/guides/deprecations.md +++ b/docs/guides/deprecations.md @@ -25,11 +25,16 @@ A tabela a seguir lista todos os recursos depreciados, organizados pelo release - - PoNavbar + + PoNavbar Componente descontinuado v23 + + PoGauge + Componente descontinuado + v22 + PoTabs p-small @@ -71,6 +76,43 @@ A tabela a seguir lista todos os recursos depreciados, organizados pelo release Esta seção contém uma lista completa de todos os recursos obsoletos com detalhes para ajudá-lo a planejar sua migração. +### PoGauge + +
+
+ + + + + + + + + + + + + + + + + +
RecursoSubstituiçãoAnúncio da DepreciaçãoRemovido em
Componente po-gaugepo-chart (type=gauge)v19v22
+
+
+ +O componente `po-gauge` foi removido. Utilize o `po-chart` com `p-type="gauge"` como alternativa. + +Antes: +``` + +``` + +Depois: +``` + +``` + ### PoButton
@@ -222,6 +264,12 @@ Depois - Animalia Icons (atual) + + PoGauge + Componente descontinuado + PoChart (type=gauge) + v22 + PoNavbar Componente descontinuado diff --git a/docs/guides/development-flow.md b/docs/guides/development-flow.md index 7222cee2a4..e6d5e3ffd9 100644 --- a/docs/guides/development-flow.md +++ b/docs/guides/development-flow.md @@ -55,7 +55,7 @@ Este guia tem por objetivo definir as regras para criação de *Issues* relacion
  • Crie uma nova aplicação em Angular incluindo o componente e o comportamento reportado para nossa análise.
  • Adicione o mínimo de código necessário para reprodução do bug, facilitando assim a verificação da situação.
  • Publique a aplicação no GitHub e inclua o link ao criar a issue.
  • -
  • Pode-se também usar o Stackblitz para reproduzir o bug relatado na issue.
  • +
  • Pode-se também usar o Stackblitz para reproduzir o bug relatado na issue.
  • Certifique-se de incluir os passos para reprodução da issue. Estes passos devem ser claros e simples de seguir.
  • diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md index cac977a40b..4e2d43d6ad 100644 --- a/docs/guides/getting-started.md +++ b/docs/guides/getting-started.md @@ -3,16 +3,16 @@ ### Pré-requisitos -Para começar a utilizar o **PO UI** é pré-requisito ter o `Node.js` instalado (versão 20.11.x ou acima) e o seu gerenciador de pacote favorito na versão mais atual. Caso você ainda não tenha instalado o pacote `@angular/cli`, instale-o via `npm` ou `yarn`. +Para começar a utilizar o **PO UI** é pré-requisito ter o `Node.js` instalado (versão 24.22.1 e acima) e o seu gerenciador de pacote favorito na versão mais atual. Caso você ainda não tenha instalado o pacote `@angular/cli`, instale-o via `npm` ou `yarn`. Instalando com npm: ``` -npm i -g @angular/cli@21 +npm i -g @angular/cli@22 ``` Caso prefira instalar com o yarn: ``` -yarn global add @angular/cli@21 +yarn global add @angular/cli@22 ``` ### Passo 1 - Crie o seu primeiro projeto @@ -36,26 +36,24 @@ Veja abaixo a lista de dependências e as versões compatíveis, elas devem ser ```json "dependencies": { - "@angular/animations": "~21.2.17", - "@angular/common": "~21.2.17", - "@angular/compiler": "~21.2.17", - "@angular/core": "~21.2.17", - "@angular/forms": "~21.2.17", - "@angular/platform-browser": "~21.2.17", - "@angular/platform-browser-dynamic": "~21.2.17", - "@angular/router": "~21.2.17", + "@angular/common": "~22.2.1", + "@angular/compiler": "~22.2.1", + "@angular/core": "~22.2.1", + "@angular/forms": "~22.2.1", + "@angular/platform-browser": "~22.2.1", + "@angular/router": "~22.2.1", "rxjs": "~7.8.1", "tslib": "^2.6.2", "zone.js": "~0.15.0" ... }, "devDependencies": { - "@angular-devkit/build-angular": "~21.2.17", - "@angular-devkit/schematics": "~21.2.17", - "@angular/cli": "~21.2.17", - "@angular/compiler-cli": "~21.2.17", + "@angular-devkit/schematics": "~22.2.1", + "@angular/build": "~22.2.1", + "@angular/cli": "~22.2.1", + "@angular/compiler-cli": "~22.2.1", ... - "typescript": "~5.9.3" + "typescript": "~6.0.3" } ``` @@ -71,27 +69,11 @@ Caso prefira instalar com o yarn: yarn install ``` -### Observação para Angular 19+/21+ +### Observação para Angular 19+ -Em versões mais recentes do Angular, o projeto pode utilizar o novo build system baseado em **@angular/build**. Caso ocorra o erro: +Em versões mais recentes do Angular, o projeto utiliza, por padrão, novo build system baseado em **@angular/build**. -``` -Could not find the @angular/build:dev-server builder's package -``` - -Verifique se o pacote está declarado em **devDependencies**: - -``` -npm install -D @angular/build -``` - -ou - -``` -pnpm install -D @angular/build -``` - -Além disso, valide no arquivo angular.json se o builder está configurado para **@angular/build:***: +Verifique se o pacote está declarado em **devDependencies**. Além disso, valide no arquivo angular.json se o builder está configurado para **@angular/build:***: ``` "projects": { @@ -108,17 +90,16 @@ Além disso, valide no arquivo angular.json se o builder está configurado para } ``` -Se o **builder** for **@angular/build:***, o pacote **@angular/build** deve estar instalado. Caso esteja utilizando **@angular-devkit/build-angular**, o comportamento será o modelo tradicional. Para maiores informações veja na documentação oficial do [Angular](https://angular.dev/tools/cli/build-system-migration). -### Passo 2 - Adiconando o pacote @po-ui/ng-components +### Passo 2 - Adicionando o pacote @po-ui/ng-components Utilizando o comando `ng add` do [Angular CLI](https://cli.angular.io/), vamos adicionar o **Po** em seu projeto e o mesmo se encarregará de configurar o tema, instalar o pacote e importar o módulo do **Po**. Além de importar também o modulo **HttpClientModule**. Execute o comando abaixo na pasta raiz do seu projeto: ``` -ng add @po-ui/ng-components +ng add @po-ui/ng-components@next ``` > Ao executar o comando acima, será perguntado se deseja incluir uma estrutura inicial em seu projeto com menu lateral, página e toolbar, utilizando componentes do **Po**, **caso desejar, apenas informe: `Y`**. @@ -146,7 +127,7 @@ Agora é só abrir seu **editor / IDE** favorito e começar a trabalhar no seu p Caso você queira utilizar nossos componentes de templates, como o **[po-page-login](/documentation/po-page-login)**, **[po-modal-password-recovery](/documentation/po-modal-password-recovery)**, **[po-page-blocked-user](/documentation/po-page-blocked-user)**, **[po-page-dynamic-table](/documentation/po-page-dynamic-table)** entre outros, basta adicionar o pacote `@po-ui/ng-templates` executando o comando abaixo: ``` -ng add @po-ui/ng-templates +ng add @po-ui/ng-templates@next ``` > Ao executar este comando, será instalado o pacote `@po-ui/ng-templates` e configurado o `PoTemplatesModules` no `app.module` somente se sua aplicação for configurada com módulos. diff --git a/docs/guides/migration-poui.md b/docs/guides/migration-poui.md index 0cfa0cceae..0562c97e17 100644 --- a/docs/guides/migration-poui.md +++ b/docs/guides/migration-poui.md @@ -13,8 +13,7 @@ Antes de atualizar a versão do PO UI, é importante que você tenha atualizado o Angular que o PO UI está homologado, veja nossa [tabela de compatibilidade](https://github.com/po-ui/po-angular/wiki#vers%C3%B5es-angular-x-po-ui) em nosso Github Wiki. -> Caso o seu projeto esteja na versão Angular@20: -Realize a instalação do pacote Schematics do Angular para o nosso script de atualização funcionar corretamente: +> Caso o seu projeto não possua a dependência `@angular-devkit/schematics`, realize a instalação do pacote para o nosso script de atualização funcionar corretamente: ``` npm install @angular-devkit/schematics --save-dev @@ -29,7 +28,7 @@ ng update @angular/cli@ @angular/core@ --force Por exemplo: ``` -ng update @angular/cli@21 @angular/core@21 --force +ng update @angular/cli@22 @angular/core@22 --force ``` > Para realizar a migração completa e avaliar se não precisa fazer alguma alteração veja o [**Guia de Upgrade do Angular**](https://update.angular.io/). @@ -60,21 +59,11 @@ ng update @po-ui/ng-components@ --allow-dirty --force Por exemplo: ``` -ng update @po-ui/ng-components --allow-dirty --force +ng update @po-ui/ng-components@next --allow-dirty --force ``` > Caso ocorra um erro ao concluir o comando acima pode ser necessário fazer uma instalação limpa no projeto apagando a pasta `node_modules` e o arquivo `package-lock.json` e executando o comando `npm i --legacy-peer-deps` antes de realizar o `ng update`. -> Caso sua aplicação seja configurada com módulos, pode ser necessária a inclusão da seguinte `devDependencies`: - -```json - "devDependencies": { - ..., - "@angular-devkit/schematics": "~21.2.17", - ... - } -``` - O `ng update` ajudará nas alterações necessárias para seu projeto seguir atualizado, que são elas: - Caso houver *breaking changes*, serão realizados as alterações possíveis, mas fique atento ao [CHANGELOG](https://github.com/po-ui/po-angular/blob/master/CHANGELOG.md); @@ -103,13 +92,44 @@ ng update @po-ui/ng-sync@ --allow-dirty --force Por exemplo: ``` -ng update @po-ui/ng-sync --allow-dirty --force +ng update @po-ui/ng-sync@next --allow-dirty --force ``` O `ng update` ajudará nas alterações necessárias para seu projeto, que será atualizar as versões dos pacotes: - `@po-ui/ng-sync`; - `@po-ui/ng-storage`; +> Pode ocorrer o seguinte erro `TypeError: Failed to fetch dynamically imported module...`, sendo necessário adicionar ao arquivo `angular.json` as seguintes configurações: +> ```json +> { +> "projects": { +> "app": { +> ... +> "architect": { +> ... +> "build": { +> ... +> "options": { +> ... +> "polyfills": ["zone.js"], +> }, +> }, +> "serve": { +> ... +> "builder": "@angular/build:dev-server", +> "options": { +> ... +> "prebundle": { +> "exclude": ["@ionic/angular", "@ionic/core", "ionicons"] +> } +> } +> }, +> } +> } +> }, +> } +> ``` + ## Depreciações e Breaking Changes Possuimos uma documentação que lista as depreciações correntes e os *breaking changes* já realizados na biblioteca, diff --git a/docs/guides/releases.md b/docs/guides/releases.md index 815ef7d455..6b46443a0a 100644 --- a/docs/guides/releases.md +++ b/docs/guides/releases.md @@ -41,7 +41,12 @@ Consulte abaixo nossos guias de migração de versão para obter mais informaç - + + 22.0.0 + 22.0.0 + Migração do PO UI + + 21.0.0 21.0.0 Migração do PO UI diff --git a/docs/guides/schematics.md b/docs/guides/schematics.md index 2a1a3c2643..fa5ced785a 100644 --- a/docs/guides/schematics.md +++ b/docs/guides/schematics.md @@ -13,7 +13,7 @@ Caso esteja iniciando uma aplicação com PO, indica-se utilizar o comando abaix no qual será instalado o pacote `@po-ui/ng-components` e realizadas algumas configurações, que serão descritas em seguida: ``` -ng add @po-ui/ng-components +ng add @po-ui/ng-components@next ``` - Substitui o `AppComponent` com uma estrutura incial de um projeto, utilizando os components `po-page-default`, `po-toolbar`, e `po-menu`; @@ -26,127 +26,8 @@ Para a utilização de componentes de template o processo para inclusão é seme Primeiramente, deve-se utilizar o comando abaixo, no qual será instalado o pacote `@po-ui/ng-templates`: ``` -ng add @po-ui/ng-templates +ng add @po-ui/ng-templates@next ``` - Importa o módulo do PO; - Configura o tema do PO no projeto caso não possua; - -## Generate Schematics - -O `PO` vem com vários `schematics` que podem ser usados ​​para gerar componentes facilmente. - -Para gerar o componente, execute o comando abaixo, onde `package` é o pacote e ```schematic-name``` o componente que deseja: - -``` -ng generate : -``` - -> A lista de opções disponíveis que o CLI oferece para o *ng generate* é vista acrescentando `--help` no comando. - -### PO UI Components - -``` -ng generate @po-ui/ng-components: -``` - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    NomeDescrição
    po-page-list - - Componente que deve ser utilizado como o container principal para as telas de listagem de dados, podendo ser apresentado como lista ou tabela. -
    - po-page-default - Componente que deve ser utilizado como o container principal para as telas sem um template definido.
    po-page-edit - Componente que deve ser utilizado como container principal para tela de edição ou adição de um registro.
    po-page-detail - Componente que deve ser utilizado como container principal para a tela de detalhamento de um registro.
    -
    -
    - -### Po UI Templates -``` -ng generate @po-ui/ng-templates: -``` - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NomeDescrição
    po-page-dynamic-table - Página que exibe uma lista de registros em uma tabela baseado em uma lista de fields, o mesmo também suporta metadados conforme especificado na documentação. -
    - po-page-dynamic-detail - Página que serve para exibir registros em detalhes, o mesmo também suporta metadados conforme especificado na documentação. -
    po-page-dynamic-editPágina que pode servir para editar ou criar novos registros, o mesmo também suporta metadados conforme especificado na documentação. -
    po-page-dynamic-searchComponente com as ações de pesquisa já definidas, bastando que o desenvolvedor implemente apenas a chamada para as APIs e exiba as informações. -
    po-page-job-schedulerPágina que serve para criação e atualização de agendamentos da execução de processos (Job Scheduler), como por exemplo: a geração da folha de pagamento dos funcionários. Para utilizá-la, basta informar o serviço (endpoint) para consumo, sem a necessidade de criar componentes e tratamentos dos dados. -
    po-page-loginPágina utilizada como template para tela de login. Com ele é possível definirmos valores para usuário, senha e definir ações para recuperação de senha e gravação de dados do usuário. Também é possível inserir uma imagem em conjunto com um texto de destaque. -
    po-page-change-passwordPágina utilizada como template para tela de cadastro ou alteração de senha. -
    po-page-blocked-userPágina utilizada como template para tela de bloqueio de usuário. -
    -
    -
    diff --git a/docs/guides/sync-get-started.md b/docs/guides/sync-get-started.md index 6499a14c51..8e79ae9c26 100644 --- a/docs/guides/sync-get-started.md +++ b/docs/guides/sync-get-started.md @@ -9,13 +9,13 @@ Para maiores detalhes sobre os serviços e métodos utilizados neste tutorial, c ### Pré-requisitos - [Node.js e NPM](https://nodejs.org/en/) -- [Angular CLI](https://cli.angular.io/) (~21.2.17): +- [Angular CLI](https://cli.angular.io/) (~22.2.1): - ```shell - npm install -g @angular/cli@21 + npm install -g @angular/cli@22 ``` -- [Ionic](https://ionicframework.com/docs/cli/) (^7.2.0): +- [Ionic](https://ionicframework.com/docs/cli/): - ```shell - npm install -g @ionic/cli@7 + npm install -g @ionic/cli ``` @@ -23,8 +23,6 @@ Para maiores detalhes sobre os serviços e métodos utilizados neste tutorial, c ### Passo 1 - Criando o aplicativo -> Atualmente, a Ionic CLI cria novos projetos utilizando Angular 20 como versão base, independentemente da versão final desejada do Angular. - Para a aplicação de exemplo usaremos o template *blank* do Ionic. Para isso, execute o seguinte comando: ```shell @@ -35,34 +33,24 @@ Caso surja a questão relacionada ao framework desejado, opte por `Angular`. ### Passo 2 - Instalando as dependências -É necessário realizar alguns ajustes de compatibilidade do PO para o projeto criado. +É necessário realizar alguns ajustes de compatibilidade do PO UI para o projeto criado. Navegue até a pasta do aplicativo: ```shell cd po-sync-getting-started ``` -Antes de instalar o po-sync, é necessário atualizar o projeto para o Angular 21, garantindo compatibilidade com o PO UI. - -```shell -ng update @angular/core@21 @angular/cli@21 -``` - -> Esse passo é necessário porque o projeto foi inicialmente criado com Angular 20, e o upgrade garante compatibilidade com as versões utilizadas pelo PO UI. - Veja abaixo a lista de dependências e as versões compatíveis, elas devem ser conferidas e se necessário, ajustadas no seu projeto. ```json ... "dependencies": { - "@angular/animations": "~21.2.17", - "@angular/common": "~21.2.17", - "@angular/compiler": "~21.2.17", - "@angular/core": "~21.2.17", - "@angular/forms": "~21.2.17", - "@angular/platform-browser": "~21.2.17", - "@angular/platform-browser-dynamic": "~21.2.17", - "@angular/router": "~21.2.17", + "@angular/common": "~22.2.1", + "@angular/compiler": "~22.2.1", + "@angular/core": "~22.2.1", + "@angular/forms": "~22.2.1", + "@angular/platform-browser": "~22.2.1", + "@angular/router": "~22.2.1", "@capacitor/app": "8.0.0", "@capacitor/core": "8.0.1", "@capacitor/haptics": "8.0.0", @@ -76,22 +64,31 @@ Veja abaixo a lista de dependências e as versões compatíveis, elas devem ser "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/schematics": "~21.2.17", - ... - "@angular/cli": "~21.2.17", - "@angular/compiler-cli": "~21.2.17", - "@angular/language-service": "~21.2.17", + "@angular-devkit/schematics": "~22.2.1", + "@angular/build": "~22.2.1", + "@angular/cli": "~22.2.1", + "@angular/compiler-cli": "~22.2.1", + "@angular/language-service": "~22.2.1", "@capacitor/cli": "8.0.1", "@ionic/angular-toolkit": "^12.0.0", ... - "typescript": "~5.9.3" + "typescript": "~6.0.3" }, ... ``` +> **Nota para projetos com módulos (NgModule)**: A CLI do Ionic pode gerar projetos com o arquivo `src/main.ts` utilizando o `platformBrowserDynamic`. Caso isso aconteça, será necessário adicionar o pacote `@angular/platform-browser-dynamic` no arquivo `package.json` (dentro de `dependencies`), juntamente com as outras dependências listadas acima: +> ```json +> "dependencies": { +> ... +> "@angular/platform-browser-dynamic": "~22.2.1", +> ... +> } +> ``` + > Após configurar seu arquivo, certifique-se de salvar as alterações realizadas. -Execute o seguinte comando para instalar as dependências: +Realize a limpeza do arquivo `package-lock.json` e da pasta `node_modules/`, para então executar o seguinte comando para instalar as dependências: ```shell npm install @@ -102,14 +99,14 @@ npm install Para instalar o `po-sync` no aplicativo execute o seguinte comando: ```shell -ng add @po-ui/ng-sync +ng add @po-ui/ng-sync@next ``` ### Passo 4 - Utilizando o po-sync #### Passo 4.1 (NgModule) - Importando o `po-sync` e o `po-storage` -No arquivo `src/app/app.module.ts`, adicione a importação dos módulos do `po-storage` e do `po-sync`: +No arquivo `src/app/app.module.ts`, adicione a importação dos módulos do `po-storage` e do `po-sync`: ```typescript import { NgModule } from '@angular/core'; @@ -145,7 +142,7 @@ export class AppModule {} #### Passo 4.1 (Standalone) - Importando o `po-sync` e o `po-storage` -No arquivo `src/main.ts`, adicione a importação dos módulos do `po-storage` e do `po-sync`: +No arquivo `src/main.ts`, avalie se foi feita a importação dos módulos do `po-storage` e do `po-sync`: ```typescript import { bootstrapApplication } from '@angular/platform-browser'; @@ -201,7 +198,7 @@ Após ter o seu primeiro *schema* criado, configure o seu aplicativo utilizando Substitua o conteúdo do arquivo pelo conteúdo abaixo: ```typescript -import { Component } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { Capacitor } from '@capacitor/core'; import { Platform } from '@ionic/angular'; import { SplashScreen } from '@capacitor/splash-screen'; @@ -215,8 +212,11 @@ import { conferenceSchema } from './home/conference-schema.constants'; styleUrls: ['app.component.scss'], standalone: false }) -export class AppComponent { - constructor(private platform: Platform, private poSync: PoSyncService) { +export class AppComponent implements OnInit { + private readonly platform = inject(Platform); + private readonly poSync = inject(PoSyncService); + + ngOnInit() { this.initializeApp(); } @@ -249,7 +249,7 @@ Após utilizar o método `PoSyncService.prepare()`, a aplicação estará pronta Substitua o conteúdo do arquivo pelo conteúdo abaixo: ```typescript -import { Component } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone'; import { Capacitor } from '@capacitor/core'; import { Platform } from '@ionic/angular'; @@ -264,10 +264,11 @@ import { conferenceSchema } from './home/conference-schema.constants'; templateUrl: 'app.component.html', imports: [IonApp, IonRouterOutlet], }) -export class AppComponent { - constructor( - private platform: Platform, private poSync: PoSyncService - ) { +export class AppComponent implements OnInit { + private readonly platform = inject(Platform); + private readonly poSync = inject(PoSyncService); + + ngOnInit() { this.initializeApp(); } @@ -297,10 +298,35 @@ export class AppComponent { ### Passo 6 (NgModule) - Acessando os dados +Caso o projeto tenha sido gerado em uma versão anterior a 9.x do `@ionic/angular`, no arquivo `po-sync-getting-started/src/app/home/home.module.ts`, atualize a importação do `IonicModule` para utilizar o caminho `import { IonicModule } from '@ionic/angular';`: + +```typescript +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { IonicModule } from '@ionic/angular'; +import { FormsModule } from '@angular/forms'; +import { HomePage } from './home.page'; + +import { HomePageRoutingModule } from './home-routing.module'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + HomePageRoutingModule + ], + declarations: [HomePage] +}) +export class HomePageModule {} +``` + +> **Nota sobre importação do `IonicModule`**: As versões anteriores à 9.x do `@ionic/angular` não possuem o export `lazy`, devendo ser feito o import de `@ionic/angular`. A partir da versão 9.x, o import de `@ionic/angular/lazy` funciona normalmente (sendo o padrão da CLI do ionic para projetos standalone). + Localize o arquivo `src/app/home/home.page.ts` e faça as seguintes alterações: ```typescript -import { Component } from '@angular/core'; +import { Component, inject, signal } from '@angular/core'; import { PoSyncService } from '@po-ui/ng-sync'; @@ -311,21 +337,21 @@ import { PoSyncService } from '@po-ui/ng-sync'; standalone: false }) export class HomePage { + private readonly poSync = inject(PoSyncService); - conference: any; + readonly conference = signal(null); - constructor(private poSync: PoSyncService) { + constructor() { this.poSync.onSync().subscribe(() => this.loadHomePage()); } async loadHomePage() { - this.conference = await this.poSync.getModel('conference').findOne().exec(); + this.conference.set(await this.poSync.getModel('conference').findOne().exec()); } clear() { - this.conference = null; + this.conference.set(null); } - } ``` @@ -336,31 +362,38 @@ No construtor, foi realizado uma inscrição no método `PoSyncService.onSync()` Localize o arquivo `src/app/home/home.page.ts` e faça as seguintes alterações: ```typescript -import { Component } from '@angular/core'; -import { NgIf } from '@angular/common'; - -import { IonicModule } from '@ionic/angular'; +import { Component, inject, signal } from '@angular/core'; + +import { + IonContent, + IonButton, + IonCard, + IonCardContent, + IonCardTitle +} from '@ionic/angular/standalone'; import { PoSyncService } from '@po-ui/ng-sync'; @Component({ selector: 'app-home', templateUrl: 'home.page.html', styleUrls: ['home.page.scss'], - imports: [IonicModule, NgIf], + imports: [IonContent, IonButton, IonCard, IonCardContent, IonCardTitle], }) export class HomePage { - conference: any; + private readonly poSync = inject(PoSyncService); + + readonly conference = signal(null); - constructor(private poSync: PoSyncService) { + constructor() { this.poSync.onSync().subscribe(() => this.loadHomePage()); } async loadHomePage() { - this.conference = await this.poSync.getModel('conference').findOne().exec(); + this.conference.set(await this.poSync.getModel('conference').findOne().exec()); } clear() { - this.conference = null; + this.conference.set(null); } } @@ -371,18 +404,20 @@ export class HomePage { No arquivo `src/app/home/home.page.html` crie a seguinte estrutura: ```html - Buscar informações - Apagar informações - - - - - {{ conference.title }} - -

    {{ conference.description }}

    -

    {{ conference.location }}

    -
    -
    + Buscar informações + Apagar informações + + @if (conference(); as conference) { + + + + {{ conference.title }} + +

    {{ conference.description }}

    +

    {{ conference.location }}

    +
    +
    + }
    ``` @@ -390,7 +425,38 @@ No arquivo `src/app/home/home.page.html` crie a seguinte estrutura: Execute o comando `ionic serve` e verifique o funcionamento do aplicativo Ionic com `po-sync`. -> Pode ocorrer o seguinte erro `TS2320: Interface 'HTMLIonIconElement' cannot simultaneously extend types 'IonIcon' and 'HTMLStencilElement'` por conta da versão do TypeScript (5.2.x) conforme esta [issue](https://github.com/ionic-team/ionicons/issues/1011), neste caso adicione no arquivo **tsconfig.json** `"skipLibCheck": true`. +> Pode ocorrer o seguinte erro `TypeError: Failed to fetch dynamically imported module...`, sendo necessário adicionar ao arquivo `angular.json` as seguintes configurações: +> ```json +> { +> "projects": { +> "app": { +> ... +> "architect": { +> ... +> "build": { +> ... +> "options": { +> ... +> "polyfills": ["zone.js"], +> }, +> }, +> "serve": { +> ... +> "builder": "@angular/build:dev-server", +> "options": { +> ... +> "prebundle": { +> "exclude": ["@ionic/angular", "@ionic/core", "ionicons"] +> } +> } +> }, +> } +> } +> }, +> } +> ``` + +> Pode ocorrer o seguinte erro `TS2320: Interface 'HTMLIonIconElement' cannot simultaneously extend types 'IonIcon' and 'HTMLStencilElement'` por conta da versão do TypeScript conforme esta [issue](https://github.com/ionic-team/ionicons/issues/1011), neste caso adicione no arquivo **tsconfig.json** `"skipLibCheck": true`. > Ao executar um projeto standalone, pode ocorrer o seguinte erro: `[ERROR] Invalid project type: angular-standalone (project config: ./ionic.config.json).`. Para corrigir, edite o arquivo `ionic.config.json` e ajuste a propriedade `type` para o valor `angular`. diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000000..a3aaffd3ed --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,248 @@ +// Flat config (ESLint 9 / angular-eslint 22 / typescript-eslint 8). +// +// Migrado a partir dos arquivos .eslintrc.json legados. As regras foram +// preservadas conforme o modelo anterior. Os presets "recommended" do +// @angular-eslint e do @typescript-eslint sao carregados via os pacotes +// umbrella (angular-eslint / typescript-eslint), ja que os pacotes granulares +// da v22 nao expoem os shareable configs no formato eslintrc usado pelo +// FlatCompat. +import tseslint from 'typescript-eslint'; +import angular from 'angular-eslint'; +import sonarjs from 'eslint-plugin-sonarjs'; + +export default tseslint.config( + { + ignores: [ + 'dist/**', + 'node_modules/**', + '.angular/**', + 'coverage/**', + 'out-tsc/**', + // Fixtures de teste manual da migracao do po-gauge: arquivos de entrada + // propositalmente crafted (usos de po-gauge, @ts-ignore, etc.) que servem + // de material para a schematic transformar; nao devem ser lintados. + 'projects/ui/schematics/ng-update/v22/gauge-manual-test/**' + ] + }, + { + // O modelo legado (.eslintrc.json) nao reportava diretivas eslint-disable + // nao utilizadas; mantem o mesmo comportamento. + linterOptions: { + reportUnusedDisableDirectives: 'off' + } + }, + { + files: ['**/*.ts'], + extends: [ + // Baseline "recommended" equivalente ao modelo legado + // (plugin:@typescript-eslint/recommended + plugin:@angular-eslint/recommended). + ...tseslint.configs.recommended, + ...angular.configs.tsRecommended + ], + // Habilita o processamento de templates inline dos componentes + // (equivalente a plugin:@angular-eslint/template/process-inline-templates). + processor: angular.processInlineTemplates, + plugins: { + sonarjs + }, + languageOptions: { + parserOptions: { + // Usa o Project Service do typescript-eslint (v8+) em vez de listar + // manualmente todos os tsconfigs. O Project Service resolve o tsconfig + // correto por arquivo sob demanda e reaproveita Programs, reduzindo + // drasticamente o consumo de memoria (evita OOM ao manter 14 Programs + // TypeScript vivos ao mesmo tempo). + projectService: true, + tsconfigRootDir: import.meta.dirname + } + }, + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-this-alias': 'off', + '@typescript-eslint/no-unused-vars': 'off', + '@typescript-eslint/no-array-constructor': 'off', + '@angular-eslint/component-selector': [ + 'error', + { type: ['element', 'attribute'], prefix: '', style: 'kebab-case' } + ], + '@angular-eslint/directive-class-suffix': 'off', + '@angular-eslint/directive-selector': ['error', { type: 'attribute', prefix: '', style: 'kebab-case' }], + '@angular-eslint/no-input-rename': 'off', + '@angular-eslint/no-output-rename': 'off', + '@angular-eslint/no-output-native': 'off', + '@angular-eslint/no-output-on-prefix': 'off', + '@angular-eslint/no-conflicting-lifecycle': 'off', + '@typescript-eslint/array-type': ['error', { default: 'generic' }], + '@typescript-eslint/await-thenable': 'error', + '@typescript-eslint/consistent-type-assertions': 'off', + '@typescript-eslint/consistent-type-definitions': 'error', + '@typescript-eslint/dot-notation': 'off', + '@typescript-eslint/explicit-member-accessibility': ['off', { accessibility: 'explicit' }], + '@typescript-eslint/no-empty-interface': 'off', + '@typescript-eslint/no-for-in-array': 'error', + '@typescript-eslint/no-inferrable-types': ['off', { ignoreParameters: true }], + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-unnecessary-type-assertion': 'error', + '@typescript-eslint/no-unused-expressions': 'off', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/prefer-for-of': 'off', + '@typescript-eslint/require-array-sort-compare': ['error', { ignoreStringArrays: true }], + camelcase: 'off', + '@typescript-eslint/naming-convention': [ + 'error', + { selector: 'default', format: ['camelCase'] }, + { selector: 'variable', format: ['camelCase', 'UPPER_CASE', 'snake_case', 'PascalCase'], leadingUnderscore: 'allow' }, + { selector: 'import', format: ['camelCase', 'PascalCase'], leadingUnderscore: 'allow' }, + { selector: 'classProperty', format: ['camelCase', 'UPPER_CASE', 'snake_case', 'PascalCase'], leadingUnderscore: 'allow' }, + { selector: 'parameter', format: ['camelCase'], leadingUnderscore: 'allow' }, + { selector: 'memberLike', modifiers: ['private'], format: ['camelCase'], leadingUnderscore: 'allow' }, + { selector: 'typeLike', format: ['PascalCase', 'camelCase'] }, + { selector: 'enumMember', format: ['UPPER_CASE', 'camelCase', 'PascalCase'], leadingUnderscore: 'allow' }, + { selector: ['objectLiteralMethod'], format: ['PascalCase', 'camelCase', 'snake_case', 'UPPER_CASE'], leadingUnderscore: 'allow' }, + { selector: ['objectLiteralProperty'], format: null, leadingUnderscore: 'allow' }, + { selector: 'function', format: ['PascalCase', 'camelCase'], leadingUnderscore: 'allow' } + ], + '@typescript-eslint/member-ordering': ['error', { default: ['signature', 'field', 'constructor', 'method'] }], + 'arrow-parens': ['off', 'always'], + 'arrow-body-style': ['error', 'as-needed'], + 'brace-style': ['off', 'off'], + 'default-case-last': 'error', + 'dot-notation': 'off', + 'eol-last': 'off', + 'id-blacklist': 'off', + 'id-match': 'off', + indent: 'off', + 'linebreak-style': 'off', + 'max-len': 'off', + 'max-lines-per-function': ['off', { max: 200 }], + 'max-params': ['error', { max: 8 }], + 'new-parens': 'off', + 'newline-per-chained-call': 'off', + 'no-empty-function': 'off', + 'no-empty-pattern': 'off', + 'no-extra-parens': 'off', + 'no-extra-semi': 'error', + 'no-irregular-whitespace': 'off', + 'no-multi-str': 'error', + 'no-self-assign': 'error', + 'no-shadow': 'off', + 'no-trailing-spaces': 'off', + 'no-underscore-dangle': 'off', + // No modelo legado, o preset @typescript-eslint/recommended desligava a + // regra core `no-unused-expressions` (em favor da versao TS, que estava + // `off`). O efeito liquido era nenhuma das duas ativa; mantido igual. + 'no-unused-expressions': 'off', + '@typescript-eslint/no-unused-expressions': 'off', + 'no-use-before-define': 'off', + 'object-shorthand': 'off', + 'padded-blocks': ['off', { blocks: 'never' }, { allowSingleLineBlocks: true }], + 'quote-props': 'off', + semi: 'off', + 'sonarjs/cognitive-complexity': 'off', + 'sonarjs/max-switch-cases': 'error', + 'sonarjs/no-all-duplicated-branches': 'error', + 'sonarjs/no-collapsible-if': 'error', + 'sonarjs/no-collection-size-mischeck': 'error', + 'sonarjs/no-duplicate-string': 'off', + 'sonarjs/no-duplicated-branches': 'off', + 'sonarjs/no-element-overwrite': 'error', + 'sonarjs/no-identical-conditions': 'error', + 'sonarjs/no-identical-expressions': 'error', + 'sonarjs/no-identical-functions': 'off', + 'sonarjs/no-inverted-boolean-check': 'error', + 'sonarjs/no-redundant-boolean': 'error', + 'sonarjs/no-redundant-jump': 'error', + 'sonarjs/no-same-line-conditional': 'error', + 'sonarjs/no-small-switch': 'error', + 'sonarjs/no-unused-collection': 'error', + 'sonarjs/no-use-of-empty-return-value': 'error', + 'sonarjs/no-useless-catch': 'error', + 'sonarjs/prefer-immediate-return': 'error', + 'space-before-function-paren': 'off', + 'space-in-parens': ['off', 'never'], + '@angular-eslint/prefer-standalone': 'off', + '@typescript-eslint/no-unsafe-function-type': 'off', + '@typescript-eslint/no-empty-object-type': 'off', + '@angular-eslint/prefer-inject': 'off', + // Nao fazia parte do preset "recommended" legado do @angular-eslint (v21); + // o preset da v22 passou a inclui-la. Desligada para preservar o + // comportamento anterior. + '@angular-eslint/prefer-on-push-component-change-detection': 'off' + } + }, + // Arquivos de schematics sao compilados com tsconfig.schematics.json + // (strictNullChecks: true). Type-checa-los com o mesmo tsconfig evita que + // regras type-aware (ex.: no-unnecessary-type-assertion) divirjam do build: + // sem isso, o lint usa o tsconfig.lib.json (strict: false) e considera + // desnecessarios os `!`/casts que o build strict realmente exige. + // Com o Project Service habilitado no bloco base, a associacao arquivo -> + // tsconfig e resolvida automaticamente (inclusive para os tsconfigs de + // schematics). Por isso nao e mais necessario declarar `project` aqui; fazer + // isso gera erro "Enabling 'project' does nothing when 'projectService' is + // enabled". Os blocos abaixo permanecem apenas como marcadores/documentacao + // do escopo, sem override de parserOptions. + + // --------------------------------------------------------------------------- + // Overrides por projeto (equivalentes aos .eslintrc.json de cada projeto). + // Aplicados apos o bloco compartilhado; em flat config, blocos posteriores + // sobrescrevem os anteriores para os arquivos correspondentes. + // --------------------------------------------------------------------------- + + // projects/ui: directive-selector como "warn"; specs e alguns arquivos + // excluidos das regras TS; regras extras desligadas. + { + ignores: ['projects/ui/**/util-expect.spec.ts'] + }, + { + files: ['projects/ui/**/*.ts'], + ignores: [ + 'projects/ui/**/test.ts', + 'projects/ui/**/*.spec.ts', + 'projects/ui/**/*.po.ts', + 'projects/ui/src/lib/util-test/util-expect.spec.ts' + ], + rules: { + '@angular-eslint/directive-selector': ['warn', { type: 'attribute', prefix: '', style: 'kebab-case' }], + // Nota: @angular-eslint/no-host-metadata-property foi removida na v22 e + // por isso nao e mais referenciada (era `off` no modelo legado, sem efeito). + 'prefer-spread': 'off' + } + }, + + // projects/sync: selectors com prefixo "lib". + { + files: ['projects/sync/**/*.ts'], + rules: { + '@angular-eslint/component-selector': ['error', { type: 'element', prefix: 'lib', style: 'kebab-case' }], + '@angular-eslint/directive-selector': ['error', { type: 'attribute', prefix: 'lib', style: 'camelCase' }] + } + }, + + // projects/portal: selectors com prefixo "app"; pastas de docs/samples ignoradas. + { + ignores: ['projects/portal/docs/**/*', 'projects/portal/src/app/documentation/samples/**/*'] + }, + { + files: ['projects/portal/**/*.ts'], + rules: { + '@angular-eslint/component-selector': ['error', { type: 'element', prefix: 'app', style: 'kebab-case' }], + '@angular-eslint/directive-selector': ['error', { type: 'attribute', prefix: 'app', style: 'camelCase' }] + } + }, + + // projects/app: no-extra-parens habilitado como erro. + { + files: ['projects/app/**/*.ts'], + rules: { + 'no-extra-parens': 'error' + } + }, + + { + files: ['**/*.html'], + extends: [...angular.configs.templateRecommended], + rules: { + '@angular-eslint/template/prefer-control-flow': 'warn' + } + } +); diff --git a/package.json b/package.json index 93914b08d4..daab11d93b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "po-ui-sources", - "version": "21.35.0", + "version": "22.0.0-rc.0", "description": "PO UI", "homepage": "https://po-ui.io", "license": "MIT", @@ -27,7 +27,7 @@ "test:sync:schematics": "gulp build:schematics --lib sync && jasmine \"dist/ng-sync/schematics/**/*.spec.js\"", "test:sync:browse": "ng test sync --code-coverage --browsers=Chrome --source-map", "test:ui": "ng test ui --watch=false --code-coverage --browsers=ChromeHeadless --source-map", - "test:ui:schematics": "gulp build:schematics --lib ui && jasmine \"./dist/ng-components/schematics/**/*.spec.js\"", + "test:ui:schematics": "gulp clean:schematics --lib ui && gulp build:schematics:lib && gulp build:schematics:spec --lib ui && jasmine \"./dist/ng-components/schematics/**/*.spec.js\"", "test:ui:browse": "ng test ui --code-coverage --browsers=Chrome --source-map", "test:templates": "ng test templates --watch=false --code-coverage --browsers=ChromeHeadless --source-map", "test:templates:schematics": "gulp build:schematics --lib templates && jasmine \"dist/ng-templates/schematics/**/*.spec.js\"", @@ -68,18 +68,16 @@ }, "private": true, "dependencies": { - "@angular/animations": "~21.2.17", - "@angular/cdk": "~21.2.14", - "@angular/common": "~21.2.17", - "@angular/compiler": "~21.2.17", - "@angular/core": "~21.2.17", - "@angular/forms": "~21.2.17", - "@angular/platform-browser": "~21.2.17", - "@angular/platform-browser-dynamic": "~21.2.17", - "@angular/router": "~21.2.17", + "@angular/cdk": "~22.2.1", + "@angular/common": "~22.2.1", + "@angular/compiler": "~22.2.1", + "@angular/core": "~22.2.1", + "@angular/forms": "~22.2.1", + "@angular/platform-browser": "~22.2.1", + "@angular/router": "~22.2.1", "@capacitor/core": "5.7.2", "@capacitor/network": "^5.0.7", - "@po-ui/style": "21.35.0", + "@po-ui/style": "22.0.0-rc.0", "custom-idle-queue": "4.0.0", "driver.js": "~1.4.0", "echarts": "^6.1.0", @@ -92,19 +90,21 @@ "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "~21.2.17", - "@angular-eslint/builder": "^21.1.0", - "@angular-eslint/eslint-plugin": "^21.1.0", - "@angular-eslint/eslint-plugin-template": "^21.1.0", - "@angular-eslint/schematics": "^21.1.0", - "@angular-eslint/template-parser": "^21.1.0", - "@angular/cli": "~21.2.17", - "@angular/compiler-cli": "~21.2.17", - "@angular/language-service": "~21.2.17", + "@angular-eslint/builder": "^22.0.0", + "@angular-eslint/eslint-plugin": "^22.0.0", + "@angular-eslint/eslint-plugin-template": "^22.0.0", + "@angular-eslint/schematics": "^22.0.0", + "@angular-eslint/template-parser": "^22.0.0", + "@angular/build": "~22.2.1", + "@angular/cli": "~22.2.1", + "@angular/compiler-cli": "~22.2.1", + "@angular/language-service": "~22.2.1", "@animaliads/animalia-icon": "^1.1.0", "@commitlint/cli": "^18.4.3", "@commitlint/config-angular": "^18.4.3", - "@po-ui/ng-schematics": "^18.0.0", + "@eslint/eslintrc": "^3.3.7", + "@eslint/js": "^9.39.5", + "@po-ui/ng-schematics": "file:dist/ng-schematics", "@types/jasmine": "~5.1.4", "@types/jasminewd2": "~2.0.13", "@types/node": "25.0.1", @@ -112,6 +112,7 @@ "@types/systemjs": "^6.13.5", "@typescript-eslint/eslint-plugin": "^8.33.1", "@typescript-eslint/parser": "^8.33.1", + "angular-eslint": "^22.2.0", "capitalize": "^2.0.4", "colors": "1.4.0", "core-js": "3.33.3", @@ -129,6 +130,7 @@ "gulp-tap": "^2.0.0", "highlight.js": "^11.9.0", "husky": "^8.0.0", + "istanbul-lib-instrument": "^6.0.3", "jasmine": "2.8.0", "jasmine-core": "5.1.1", "jasmine-spec-reporter": "7.0.0", @@ -139,16 +141,16 @@ "karma-jasmine-html-reporter": "2.1.0", "lint-staged": "^15.1.0", "mkdirp": "3.0.1", - "ng-packagr": "~21.2.5", - "ngx-markdown": "^21.0.1", - "prettier": "^3.9.4", + "ng-packagr": "~22.0.0", + "ngx-markdown": "^22.0.0", + "prettier": "^3.1.0", "rollup": "4.60.1", "run-sequence": "^2.2.1", "rxjs-compat": "~6.6.7", "standard-version": "^9.5.0", "ts-node": "~10.9.1", "typemoq": "^2.1.0", - "typescript": "~5.9.3", + "typescript": "~6.0.3", "validate.js": "file:libs/validate.js-v0.13.2.tgz", "yargs": "^17.7.2" }, diff --git a/projects/app/.eslintrc.json b/projects/app/.eslintrc.json deleted file mode 100644 index 410dd78e8e..0000000000 --- a/projects/app/.eslintrc.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "extends": "../../.eslintrc.json", - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": ["projects/app/tsconfig.app.json", "projects/app/tsconfig.spec.json"], - "createDefaultProgram": true - }, - "plugins": ["sonarjs"], - "rules": { - "@angular-eslint/component-selector": [ - "error", - { - "type": ["element", "attribute"], - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/directive-class-suffix": "off", - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/no-input-rename": "off", - "@angular-eslint/no-output-rename": "off", - "@typescript-eslint/array-type": [ - "error", - { - "default": "generic" - } - ], - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "off", - { - "types": { - "String": { - "message": "Use string instead", - "fixWith": "string" - }, - "Boolean": { - "message": "Use boolean instead", - "fixWith": "boolean" - }, - "Number": { - "message": "Use number instead", - "fixWith": "number" - } - } - } - ], - "@typescript-eslint/consistent-type-assertions": "off", - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/dot-notation": "off", - "@typescript-eslint/explicit-member-accessibility": [ - "off", - { - "accessibility": "explicit" - } - ], - "@typescript-eslint/member-delimiter-style": [ - "off", - { - "multiline": { - "delimiter": "none", - "requireLast": true - }, - "singleline": { - "delimiter": "semi", - "requireLast": false - } - } - ], - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": [ - "off", - { - "ignoreParameters": true - } - ], - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "@typescript-eslint/no-var-requires": "error", - "@typescript-eslint/prefer-for-of": "off", - "@typescript-eslint/quotes": [ - "off", - "single", - { - "allowTemplateLiterals": true - } - ], - "@typescript-eslint/require-array-sort-compare": [ - "error", - { - "ignoreStringArrays": true - } - ], - "@typescript-eslint/semi": ["off", null], - "@typescript-eslint/type-annotation-spacing": "off", - "arrow-parens": ["off", "always"], - "brace-style": ["off", "off"], - "default-case-last": "error", - "dot-notation": "off", - "eol-last": "off", - "id-blacklist": "off", - "id-match": "off", - "indent": "off", - "linebreak-style": "off", - "max-len": "off", - "max-lines-per-function": [ - "off", - { - "max": 200 - } - ], - "max-params": [ - "error", - { - "max": 8 - } - ], - "new-parens": "off", - "newline-per-chained-call": "off", - "no-empty-function": "off", - "no-empty-pattern": "off", - "no-extra-parens": "error", - "no-extra-semi": "error", - "no-irregular-whitespace": "off", - "no-multi-str": "error", - "no-self-assign": "error", - "no-shadow": "off", - "no-trailing-spaces": "off", - "no-underscore-dangle": "off", - "no-unused-expressions": "error", - "no-use-before-define": "off", - "object-shorthand": "off", - "padded-blocks": [ - "off", - { - "blocks": "never" - }, - { - "allowSingleLineBlocks": true - } - ], - "prefer-arrow/prefer-arrow-functions": "off", - "quote-props": "off", - "semi": "off", - "sonarjs/cognitive-complexity": "off", - "sonarjs/max-switch-cases": "error", - "sonarjs/no-all-duplicated-branches": "error", - "sonarjs/no-collapsible-if": "error", - "sonarjs/no-collection-size-mischeck": "error", - "sonarjs/no-duplicate-string": "off", - "sonarjs/no-duplicated-branches": "off", - "sonarjs/no-element-overwrite": "error", - "sonarjs/no-identical-conditions": "error", - "sonarjs/no-identical-expressions": "error", - "sonarjs/no-identical-functions": "off", - "sonarjs/no-inverted-boolean-check": "error", - "sonarjs/no-one-iteration-loop": "off", - "sonarjs/no-redundant-boolean": "error", - "sonarjs/no-redundant-jump": "error", - "sonarjs/no-same-line-conditional": "error", - "sonarjs/no-small-switch": "error", - "sonarjs/no-unused-collection": "error", - "sonarjs/no-use-of-empty-return-value": "error", - "sonarjs/no-useless-catch": "error", - "sonarjs/prefer-immediate-return": "error", - "space-before-function-paren": "off", - "space-in-parens": ["off", "never"] - } - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/projects/app/src/app/app.component.ts b/projects/app/src/app/app.component.ts index 7bf08e2511..9de48f8882 100644 --- a/projects/app/src/app/app.component.ts +++ b/projects/app/src/app/app.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class AppComponent {} diff --git a/projects/app/src/app/app.module.ts b/projects/app/src/app/app.module.ts index 919d44b3de..57d48ac7f7 100644 --- a/projects/app/src/app/app.module.ts +++ b/projects/app/src/app/app.module.ts @@ -1,4 +1,4 @@ -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { NgModule } from '@angular/core'; @@ -12,6 +12,6 @@ import { AppComponent } from './app.component'; declarations: [AppComponent], bootstrap: [AppComponent], imports: [BrowserModule, FormsModule, RouterModule.forRoot([], {}), PoModule], - providers: [provideHttpClient(withInterceptorsFromDi())] + providers: [provideHttpClient(withXhr(), withInterceptorsFromDi())] }) export class AppModule {} diff --git a/projects/app/src/main.ts b/projects/app/src/main.ts index e4a844c38a..f77aa4e348 100644 --- a/projects/app/src/main.ts +++ b/projects/app/src/main.ts @@ -1,5 +1,5 @@ import { enableProdMode, provideZoneChangeDetection } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { platformBrowser } from '@angular/platform-browser'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; @@ -8,6 +8,6 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic() +platformBrowser() .bootstrapModule(AppModule, { applicationProviders: [provideZoneChangeDetection()] }) .catch(err => console.error('Error in app bootstrap:', err)); diff --git a/projects/app/tsconfig.app.json b/projects/app/tsconfig.app.json index cc10af0398..e1e7730a29 100644 --- a/projects/app/tsconfig.app.json +++ b/projects/app/tsconfig.app.json @@ -5,5 +5,8 @@ "types": [] }, "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"] + "include": ["src/**/*.d.ts"], + "angularCompilerOptions": { + "strictTemplates": false + } } diff --git a/projects/code-editor/.eslintrc.json b/projects/code-editor/.eslintrc.json deleted file mode 100644 index 9de0388323..0000000000 --- a/projects/code-editor/.eslintrc.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "extends": "../../.eslintrc.json", - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": ["projects/code-editor/tsconfig.lib.json", "projects/code-editor/tsconfig.spec.json"], - "createDefaultProgram": true - }, - "plugins": ["sonarjs"], - "rules": { - "@angular-eslint/component-selector": [ - "error", - { - "type": ["element", "attribute"], - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/directive-class-suffix": "off", - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/no-input-rename": "off", - "@angular-eslint/no-output-rename": "off", - "@typescript-eslint/array-type": [ - "error", - { - "default": "generic" - } - ], - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "off", - { - "types": { - "String": { - "message": "Use string instead", - "fixWith": "string" - }, - "Boolean": { - "message": "Use boolean instead", - "fixWith": "boolean" - }, - "Number": { - "message": "Use number instead", - "fixWith": "number" - } - } - } - ], - "@typescript-eslint/consistent-type-assertions": "off", - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/dot-notation": "off", - "@typescript-eslint/explicit-member-accessibility": [ - "off", - { - "accessibility": "explicit" - } - ], - "@typescript-eslint/member-delimiter-style": [ - "off", - { - "multiline": { - "delimiter": "none", - "requireLast": true - }, - "singleline": { - "delimiter": "semi", - "requireLast": false - } - } - ], - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": [ - "off", - { - "ignoreParameters": true - } - ], - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "@typescript-eslint/no-var-requires": "error", - "@typescript-eslint/prefer-for-of": "off", - "@typescript-eslint/quotes": [ - "off", - "single", - { - "allowTemplateLiterals": true - } - ], - "@typescript-eslint/require-array-sort-compare": [ - "error", - { - "ignoreStringArrays": true - } - ], - "@typescript-eslint/semi": ["off", null], - "@typescript-eslint/type-annotation-spacing": "off", - "arrow-parens": ["off", "always"], - "brace-style": ["off", "off"], - "default-case-last": "error", - "dot-notation": "off", - "eol-last": "off", - "id-blacklist": "off", - "id-match": "off", - "indent": "off", - "linebreak-style": "off", - "max-len": "off", - "max-lines-per-function": [ - "off", - { - "max": 200 - } - ], - "max-params": [ - "error", - { - "max": 8 - } - ], - "new-parens": "off", - "newline-per-chained-call": "off", - "no-empty-function": "off", - "no-empty-pattern": "off", - "no-extra-parens": "off", - "no-extra-semi": "error", - "no-irregular-whitespace": "off", - "no-multi-str": "error", - "no-self-assign": "error", - "no-shadow": "off", - "no-trailing-spaces": "off", - "no-underscore-dangle": "off", - "no-unused-expressions": "error", - "no-use-before-define": "off", - "object-shorthand": "off", - "padded-blocks": [ - "off", - { - "blocks": "never" - }, - { - "allowSingleLineBlocks": true - } - ], - "prefer-arrow/prefer-arrow-functions": "off", - "quote-props": "off", - "semi": "off", - "sonarjs/cognitive-complexity": "off", - "sonarjs/max-switch-cases": "error", - "sonarjs/no-all-duplicated-branches": "error", - "sonarjs/no-collapsible-if": "error", - "sonarjs/no-collection-size-mischeck": "error", - "sonarjs/no-duplicate-string": "off", - "sonarjs/no-duplicated-branches": "off", - "sonarjs/no-element-overwrite": "error", - "sonarjs/no-identical-conditions": "error", - "sonarjs/no-identical-expressions": "error", - "sonarjs/no-identical-functions": "off", - "sonarjs/no-inverted-boolean-check": "error", - "sonarjs/no-one-iteration-loop": "off", - "sonarjs/no-redundant-boolean": "error", - "sonarjs/no-redundant-jump": "error", - "sonarjs/no-same-line-conditional": "error", - "sonarjs/no-small-switch": "error", - "sonarjs/no-unused-collection": "error", - "sonarjs/no-use-of-empty-return-value": "error", - "sonarjs/no-useless-catch": "error", - "sonarjs/prefer-immediate-return": "error", - "space-before-function-paren": "off", - "space-in-parens": ["off", "never"] - } - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/projects/code-editor/karma.conf.js b/projects/code-editor/karma.conf.js index 011cc1dbb4..48e41f9154 100644 --- a/projects/code-editor/karma.conf.js +++ b/projects/code-editor/karma.conf.js @@ -9,8 +9,7 @@ module.exports = function (config) { require('karma-jasmine'), require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), - require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('karma-coverage') ], client: { clearContext: false // leave Jasmine Spec Runner output visible in browser diff --git a/projects/code-editor/package.json b/projects/code-editor/package.json index 0676c54d14..c8801a8bdc 100644 --- a/projects/code-editor/package.json +++ b/projects/code-editor/package.json @@ -19,9 +19,9 @@ "tslib": "^2.6.2" }, "peerDependencies": { - "@angular/common": "^21", - "@angular/core": "^21", - "@angular/forms": "^21", + "@angular/common": "^22", + "@angular/core": "^22", + "@angular/forms": "^22", "@po-ui/ng-components": "0.0.0-PLACEHOLDER", "monaco-editor": "0.44.0", "zone.js": "~0.15.0" diff --git a/projects/code-editor/src/lib/components/po-code-editor/po-code-editor.component.ts b/projects/code-editor/src/lib/components/po-code-editor/po-code-editor.component.ts index ee14c79755..9f57fc5cd3 100644 --- a/projects/code-editor/src/lib/components/po-code-editor/po-code-editor.component.ts +++ b/projects/code-editor/src/lib/components/po-code-editor/po-code-editor.component.ts @@ -1,4 +1,14 @@ -import { AfterViewInit, Component, DoCheck, ElementRef, forwardRef, NgZone, ViewChild, Provider } from '@angular/core'; +import { + AfterViewInit, + Component, + DoCheck, + ElementRef, + forwardRef, + NgZone, + ViewChild, + Provider, + ChangeDetectionStrategy +} from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { PoCodeEditorBaseComponent } from './po-code-editor-base.component'; @@ -60,6 +70,7 @@ const providers: Array = [ selector: 'po-code-editor', templateUrl: './po-code-editor.component.html', providers, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoCodeEditorComponent extends PoCodeEditorBaseComponent implements AfterViewInit, DoCheck { diff --git a/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-basic/sample-po-code-editor-basic.component.ts b/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-basic/sample-po-code-editor-basic.component.ts index c684b8c0e1..adc106e705 100644 --- a/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-basic/sample-po-code-editor-basic.component.ts +++ b/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-basic/sample-po-code-editor-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-code-editor-basic', templateUrl: './sample-po-code-editor-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCodeEditorBasicComponent {} diff --git a/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-diff/sample-po-code-editor-diff.component.ts b/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-diff/sample-po-code-editor-diff.component.ts index 1884a96c6a..befc3a0a55 100644 --- a/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-diff/sample-po-code-editor-diff.component.ts +++ b/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-diff/sample-po-code-editor-diff.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-code-editor-diff', templateUrl: './sample-po-code-editor-diff.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCodeEditorDiffComponent { diff --git a/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-labs/sample-po-code-editor-labs.component.ts b/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-labs/sample-po-code-editor-labs.component.ts index cc80b5510d..bcef0e9cfb 100644 --- a/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-labs/sample-po-code-editor-labs.component.ts +++ b/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-labs/sample-po-code-editor-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-code-editor-labs', templateUrl: './sample-po-code-editor-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCodeEditorLabsComponent implements OnInit { diff --git a/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-suggestion/sample-po-code-editor-suggestion.component.ts b/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-suggestion/sample-po-code-editor-suggestion.component.ts index d21c4f15f6..df2ae7126c 100644 --- a/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-suggestion/sample-po-code-editor-suggestion.component.ts +++ b/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-suggestion/sample-po-code-editor-suggestion.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-code-editor-suggestion', templateUrl: './sample-po-code-editor-suggestion.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCodeEditorSuggestionComponent { diff --git a/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-terraform/sample-po-code-editor-terraform.component.ts b/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-terraform/sample-po-code-editor-terraform.component.ts index f16e7e57e3..253b93737b 100644 --- a/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-terraform/sample-po-code-editor-terraform.component.ts +++ b/projects/code-editor/src/lib/components/po-code-editor/samples/sample-po-code-editor-terraform/sample-po-code-editor-terraform.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-code-editor-terraform', templateUrl: './sample-po-code-editor-terraform.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCodeEditorTerraformComponent {} diff --git a/projects/code-editor/src/test.ts b/projects/code-editor/src/test.ts index 8f714a3c85..89c3949e89 100644 --- a/projects/code-editor/src/test.ts +++ b/projects/code-editor/src/test.ts @@ -1,11 +1,15 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files -import 'zone.js'; -import 'zone.js/testing'; +import { NgModule, provideZoneChangeDetection } from '@angular/core'; import { getTestBed } from '@angular/core/testing'; import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing'; +@NgModule({ + providers: [provideZoneChangeDetection()] +}) +class AppTestingModule {} + // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment(BrowserTestingModule, platformBrowserTesting(), { +getTestBed().initTestEnvironment([BrowserTestingModule, AppTestingModule], platformBrowserTesting(), { teardown: { destroyAfterEach: false } }); diff --git a/projects/code-editor/tsconfig.lib.json b/projects/code-editor/tsconfig.lib.json index cf6fbcdce5..7033507129 100644 --- a/projects/code-editor/tsconfig.lib.json +++ b/projects/code-editor/tsconfig.lib.json @@ -10,9 +10,9 @@ "angularCompilerOptions": { "skipTemplateCodegen": true, "strictMetadataEmit": true, - "fullTemplateTypeCheck": true, "strictInjectionParameters": true, - "enableResourceInlining": true + "enableResourceInlining": true, + "strictTemplates": false }, "exclude": ["src/test.ts", "**/*.spec.ts"] } diff --git a/projects/code-editor/tsconfig.schematics.json b/projects/code-editor/tsconfig.schematics.json index 08454e09fb..0c5918d4dd 100644 --- a/projects/code-editor/tsconfig.schematics.json +++ b/projects/code-editor/tsconfig.schematics.json @@ -1,11 +1,10 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "baseUrl": "../../", "lib": ["es2018", "dom"], "declaration": true, - "module": "commonjs", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "noEmitOnError": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": false, diff --git a/projects/code-editor/tsconfig.spec.json b/projects/code-editor/tsconfig.spec.json index 519c167a68..92ff656bd5 100644 --- a/projects/code-editor/tsconfig.spec.json +++ b/projects/code-editor/tsconfig.spec.json @@ -6,5 +6,8 @@ "skipLibCheck": true }, "files": ["src/test.ts"], - "include": ["**/*.spec.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.d.ts"], + "angularCompilerOptions": { + "strictTemplates": false + } } diff --git a/projects/mcp/tsconfig.json b/projects/mcp/tsconfig.json index 8fa72b5cb0..a754d1dd25 100644 --- a/projects/mcp/tsconfig.json +++ b/projects/mcp/tsconfig.json @@ -1,10 +1,9 @@ { "compilerOptions": { - "baseUrl": ".", "lib": ["es2022"], "declaration": true, - "module": "commonjs", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "noEmitOnError": false, "noFallthroughCasesInSwitch": true, "noImplicitAny": true, diff --git a/projects/portal/.eslintrc.json b/projects/portal/.eslintrc.json deleted file mode 100644 index a8a4c3d7a6..0000000000 --- a/projects/portal/.eslintrc.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "extends": "../../.eslintrc.json", - "ignorePatterns": ["!**/*", "docs/**/*", "src/app/documentation/samples/**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": ["projects/portal/tsconfig.app.json", "projects/portal/tsconfig.spec.json"], - "createDefaultProgram": true - }, - "plugins": ["sonarjs"], - "rules": { - "@angular-eslint/component-selector": [ - "error", - { - "type": "element", - "prefix": "app", - "style": "kebab-case" - } - ], - "@angular-eslint/directive-class-suffix": "off", - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "app", - "style": "camelCase" - } - ], - "@angular-eslint/no-input-rename": "off", - "@angular-eslint/no-output-rename": "off", - "@typescript-eslint/array-type": [ - "error", - { - "default": "generic" - } - ], - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "off", - { - "types": { - "String": { - "message": "Use string instead", - "fixWith": "string" - }, - "Boolean": { - "message": "Use boolean instead", - "fixWith": "boolean" - }, - "Number": { - "message": "Use number instead", - "fixWith": "number" - } - } - } - ], - "@typescript-eslint/consistent-type-assertions": "off", - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/dot-notation": "off", - "@typescript-eslint/explicit-member-accessibility": [ - "off", - { - "accessibility": "explicit" - } - ], - "@typescript-eslint/member-delimiter-style": [ - "off", - { - "multiline": { - "delimiter": "none", - "requireLast": true - }, - "singleline": { - "delimiter": "semi", - "requireLast": false - } - } - ], - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": [ - "off", - { - "ignoreParameters": true - } - ], - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "@typescript-eslint/no-var-requires": "error", - "@typescript-eslint/prefer-for-of": "off", - "@typescript-eslint/quotes": [ - "off", - "single", - { - "allowTemplateLiterals": true - } - ], - "@typescript-eslint/require-array-sort-compare": [ - "error", - { - "ignoreStringArrays": true - } - ], - "@typescript-eslint/semi": ["off", null], - "@typescript-eslint/type-annotation-spacing": "off", - "arrow-parens": ["off", "always"], - "brace-style": ["off", "off"], - "default-case-last": "error", - "dot-notation": "off", - "eol-last": "off", - "id-blacklist": "off", - "id-match": "off", - "indent": "off", - "linebreak-style": "off", - "max-len": "off", - "max-lines-per-function": [ - "off", - { - "max": 200 - } - ], - "max-params": [ - "error", - { - "max": 8 - } - ], - "new-parens": "off", - "newline-per-chained-call": "off", - "no-empty-function": "off", - "no-empty-pattern": "off", - "no-extra-parens": "off", - "no-extra-semi": "error", - "no-irregular-whitespace": "off", - "no-multi-str": "error", - "no-self-assign": "error", - "no-shadow": "off", - "no-trailing-spaces": "off", - "no-underscore-dangle": "off", - "no-unused-expressions": "error", - "no-use-before-define": "off", - "object-shorthand": "off", - "padded-blocks": [ - "off", - { - "blocks": "never" - }, - { - "allowSingleLineBlocks": true - } - ], - "prefer-arrow/prefer-arrow-functions": "off", - "quote-props": "off", - "semi": "off", - "sonarjs/cognitive-complexity": "off", - "sonarjs/max-switch-cases": "error", - "sonarjs/no-all-duplicated-branches": "error", - "sonarjs/no-collapsible-if": "error", - "sonarjs/no-collection-size-mischeck": "error", - "sonarjs/no-duplicate-string": "off", - "sonarjs/no-duplicated-branches": "off", - "sonarjs/no-element-overwrite": "error", - "sonarjs/no-identical-conditions": "error", - "sonarjs/no-identical-expressions": "error", - "sonarjs/no-identical-functions": "off", - "sonarjs/no-inverted-boolean-check": "error", - "sonarjs/no-one-iteration-loop": "off", - "sonarjs/no-redundant-boolean": "error", - "sonarjs/no-redundant-jump": "error", - "sonarjs/no-same-line-conditional": "error", - "sonarjs/no-small-switch": "error", - "sonarjs/no-unused-collection": "error", - "sonarjs/no-use-of-empty-return-value": "error", - "sonarjs/no-useless-catch": "error", - "sonarjs/prefer-immediate-return": "error", - "space-before-function-paren": "off", - "space-in-parens": ["off", "never"] - } - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/projects/portal/docs/processors/helpers/file-writer.js b/projects/portal/docs/processors/helpers/file-writer.js index 7184d75bad..73a442c450 100644 --- a/projects/portal/docs/processors/helpers/file-writer.js +++ b/projects/portal/docs/processors/helpers/file-writer.js @@ -79,11 +79,12 @@ module.exports = { generateApiComponentFile: function (docName, component) { const componentSource = ` -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ selector: 'sample-{{docName}}-doc', templateUrl: './sample-{{docName}}-doc.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class Sample{{component}}DocComponent { } @@ -109,11 +110,12 @@ export class Sample{{component}}DocComponent { } }, generateSampleViewComponentFile: function (docName, name, component) { const componentSource = ` -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ selector: 'sample-{{name}}-view', templateUrl: './sample-{{name}}-view.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class Sample{{component}}ViewComponent { @@ -191,10 +193,11 @@ export class Doc{{component}}RoutingModule { } const componentSource = ` import { ActivatedRoute, Router } from '@angular/router'; -import { Component, OnInit, OnDestroy } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit, OnDestroy } from '@angular/core'; @Component({ templateUrl: './doc-{{docName}}.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class Doc{{component}}Component implements OnInit, OnDestroy { diff --git a/projects/portal/src/app/app.component.ts b/projects/portal/src/app/app.component.ts index c6165948e7..a9ee15f66e 100644 --- a/projects/portal/src/app/app.component.ts +++ b/projects/portal/src/app/app.component.ts @@ -1,9 +1,9 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; import { PoMenuItem, PoNavbarIconAction, PoNavbarItem, PoThemeA11yEnum } from '@po-ui/ng-components'; -import { PoDensityMode } from 'projects/ui/src/lib/enums/po-density-mode.enum'; +import { PoDensityMode } from '../../../ui/src/lib/enums/po-density-mode.enum'; import { firstValueFrom } from 'rxjs'; import { PoThemeService, PoThemeTypeEnum } from '../../../ui/src/lib'; import { poThemeConstant } from './shared/po-theme.constant'; @@ -12,6 +12,7 @@ import { VersionService } from './shared/version.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class AppComponent implements OnInit, OnDestroy { diff --git a/projects/portal/src/app/app.module.ts b/projects/portal/src/app/app.module.ts index 6ccbfee28e..0fe04da1b4 100644 --- a/projects/portal/src/app/app.module.ts +++ b/projects/portal/src/app/app.module.ts @@ -1,5 +1,4 @@ import { BrowserModule } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NgModule } from '@angular/core'; import { SharedModule } from './shared/shared.module'; @@ -7,13 +6,13 @@ import { SharedModule } from './shared/shared.module'; import { AppComponent } from './app.component'; import { AppRoutingModule } from './app-routing.module'; import { MenuService } from './menu.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; @NgModule({ declarations: [AppComponent], exports: [], bootstrap: [AppComponent], - imports: [BrowserModule, BrowserAnimationsModule, SharedModule, AppRoutingModule], - providers: [MenuService, provideHttpClient(withInterceptorsFromDi())] + imports: [BrowserModule, SharedModule, AppRoutingModule], + providers: [MenuService, provideHttpClient(withXhr(), withInterceptorsFromDi())] }) export class AppModule {} diff --git a/projects/portal/src/app/documentation/documentation-list.component.ts b/projects/portal/src/app/documentation/documentation-list.component.ts index 92dedcc380..fc5dd4b56a 100644 --- a/projects/portal/src/app/documentation/documentation-list.component.ts +++ b/projects/portal/src/app/documentation/documentation-list.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; import { PoListViewAction, PoListViewFieldProperties } from '@po-ui/ng-components'; @@ -8,6 +8,7 @@ import { DocumentationService } from '../documentation/documentation.service'; @Component({ templateUrl: './documentation-list.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class DocumentationListComponent implements OnInit { diff --git a/projects/portal/src/app/documentation/documentation.component.ts b/projects/portal/src/app/documentation/documentation.component.ts index 65171eee8b..06f86ec35c 100644 --- a/projects/portal/src/app/documentation/documentation.component.ts +++ b/projects/portal/src/app/documentation/documentation.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { MenuComponentsService } from './menu-components.service'; @@ -6,6 +6,7 @@ import { MenuComponentsService } from './menu-components.service'; @Component({ templateUrl: './documentation.component.html', providers: [MenuComponentsService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class DocumentationComponent implements OnInit { diff --git a/projects/portal/src/app/documentation/ia-tools-llms/ia-tools-llms.component.ts b/projects/portal/src/app/documentation/ia-tools-llms/ia-tools-llms.component.ts index 57e99edacb..1ac78631c5 100644 --- a/projects/portal/src/app/documentation/ia-tools-llms/ia-tools-llms.component.ts +++ b/projects/portal/src/app/documentation/ia-tools-llms/ia-tools-llms.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ templateUrl: './ia-tools-llms.component.html', @@ -13,6 +13,7 @@ import { Component } from '@angular/core'; } ` ], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class IaToolsLlmsComponent {} diff --git a/projects/portal/src/app/documentation/ia-tools-mcp/ia-tools-mcp.component.ts b/projects/portal/src/app/documentation/ia-tools-mcp/ia-tools-mcp.component.ts index 4710b5c465..171b3d851e 100644 --- a/projects/portal/src/app/documentation/ia-tools-mcp/ia-tools-mcp.component.ts +++ b/projects/portal/src/app/documentation/ia-tools-mcp/ia-tools-mcp.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ templateUrl: './ia-tools-mcp.component.html', @@ -13,6 +13,7 @@ import { Component } from '@angular/core'; } ` ], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class IaToolsMcpComponent {} diff --git a/projects/portal/src/app/guide/guides.components.ts b/projects/portal/src/app/guide/guides.components.ts index 524e5e65af..1193b6915b 100644 --- a/projects/portal/src/app/guide/guides.components.ts +++ b/projects/portal/src/app/guide/guides.components.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { MenuGuidesService } from './menu-guides.service'; @@ -6,6 +6,7 @@ import { MenuGuidesService } from './menu-guides.service'; @Component({ templateUrl: './guides.component.html', providers: [MenuGuidesService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class GuidesComponent implements OnInit { diff --git a/projects/portal/src/app/home/home-colorful/home-colorful.component.ts b/projects/portal/src/app/home/home-colorful/home-colorful.component.ts index a148baad08..5a4c84f964 100644 --- a/projects/portal/src/app/home/home-colorful/home-colorful.component.ts +++ b/projects/portal/src/app/home/home-colorful/home-colorful.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { pluck } from 'rxjs/operators'; import { HomeColorfulService } from './home-colorful.service'; @@ -6,6 +6,7 @@ import { HomeColorfulService } from './home-colorful.service'; selector: 'app-home-colorful', templateUrl: './home-colorful.component.html', styleUrls: ['./home-colorful.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class HomeColorfulComponent implements OnInit { diff --git a/projects/portal/src/app/home/home.component.ts b/projects/portal/src/app/home/home.component.ts index 3f38cfb0f3..40d31f9aa6 100644 --- a/projects/portal/src/app/home/home.component.ts +++ b/projects/portal/src/app/home/home.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-home', templateUrl: 'home.component.html', styleUrls: ['home.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class HomeComponent { diff --git a/projects/portal/src/app/icons/icons.component.ts b/projects/portal/src/app/icons/icons.component.ts index 4714c584cd..0d28932a33 100644 --- a/projects/portal/src/app/icons/icons.component.ts +++ b/projects/portal/src/app/icons/icons.component.ts @@ -1,11 +1,12 @@ import { HttpClient } from '@angular/common/http'; -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoComboOption, PoNotificationService, PoSearchComponent, PoSearchFilterMode } from '../../../../ui/src/lib'; @Component({ selector: 'app-icons', templateUrl: './icons.component.html', styleUrls: ['icons.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class IconsComponent { diff --git a/projects/portal/src/app/theme-builder/theme-builder.component.ts b/projects/portal/src/app/theme-builder/theme-builder.component.ts index d3298602f0..79830f1ed2 100644 --- a/projects/portal/src/app/theme-builder/theme-builder.component.ts +++ b/projects/portal/src/app/theme-builder/theme-builder.component.ts @@ -5,7 +5,8 @@ import { ElementRef, OnInit, ViewChild, - ViewEncapsulation + ViewEncapsulation, + ChangeDetectionStrategy } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @@ -35,6 +36,7 @@ import { templateUrl: './theme-builder.component.html', styleUrls: ['theme-builder.component.css'], encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class ThemeBuilderComponent implements AfterViewInit, OnInit { diff --git a/projects/portal/src/app/tools/tools-dynamic-form/tools-dynamic-form.component.ts b/projects/portal/src/app/tools/tools-dynamic-form/tools-dynamic-form.component.ts index 6a92a29e8f..5ae4dbb34f 100644 --- a/projects/portal/src/app/tools/tools-dynamic-form/tools-dynamic-form.component.ts +++ b/projects/portal/src/app/tools/tools-dynamic-form/tools-dynamic-form.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { @@ -11,12 +11,13 @@ import { PoTableColumn, PoToasterOrientation } from '@po-ui/ng-components'; -import { PoButtonType } from 'projects/ui/src/lib'; +import { PoButtonType } from '@po-ui/ng-components'; @Component({ selector: 'app-tools-dynamic-form', templateUrl: 'tools-dynamic-form.component.html', styleUrls: ['tools-dynamic-form.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class ToolsDynamicFormComponent { diff --git a/projects/portal/src/app/tools/tools-dynamic-view/tools-dynamic-view.component.ts b/projects/portal/src/app/tools/tools-dynamic-view/tools-dynamic-view.component.ts index 94b4ba6c56..067d3716ff 100644 --- a/projects/portal/src/app/tools/tools-dynamic-view/tools-dynamic-view.component.ts +++ b/projects/portal/src/app/tools/tools-dynamic-view/tools-dynamic-view.component.ts @@ -1,6 +1,5 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; -import { trigger, state, style, transition, animate } from '@angular/animations'; import { PoDynamicFormField, @@ -18,6 +17,7 @@ import { selector: 'app-tools-dynamic-view', templateUrl: 'tools-dynamic-view.component.html', styleUrls: ['tools-dynamic-view.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class ToolsDynamicViewComponent { diff --git a/projects/portal/src/main.ts b/projects/portal/src/main.ts index 9a13dc9636..e3e564a866 100644 --- a/projects/portal/src/main.ts +++ b/projects/portal/src/main.ts @@ -1,5 +1,5 @@ import { enableProdMode, provideZoneChangeDetection } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { platformBrowser } from '@angular/platform-browser'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; @@ -8,4 +8,4 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule, { applicationProviders: [provideZoneChangeDetection()] }); +platformBrowser().bootstrapModule(AppModule, { applicationProviders: [provideZoneChangeDetection()] }); diff --git a/projects/portal/src/test.ts b/projects/portal/src/test.ts index 2005284d1d..1fdf199a87 100644 --- a/projects/portal/src/test.ts +++ b/projects/portal/src/test.ts @@ -8,7 +8,7 @@ import 'zone.js/dist/jasmine-patch'; import 'zone.js/dist/async-test'; import 'zone.js/dist/fake-async-test'; import { getTestBed } from '@angular/core/testing'; -import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; +import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing'; // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. declare const __karma__: any; @@ -18,7 +18,7 @@ declare const require: any; __karma__.loaded = () => {}; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); +getTestBed().initTestEnvironment(BrowserTestingModule, platformBrowserTesting()); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/projects/portal/src/tsconfig.app.json b/projects/portal/src/tsconfig.app.json index d0c26f13be..b58113889c 100644 --- a/projects/portal/src/tsconfig.app.json +++ b/projects/portal/src/tsconfig.app.json @@ -2,7 +2,6 @@ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/app", - "baseUrl": "", "types": ["node"], "typeRoots": ["node_modules/@types"] }, diff --git a/projects/portal/src/tsconfig.spec.json b/projects/portal/src/tsconfig.spec.json index afb1dac35b..bf4d14b44e 100644 --- a/projects/portal/src/tsconfig.spec.json +++ b/projects/portal/src/tsconfig.spec.json @@ -2,7 +2,6 @@ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/spec", - "baseUrl": "", "typeRoots": ["node_modules/@types"], "types": ["jasmine", "node"] }, diff --git a/projects/portal/tsconfig.app.json b/projects/portal/tsconfig.app.json index cc10af0398..e1e7730a29 100644 --- a/projects/portal/tsconfig.app.json +++ b/projects/portal/tsconfig.app.json @@ -5,5 +5,8 @@ "types": [] }, "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"] + "include": ["src/**/*.d.ts"], + "angularCompilerOptions": { + "strictTemplates": false + } } diff --git a/projects/schematics/package.json b/projects/schematics/package.json index cb6ea550fb..9c1990bd1f 100644 --- a/projects/schematics/package.json +++ b/projects/schematics/package.json @@ -14,9 +14,9 @@ "postbuild": "gulp replaceVersion && cd ../../dist/ng-schematics && npm pack" }, "peerDependencies": { - "@angular-devkit/core": "^21", - "@angular-devkit/schematics": "^21", - "@schematics/angular": "^21" + "@angular-devkit/core": "^22", + "@angular-devkit/schematics": "^22", + "@schematics/angular": "^22" }, "dependencies": { "jsonc-parser": "^3.2.0" diff --git a/projects/schematics/src/build-component/build-component.ts b/projects/schematics/src/build-component/build-component.ts index 3c90879c5f..f4606e48e6 100644 --- a/projects/schematics/src/build-component/build-component.ts +++ b/projects/schematics/src/build-component/build-component.ts @@ -17,12 +17,28 @@ import { parseName } from '@schematics/angular/utility/parse-name'; import { validateHtmlSelector } from '@schematics/angular/utility/validation'; import { supportedCssExtensions } from '../utils/supported-css-extensions'; +import { detectFileNameStyleGuide, FileNameStyleGuide, getFileNameSuffixes } from '../utils/file-name-style-guide'; import { getProjectFromWorkspace, getDefaultPath, getWorkspaceConfigGracefully, getProjectMainFile } from '../project'; import { addModuleImportToModule, addDeclarationComponentToModule, addExportComponentToModule } from '../module'; import { Schema as ComponentOptions } from './schema'; import { WorkspaceSchema } from '@schematics/angular/utility/workspace-models'; import { isStandaloneApp } from '@schematics/angular/utility/ng-ast-utils'; +/** + * Returns the dasherized base file names (without extension) for the generated component, + * module and routing module, honoring the resolved file name style guide. + */ +export function getFileNames(name: string, styleGuide: FileNameStyleGuide) { + const dasherizedName = strings.dasherize(name); + const suffixes = getFileNameSuffixes(styleGuide); + + return { + componentFileName: `${dasherizedName}${suffixes.componentSuffix}`, + moduleFileName: `${dasherizedName}${suffixes.moduleSuffix}`, + routingFileName: `${dasherizedName}${suffixes.routingModuleSuffix}` + }; +} + export function buildComponent(options: ComponentOptions): Rule { return (host: Tree) => { const workspace = getWorkspaceConfigGracefully(host) ?? ({} as WorkspaceSchema); @@ -31,6 +47,10 @@ export function buildComponent(options: ComponentOptions): Rule { const isStandAlone = isStandaloneApp(host, browserEntryPoint); const urlFile = !isStandAlone ? './files' : './files-standalone'; + // Use the explicit option when provided, otherwise auto-detect the style already used by the project. + const styleGuide: FileNameStyleGuide = + options.fileNameStyleGuide ?? detectFileNameStyleGuide(host, browserEntryPoint); + if (options.path === undefined && project) { options.path = getDefaultPath(project); } @@ -51,19 +71,22 @@ export function buildComponent(options: ComponentOptions): Rule { validateName(options.name); validateHtmlSelector((options).selector); + const fileNames = getFileNames(options.name, styleGuide); + const templateSource = apply(url(urlFile), [ - options.routing ? noop() : filter(path => !path.endsWith('-routing.module.ts.template')), - options.createModule ? noop() : filter(path => !path.endsWith('.module.ts.template')), + options.routing ? noop() : filter(path => !path.endsWith('__routingFileName__.ts.template')), + options.createModule ? noop() : filter(path => !path.endsWith('__moduleFileName__.ts.template')), options.skipTests ? filter(path => !path.endsWith('.spec.ts.template')) : noop(), applyTemplates({ ...strings, - ...options + ...options, + ...fileNames }), move(null as any, parsedPath.path) ]); return chain([ - options.createModule ? addImportToModule(options) : addDeclarationToModule(options), + options.createModule ? addImportToModule(options, styleGuide) : addDeclarationToModule(options, styleGuide), mergeWith(templateSource) ]); }; @@ -87,16 +110,15 @@ function buildSelector(options: ComponentOptions, projectPrefix: string) { return selector; } -function addImportToModule(options: ComponentOptions): Rule { +function addImportToModule(options: ComponentOptions, styleGuide: FileNameStyleGuide): Rule { return (tree: Tree) => { if (!options.module || options.routing) { return tree; } const modulePath = options.module; + const { moduleFileName } = getFileNames(options.name, styleGuide); - const componentModulePath = normalize( - `/${options.path}/` + strings.dasherize(options.name) + '/' + strings.dasherize(options.name) + '.module' - ); + const componentModulePath = normalize(`/${options.path}/` + strings.dasherize(options.name) + '/' + moduleFileName); const relativePath = buildRelativePath(modulePath, componentModulePath); const classifiedModuleName = strings.classify(`${options.name}Module`); @@ -105,17 +127,16 @@ function addImportToModule(options: ComponentOptions): Rule { }; } -function addDeclarationToModule(options: ComponentOptions): Rule { +function addDeclarationToModule(options: ComponentOptions, styleGuide: FileNameStyleGuide): Rule { return (tree: Tree) => { if (!options.module) { return tree; } const modulePath = options.module; + const { componentFileName } = getFileNames(options.name, styleGuide); - const componentPath = normalize( - `/${options.path}/` + strings.dasherize(options.name) + '/' + strings.dasherize(options.name) + '.component' - ); + const componentPath = normalize(`/${options.path}/` + strings.dasherize(options.name) + '/' + componentFileName); const relativePath = buildRelativePath(modulePath, componentPath); const classifiedName = strings.classify(`${options.name}Component`); diff --git a/projects/schematics/src/build-component/schema.ts b/projects/schematics/src/build-component/schema.ts index 263d5b868e..cb9a31180b 100644 --- a/projects/schematics/src/build-component/schema.ts +++ b/projects/schematics/src/build-component/schema.ts @@ -40,4 +40,14 @@ export interface Schema { /** When true, create a component module. */ createModule?: boolean; + + /** + * The file naming convention to use for generated files. + * + * - `2016`: classic Angular Style Guide suffixes (e.g. `name.component.ts`, `name.module.ts`). + * - `2025`: current Angular convention without type suffixes (e.g. `name.ts`, `name-module.ts`). + * + * When omitted, the convention already used by the project is auto-detected. + */ + fileNameStyleGuide?: '2016' | '2025'; } diff --git a/projects/schematics/src/standalone/standalone.ts b/projects/schematics/src/standalone/standalone.ts index 3ac6e2764d..59080af1a6 100644 --- a/projects/schematics/src/standalone/standalone.ts +++ b/projects/schematics/src/standalone/standalone.ts @@ -1,6 +1,6 @@ import { Rule, Tree } from '@angular-devkit/schematics'; -import * as ts from '@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript'; +import * as ts from 'typescript'; import { WorkspaceSchema } from '@schematics/angular/utility/workspace-models'; import { addRootProvider } from '@schematics/angular/utility'; import { applyToUpdateRecorder } from '@schematics/angular/utility/change'; @@ -15,7 +15,7 @@ export function importProvidersFrom( moduleName: string, packageName: string, argsImportProvidersFrom: string -) { +): Rule { return (host: Tree) => { const workspace = getWorkspaceConfigGracefully(host) ?? ({} as WorkspaceSchema); const project: any = getProjectFromWorkspace(workspace, options.project); @@ -44,7 +44,7 @@ function addProvider( return addRootProvider( projectName, ({ code, external }) => code`${external('importProvidersFrom', '@angular/core')}(${argsImportProvidersFrom})` - ); + ) as unknown as Rule; } function addImport(host: Tree, filePath: string, symbolName: string, moduleName: string): void { diff --git a/projects/schematics/src/utils/file-name-style-guide.ts b/projects/schematics/src/utils/file-name-style-guide.ts new file mode 100644 index 0000000000..3ccf1ef94b --- /dev/null +++ b/projects/schematics/src/utils/file-name-style-guide.ts @@ -0,0 +1,252 @@ +import { Tree } from '@angular-devkit/schematics'; +import { getAppModulePath } from '@schematics/angular/utility/ng-ast-utils'; +import * as ts from 'typescript'; + +/** + * Supported Angular file name style guides. + * + * - `2016`: classic Angular Style Guide, file names include the type suffix + * (e.g. `app.component.ts`, `app.module.ts`). + * - `2025`: current Angular convention, file names omit the type suffix + * (e.g. `app.ts`, `app-module.ts`). + */ +export type FileNameStyleGuide = '2016' | '2025'; + +/** + * The file name suffixes applied to generated files for each style guide. + */ +export interface FileNameSuffixes { + componentSuffix: string; + moduleSuffix: string; + routingModuleSuffix: string; +} + +/** + * Returns the file name suffixes to apply to generated files for the given style guide. + */ +export function getFileNameSuffixes(styleGuide: FileNameStyleGuide): FileNameSuffixes { + const isStyleGuide2016 = styleGuide === '2016'; + + return { + componentSuffix: isStyleGuide2016 ? '.component' : '', + moduleSuffix: isStyleGuide2016 ? '.module' : '-module', + routingModuleSuffix: isStyleGuide2016 ? '-routing.module' : '-routing-module' + }; +} + +/** + * Detects the file name style guide already used by the project by inspecting the root + * symbol (component or module) bootstrapped in the given main file. + * + * The import path of the bootstrapped symbol reveals the convention: + * - `./app/app.component` or `./app/app.module` => `2016` + * - `./app/app` or `./app/app-module` => `2025` + * + * When the main file can not be read or parsed, it falls back to `2025` (the current default). + */ +export function detectFileNameStyleGuide(host: Tree, mainPath: string): FileNameStyleGuide { + const bootstrapImportPath = getBootstrapImportPath(host, mainPath); + + if (!bootstrapImportPath) { + return '2025'; + } + + const fileName = bootstrapImportPath.split('/').pop() ?? ''; + + return fileName.endsWith('.component') || fileName.endsWith('.module') ? '2016' : '2025'; +} + +/** + * Detects the name of the root component class already used by the project, so a schematic + * that overwrites the root component keeps the class name expected by the existing imports. + * + * - Standalone apps bootstrap the component directly (`bootstrapApplication(App)`), so the + * bootstrapped symbol is the component name (e.g. `App` or `AppComponent`). + * - NgModule apps bootstrap the module (`bootstrapModule(AppModule)`), so the component is + * read from the `bootstrap: [...]` array of the module's `@NgModule` decorator. + * + * Returns `undefined` when the name can not be resolved, so callers can fall back to their + * own convention. + */ +export function detectRootComponentClassName(host: Tree, mainPath: string): string | undefined { + const mainSource = readSourceFile(host, mainPath); + + if (!mainSource) { + return undefined; + } + + const bootstrapCall = getBootstrapCall(mainSource); + + if (!bootstrapCall) { + return undefined; + } + + // Standalone: the bootstrapped symbol is the root component itself. + if (bootstrapCall.callName === 'bootstrapApplication') { + return bootstrapCall.symbolName; + } + + // NgModule: resolve the module file and read the bootstrap component from its decorator. + let appModulePath: string; + + try { + appModulePath = getAppModulePath(host, mainPath); + } catch { + return undefined; + } + + const moduleSource = readSourceFile(host, appModulePath); + + if (!moduleSource) { + return undefined; + } + + return getNgModuleBootstrapComponent(moduleSource); +} + +/** + * Reads the main file and returns the module specifier of the imported symbol that is passed + * to `bootstrapApplication(...)` (standalone) or `bootstrapModule(...)` (NgModule). + */ +function getBootstrapImportPath(host: Tree, mainPath: string): string | undefined { + const source = readSourceFile(host, mainPath); + + if (!source) { + return undefined; + } + + const bootstrapSymbol = getBootstrappedSymbolName(source); + + if (!bootstrapSymbol) { + return undefined; + } + + return getImportSpecifierForSymbol(source, bootstrapSymbol); +} + +/** Describes the bootstrap call found in a main file. */ +interface BootstrapCall { + /** The bootstrap function name: `bootstrapApplication` (standalone) or `bootstrapModule` (NgModule). */ + callName: 'bootstrapApplication' | 'bootstrapModule'; + /** The identifier passed as the first argument (the root component or the root module). */ + symbolName: string; +} + +/** + * Finds the bootstrap call in the source and returns the function name along with the + * symbol passed as its first argument. + */ +function getBootstrapCall(source: ts.SourceFile): BootstrapCall | undefined { + let result: BootstrapCall | undefined; + + const visit = (node: ts.Node): void => { + if (result) { + return; + } + + if (ts.isCallExpression(node)) { + // The bootstrap call may be a direct identifier (`bootstrapApplication(...)`) or a + // chained method (`platformBrowser().bootstrapModule(...)`), where the callee is a + // property access expression. Resolve the called name from either shape. + const callee = node.expression; + const calledName = ts.isIdentifier(callee) + ? callee.text + : ts.isPropertyAccessExpression(callee) + ? callee.name.text + : undefined; + + if (calledName === 'bootstrapApplication' || calledName === 'bootstrapModule') { + const firstArgument = node.arguments[0]; + + if (firstArgument && ts.isIdentifier(firstArgument)) { + result = { callName: calledName, symbolName: firstArgument.text }; + return; + } + } + } + + ts.forEachChild(node, visit); + }; + + ts.forEachChild(source, visit); + + return result; +} + +/** Finds the name of the symbol bootstrapped in the given source (component or module). */ +function getBootstrappedSymbolName(source: ts.SourceFile): string | undefined { + return getBootstrapCall(source)?.symbolName; +} + +/** + * Extracts the first component name listed in the `bootstrap: [...]` array of an `@NgModule` + * decorator found in the given module source. + */ +function getNgModuleBootstrapComponent(source: ts.SourceFile): string | undefined { + let componentName: string | undefined; + + const visit = (node: ts.Node): void => { + if (componentName) { + return; + } + + if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === 'bootstrap') { + if (ts.isArrayLiteralExpression(node.initializer)) { + const firstElement = node.initializer.elements[0]; + + if (firstElement && ts.isIdentifier(firstElement)) { + componentName = firstElement.text; + return; + } + } + } + + ts.forEachChild(node, visit); + }; + + ts.forEachChild(source, visit); + + return componentName; +} + +/** Reads a file from the tree and parses it into a TypeScript source file. */ +function readSourceFile(host: Tree, filePath: string): ts.SourceFile | undefined { + if (!host.exists(filePath)) { + return undefined; + } + + const content = host.read(filePath)?.toString('utf-8'); + + if (!content) { + return undefined; + } + + return ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true); +} + +/** + * Returns the module specifier used to import the given symbol name. + */ +function getImportSpecifierForSymbol(source: ts.SourceFile, symbolName: string): string | undefined { + for (const statement of source.statements) { + if ( + !ts.isImportDeclaration(statement) || + !statement.importClause || + !statement.importClause.namedBindings || + !ts.isNamedImports(statement.importClause.namedBindings) || + !ts.isStringLiteral(statement.moduleSpecifier) + ) { + continue; + } + + const importsSymbol = statement.importClause.namedBindings.elements.some( + element => element.name.text === symbolName + ); + + if (importsSymbol) { + return statement.moduleSpecifier.text; + } + } + + return undefined; +} diff --git a/projects/schematics/src/utils/index.ts b/projects/schematics/src/utils/index.ts index be8239e5d0..67c7f76e53 100644 --- a/projects/schematics/src/utils/index.ts +++ b/projects/schematics/src/utils/index.ts @@ -1 +1,2 @@ export * from './supported-css-extensions'; +export * from './file-name-style-guide'; diff --git a/projects/schematics/tsconfig.json b/projects/schematics/tsconfig.json index b0e38bebab..8d734c7aff 100644 --- a/projects/schematics/tsconfig.json +++ b/projects/schematics/tsconfig.json @@ -1,10 +1,9 @@ { "compilerOptions": { - "baseUrl": ".", "lib": ["es2022", "dom"], "declaration": true, - "module": "commonjs", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "noEmitOnError": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": false, diff --git a/projects/storage/.eslintrc.json b/projects/storage/.eslintrc.json deleted file mode 100644 index dc546d54bc..0000000000 --- a/projects/storage/.eslintrc.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "extends": "../../.eslintrc.json", - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": ["projects/storage/tsconfig.lib.json", "projects/storage/tsconfig.spec.json"], - "createDefaultProgram": true - }, - "plugins": ["sonarjs"], - "rules": { - "@angular-eslint/component-selector": [ - "error", - { - "type": ["element", "attribute"], - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/directive-class-suffix": "off", - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/no-input-rename": "off", - "@angular-eslint/no-output-rename": "off", - "@typescript-eslint/array-type": [ - "error", - { - "default": "generic" - } - ], - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "off", - { - "types": { - "String": { - "message": "Use string instead", - "fixWith": "string" - }, - "Boolean": { - "message": "Use boolean instead", - "fixWith": "boolean" - }, - "Number": { - "message": "Use number instead", - "fixWith": "number" - } - } - } - ], - "@typescript-eslint/consistent-type-assertions": "off", - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/dot-notation": "off", - "@typescript-eslint/explicit-member-accessibility": [ - "off", - { - "accessibility": "explicit" - } - ], - "@typescript-eslint/member-delimiter-style": [ - "off", - { - "multiline": { - "delimiter": "none", - "requireLast": true - }, - "singleline": { - "delimiter": "semi", - "requireLast": false - } - } - ], - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": [ - "off", - { - "ignoreParameters": true - } - ], - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "@typescript-eslint/no-var-requires": "error", - "@typescript-eslint/prefer-for-of": "off", - "@typescript-eslint/quotes": [ - "off", - "single", - { - "allowTemplateLiterals": true - } - ], - "@typescript-eslint/require-array-sort-compare": [ - "error", - { - "ignoreStringArrays": true - } - ], - "@typescript-eslint/semi": ["off", null], - "@typescript-eslint/type-annotation-spacing": "off", - "arrow-parens": ["off", "always"], - "brace-style": ["off", "off"], - "default-case-last": "error", - "dot-notation": "off", - "eol-last": "off", - "id-blacklist": "off", - "id-match": "off", - "indent": "off", - "linebreak-style": "off", - "max-len": "off", - "max-lines-per-function": [ - "off", - { - "max": 200 - } - ], - "max-params": [ - "error", - { - "max": 8 - } - ], - "new-parens": "off", - "newline-per-chained-call": "off", - "no-empty-function": "off", - "no-empty-pattern": "off", - "no-extra-parens": "off", - "no-extra-semi": "error", - "no-irregular-whitespace": "off", - "no-multi-str": "error", - "no-self-assign": "error", - "no-shadow": "off", - "no-trailing-spaces": "off", - "no-underscore-dangle": "off", - "no-unused-expressions": "error", - "no-use-before-define": "off", - "object-shorthand": "off", - "padded-blocks": [ - "off", - { - "blocks": "never" - }, - { - "allowSingleLineBlocks": true - } - ], - "prefer-arrow/prefer-arrow-functions": "off", - "quote-props": "off", - "semi": "off", - "sonarjs/cognitive-complexity": "off", - "sonarjs/max-switch-cases": "error", - "sonarjs/no-all-duplicated-branches": "error", - "sonarjs/no-collapsible-if": "error", - "sonarjs/no-collection-size-mischeck": "error", - "sonarjs/no-duplicate-string": "off", - "sonarjs/no-duplicated-branches": "off", - "sonarjs/no-element-overwrite": "error", - "sonarjs/no-identical-conditions": "error", - "sonarjs/no-identical-expressions": "error", - "sonarjs/no-identical-functions": "off", - "sonarjs/no-inverted-boolean-check": "error", - "sonarjs/no-one-iteration-loop": "off", - "sonarjs/no-redundant-boolean": "error", - "sonarjs/no-redundant-jump": "error", - "sonarjs/no-same-line-conditional": "error", - "sonarjs/no-small-switch": "error", - "sonarjs/no-unused-collection": "error", - "sonarjs/no-use-of-empty-return-value": "error", - "sonarjs/no-useless-catch": "error", - "sonarjs/prefer-immediate-return": "error", - "space-before-function-paren": "off", - "space-in-parens": ["off", "never"] - } - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/projects/storage/karma.conf.js b/projects/storage/karma.conf.js index 87203560d5..ad4103b113 100644 --- a/projects/storage/karma.conf.js +++ b/projects/storage/karma.conf.js @@ -9,8 +9,7 @@ module.exports = function (config) { require('karma-jasmine'), require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), - require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('karma-coverage') ], client: { clearContext: false // leave Jasmine Spec Runner output visible in browser diff --git a/projects/storage/package.json b/projects/storage/package.json index a36769dd60..aae7c4acb4 100644 --- a/projects/storage/package.json +++ b/projects/storage/package.json @@ -18,7 +18,7 @@ "tslib": "^2.6.2" }, "peerDependencies": { - "@angular/core": "^21", + "@angular/core": "^22", "custom-idle-queue": "3.0.1", "localforage": "1.10.0", "lokijs": "1.5.12", diff --git a/projects/storage/src/lib/drivers/lokijs/po-loki-driver.spec.ts b/projects/storage/src/lib/drivers/lokijs/po-loki-driver.spec.ts index 6fa29925c4..9929230d6b 100644 --- a/projects/storage/src/lib/drivers/lokijs/po-loki-driver.spec.ts +++ b/projects/storage/src/lib/drivers/lokijs/po-loki-driver.spec.ts @@ -170,7 +170,7 @@ describe('PoLokiDriver', () => { it('initStorage: should call `configureLokiStorage` and `databaseInitialize.bind`', () => { spyOn(poLokiDriver, 'configureLokiStorage'); - spyOn(poLokiDriver['databaseInitialize'], 'bind'); + spyOn(poLokiDriver['databaseInitialize'] as any, 'bind'); poLokiDriver['initStorage'](getConfigMock()); diff --git a/projects/storage/src/lib/services/po-storage.service.spec.ts b/projects/storage/src/lib/services/po-storage.service.spec.ts index 6178c3d8e9..99af39bd8e 100644 --- a/projects/storage/src/lib/services/po-storage.service.spec.ts +++ b/projects/storage/src/lib/services/po-storage.service.spec.ts @@ -666,11 +666,10 @@ describe('PoStorageService:', () => { it('getStorageInstance: should return localForage instance', async () => { const localForageMock: LocalForage = createLocalForageInstance(); - spyOn(LocalForage, 'createInstance').and.returnValue(localForageMock); spyOn(PoStorageService, 'getDefaultConfig').and.returnValue({}); - spyOn(poStorageService, 'setDriver').and.returnValue(Promise.resolve()); + spyOn(poStorageService, 'defineLocalForageDriver').and.returnValue(Promise.resolve(localForageMock)); - expect(await poStorageService['getStorageInstance'](getConfigMock())).toEqual(localForageMock); + expect(await poStorageService['getStorageInstance'](getConfigMock())).toBe(localForageMock); }); }); }); diff --git a/projects/storage/tsconfig.lib.json b/projects/storage/tsconfig.lib.json index cf6fbcdce5..7033507129 100644 --- a/projects/storage/tsconfig.lib.json +++ b/projects/storage/tsconfig.lib.json @@ -10,9 +10,9 @@ "angularCompilerOptions": { "skipTemplateCodegen": true, "strictMetadataEmit": true, - "fullTemplateTypeCheck": true, "strictInjectionParameters": true, - "enableResourceInlining": true + "enableResourceInlining": true, + "strictTemplates": false }, "exclude": ["src/test.ts", "**/*.spec.ts"] } diff --git a/projects/storage/tsconfig.schematics.json b/projects/storage/tsconfig.schematics.json index 2ae8422dc0..7684ef6ffa 100644 --- a/projects/storage/tsconfig.schematics.json +++ b/projects/storage/tsconfig.schematics.json @@ -1,11 +1,10 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "baseUrl": "../../", "lib": ["es2022", "dom"], "declaration": true, - "module": "commonjs", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "noEmitOnError": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": false, diff --git a/projects/storage/tsconfig.spec.json b/projects/storage/tsconfig.spec.json index 519c167a68..92ff656bd5 100644 --- a/projects/storage/tsconfig.spec.json +++ b/projects/storage/tsconfig.spec.json @@ -6,5 +6,8 @@ "skipLibCheck": true }, "files": ["src/test.ts"], - "include": ["**/*.spec.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.d.ts"], + "angularCompilerOptions": { + "strictTemplates": false + } } diff --git a/projects/sync/.eslintrc.json b/projects/sync/.eslintrc.json deleted file mode 100644 index a3e99ce887..0000000000 --- a/projects/sync/.eslintrc.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "extends": "../../.eslintrc.json", - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": ["projects/sync/tsconfig.lib.json", "projects/sync/tsconfig.spec.json"], - "createDefaultProgram": true - }, - "plugins": ["sonarjs"], - "rules": { - "@angular-eslint/component-selector": [ - "error", - { - "type": "element", - "prefix": "lib", - "style": "kebab-case" - } - ], - "@angular-eslint/directive-class-suffix": "off", - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "lib", - "style": "camelCase" - } - ], - "@angular-eslint/no-input-rename": "off", - "@angular-eslint/no-output-rename": "off", - "@typescript-eslint/array-type": [ - "error", - { - "default": "generic" - } - ], - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "off", - { - "types": { - "String": { - "message": "Use string instead", - "fixWith": "string" - }, - "Boolean": { - "message": "Use boolean instead", - "fixWith": "boolean" - }, - "Number": { - "message": "Use number instead", - "fixWith": "number" - } - } - } - ], - "@typescript-eslint/consistent-type-assertions": "off", - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/dot-notation": "off", - "@typescript-eslint/explicit-member-accessibility": [ - "off", - { - "accessibility": "explicit" - } - ], - "@typescript-eslint/member-delimiter-style": [ - "off", - { - "multiline": { - "delimiter": "none", - "requireLast": true - }, - "singleline": { - "delimiter": "semi", - "requireLast": false - } - } - ], - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": [ - "off", - { - "ignoreParameters": true - } - ], - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "@typescript-eslint/no-var-requires": "error", - "@typescript-eslint/prefer-for-of": "off", - "@typescript-eslint/quotes": [ - "off", - "single", - { - "allowTemplateLiterals": true - } - ], - "@typescript-eslint/require-array-sort-compare": [ - "error", - { - "ignoreStringArrays": true - } - ], - "@typescript-eslint/semi": ["off", null], - "@typescript-eslint/type-annotation-spacing": "off", - "arrow-parens": ["off", "always"], - "brace-style": ["off", "off"], - "default-case-last": "error", - "dot-notation": "off", - "eol-last": "off", - "id-blacklist": "off", - "id-match": "off", - "indent": "off", - "linebreak-style": "off", - "max-len": "off", - "max-lines-per-function": [ - "off", - { - "max": 200 - } - ], - "max-params": [ - "error", - { - "max": 8 - } - ], - "new-parens": "off", - "newline-per-chained-call": "off", - "no-empty-function": "off", - "no-empty-pattern": "off", - "no-extra-parens": "off", - "no-extra-semi": "error", - "no-irregular-whitespace": "off", - "no-multi-str": "error", - "no-self-assign": "error", - "no-shadow": "off", - "no-trailing-spaces": "off", - "no-underscore-dangle": "off", - "no-unused-expressions": "error", - "no-use-before-define": "off", - "object-shorthand": "off", - "padded-blocks": [ - "off", - { - "blocks": "never" - }, - { - "allowSingleLineBlocks": true - } - ], - "prefer-arrow/prefer-arrow-functions": "off", - "quote-props": "off", - "semi": "off", - "sonarjs/cognitive-complexity": "off", - "sonarjs/max-switch-cases": "error", - "sonarjs/no-all-duplicated-branches": "error", - "sonarjs/no-collapsible-if": "error", - "sonarjs/no-collection-size-mischeck": "error", - "sonarjs/no-duplicate-string": "off", - "sonarjs/no-duplicated-branches": "off", - "sonarjs/no-element-overwrite": "error", - "sonarjs/no-identical-conditions": "error", - "sonarjs/no-identical-expressions": "error", - "sonarjs/no-identical-functions": "off", - "sonarjs/no-inverted-boolean-check": "error", - "sonarjs/no-one-iteration-loop": "off", - "sonarjs/no-redundant-boolean": "error", - "sonarjs/no-redundant-jump": "error", - "sonarjs/no-same-line-conditional": "error", - "sonarjs/no-small-switch": "error", - "sonarjs/no-unused-collection": "error", - "sonarjs/no-use-of-empty-return-value": "error", - "sonarjs/no-useless-catch": "error", - "sonarjs/prefer-immediate-return": "error", - "space-before-function-paren": "off", - "space-in-parens": ["off", "never"] - } - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/projects/sync/README.md b/projects/sync/README.md index 3dcb95f171..19926b547a 100644 --- a/projects/sync/README.md +++ b/projects/sync/README.md @@ -6,7 +6,7 @@ O **PO Sync** é uma biblioteca para aplicações Angular que possibilita armaze Instalando com schematic(recomendado): ``` -ng add @po-ui/ng-sync +ng add @po-ui/ng-sync@next ``` Instalando com npm: diff --git a/projects/sync/karma.conf.js b/projects/sync/karma.conf.js index b38aa86405..b4e6878935 100644 --- a/projects/sync/karma.conf.js +++ b/projects/sync/karma.conf.js @@ -9,8 +9,7 @@ module.exports = function (config) { require('karma-jasmine'), require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), - require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('karma-coverage') ], client: { clearContext: false // leave Jasmine Spec Runner output visible in browser diff --git a/projects/sync/package.json b/projects/sync/package.json index 4a66812107..98f9362898 100644 --- a/projects/sync/package.json +++ b/projects/sync/package.json @@ -26,8 +26,8 @@ "tslib": "^2.6.2" }, "peerDependencies": { - "@angular/core": "^21", - "@angular-devkit/schematics": "^21", + "@angular/core": "^22", + "@angular-devkit/schematics": "^22", "@capacitor/core": "^6.2.0", "@capacitor/network": "^6.0.1", "@po-ui/ng-storage": "0.0.0-PLACEHOLDER", diff --git a/projects/sync/schematics/migrations.json b/projects/sync/schematics/migrations.json index fe1bc76e8b..46c618d747 100644 --- a/projects/sync/schematics/migrations.json +++ b/projects/sync/schematics/migrations.json @@ -65,6 +65,11 @@ "version": "0.0.0-PLACEHOLDER", "description": "Atualiza @po-ui/ng-sync para v21", "factory": "./ng-update/v21/index" + }, + "migration-v22": { + "version": "0.0.0-PLACEHOLDER", + "description": "Atualiza @po-ui/ng-sync para v22", + "factory": "./ng-update/v22/index" } } } diff --git a/projects/sync/schematics/ng-add/setup-project.ts b/projects/sync/schematics/ng-add/setup-project.ts index 3c6b371747..d19b550ca0 100644 --- a/projects/sync/schematics/ng-add/setup-project.ts +++ b/projects/sync/schematics/ng-add/setup-project.ts @@ -133,7 +133,7 @@ function addProviderToModuleProvider( ) { const moduleSource = getSourceFile(tree, modulePath); const changes = addProviderToModule( - moduleSource as any, + moduleSource, modulePath, ` ${provider}`, diff --git a/projects/sync/schematics/ng-update/v22/changes.ts b/projects/sync/schematics/ng-update/v22/changes.ts new file mode 100644 index 0000000000..197dbab8a9 --- /dev/null +++ b/projects/sync/schematics/ng-update/v22/changes.ts @@ -0,0 +1,12 @@ +import { UpdateDependencies } from '@po-ui/ng-schematics/package-config'; + +export const updateDepedenciesVersion: UpdateDependencies = { + dependencies: [ + '@po-ui/ng-components', + '@po-ui/ng-code-editor', + '@po-ui/ng-templates', + '@po-ui/ng-storage', + '@po-ui/ng-sync', + '@po-ui/style' + ] +}; diff --git a/projects/sync/schematics/ng-update/v22/index.ts b/projects/sync/schematics/ng-update/v22/index.ts new file mode 100644 index 0000000000..4a806ce232 --- /dev/null +++ b/projects/sync/schematics/ng-update/v22/index.ts @@ -0,0 +1,16 @@ +import { chain, Tree, SchematicContext } from '@angular-devkit/schematics'; +import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; + +import { updatePackageJson } from '@po-ui/ng-schematics/package-config'; + +import { updateDepedenciesVersion } from './changes'; + +export default function () { + return chain([updatePackageJson('0.0.0-PLACEHOLDER', updateDepedenciesVersion), postUpdate()]); +} + +function postUpdate() { + return (_: Tree, context: SchematicContext) => { + context.addTask(new NodePackageInstallTask()); + }; +} diff --git a/projects/sync/schematics/package.json b/projects/sync/schematics/package.json new file mode 100644 index 0000000000..5bbefffbab --- /dev/null +++ b/projects/sync/schematics/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/projects/sync/src/lib/models/po-entity/po-entity.model.spec.ts b/projects/sync/src/lib/models/po-entity/po-entity.model.spec.ts index eab9b589c2..8d5620563a 100644 --- a/projects/sync/src/lib/models/po-entity/po-entity.model.spec.ts +++ b/projects/sync/src/lib/models/po-entity/po-entity.model.spec.ts @@ -133,7 +133,7 @@ describe('PoEntity:', () => { const limitedCallWrapReturn = 'limitedCallWrap return'; spyOn(poEntity['poSchemaService'], 'limitedCallWrap').and.returnValue(limitedCallWrapReturn); - spyOn(poEntity['selectSaveType'], 'bind'); + spyOn(poEntity['selectSaveType'] as any, 'bind'); const result = await poEntity.save(modelMock, customRequestId); diff --git a/projects/sync/src/lib/services/po-event-sourcing/po-event-sourcing.service.spec.ts b/projects/sync/src/lib/services/po-event-sourcing/po-event-sourcing.service.spec.ts index d7ee4636c2..14d6b52607 100644 --- a/projects/sync/src/lib/services/po-event-sourcing/po-event-sourcing.service.spec.ts +++ b/projects/sync/src/lib/services/po-event-sourcing/po-event-sourcing.service.spec.ts @@ -1,5 +1,5 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { HttpResponse, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { HttpResponse, provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { TestBed } from '@angular/core/testing'; @@ -70,7 +70,7 @@ describe('PoEventSourcingService:', () => { { provide: PoSchemaService, useClass: PoSchemaService }, { provide: PoSchemaDefinitionService, useClass: PoSchemaDefinitionService }, { provide: PoHttpClientService, useClass: PoHttpClientService }, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }); diff --git a/projects/sync/src/lib/services/po-http-client/po-http-client.service.spec.ts b/projects/sync/src/lib/services/po-http-client/po-http-client.service.spec.ts index 728a3a301e..96d7d7bcf8 100644 --- a/projects/sync/src/lib/services/po-http-client/po-http-client.service.spec.ts +++ b/projects/sync/src/lib/services/po-http-client/po-http-client.service.spec.ts @@ -1,5 +1,5 @@ import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; -import { HttpResponse, HttpHeaders, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { HttpResponse, HttpHeaders, provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; @@ -15,7 +15,11 @@ describe('PoHttpClientService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoHttpClientService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoHttpClientService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); poHttpClientService = TestBed.inject(PoHttpClientService); diff --git a/projects/sync/src/lib/services/po-sync/po-sync.service.spec.ts b/projects/sync/src/lib/services/po-sync/po-sync.service.spec.ts index c6c54e4d69..8801f1e1ab 100644 --- a/projects/sync/src/lib/services/po-sync/po-sync.service.spec.ts +++ b/projects/sync/src/lib/services/po-sync/po-sync.service.spec.ts @@ -1,8 +1,6 @@ -import { HttpResponse } from '@angular/common/http'; import { fakeAsync, tick } from '@angular/core/testing'; -import { of, Subscriber } from 'rxjs'; -import { TestScheduler } from 'rxjs/testing'; -import * as TypeMoq from 'typemoq'; +import { of, Subject, Subscriber } from 'rxjs'; + import { PoNetworkType } from '../../models/po-network-type.enum'; import { PoUtils as utilsFunctions } from '../../utils/utils'; import { PoEventSourcingService } from '../po-event-sourcing/po-event-sourcing.service'; @@ -36,17 +34,13 @@ class CustomDataTransform extends PoDataTransform { } } -xdescribe('PoSyncService:', () => { - const scheduler = new TestScheduler((actual, expected) => { - expect(actual).toEqual(expected); - }); - +describe('PoSyncService:', () => { let poSync: PoSyncService; - let poNetworkServiceMock: TypeMoq.IMock; - let poEventSourcing: TypeMoq.IMock; - let poSchemaDefinition: TypeMoq.IMock; - let poSchemaService: TypeMoq.IMock; - let http: TypeMoq.IMock; + let poEventSourcing: jasmine.SpyObj; + let poSchemaDefinition: jasmine.SpyObj; + let poSchemaService: jasmine.SpyObj; + let poNetworkServiceMock: jasmine.SpyObj; + let http: jasmine.SpyObj; const customerSchema: PoSyncSchema = { idField: 'code', @@ -70,32 +64,39 @@ xdescribe('PoSyncService:', () => { }; beforeEach(() => { - http = TypeMoq.Mock.ofType(PoHttpClientService); - - poEventSourcing = TypeMoq.Mock.ofType(PoEventSourcingService); - - poEventSourcing.setup(e => e.syncGet()).returns(() => Promise.resolve({})); - - poEventSourcing.setup(e => e.syncSend()).returns(() => Promise.resolve({})); - - poEventSourcing.setup(e => e.onSaveData()).returns(() => of(null)); - - poNetworkServiceMock = TypeMoq.Mock.ofType(PoNetworkService); - - poNetworkServiceMock.setup(e => e.onChange()).returns(() => of({ status: undefined, type: undefined })); - - poSchemaDefinition = TypeMoq.Mock.ofType(PoSchemaDefinitionService); - - poSchemaService = TypeMoq.Mock.ofType(PoSchemaService); - - poNetworkServiceMock.setup(e => e.getConnectionStatus()).returns(() => new PoNetworkStatus('wifi')); + http = jasmine.createSpyObj('PoHttpClientService', ['get']); + + poEventSourcing = jasmine.createSpyObj('PoEventSourcingService', [ + 'syncGet', + 'syncSend', + 'onSaveData', + 'responsesSubject', + 'httpCommand', + 'removeEventSourcingItem', + 'destroyEventSourcingQueue' + ]); + poEventSourcing.syncGet.and.returnValue(Promise.resolve({})); + poEventSourcing.syncSend.and.returnValue(Promise.resolve({})); + poEventSourcing.onSaveData.and.returnValue(of(null)); + + poNetworkServiceMock = jasmine.createSpyObj('PoNetworkService', ['getConnectionStatus', 'onChange']); + poNetworkServiceMock.onChange.and.returnValue(of({ status: undefined, type: undefined })); + poNetworkServiceMock.getConnectionStatus.and.returnValue(new PoNetworkStatus('wifi')); + + poSchemaDefinition = jasmine.createSpyObj('PoSchemaDefinitionService', ['getAll', 'saveAll', 'destroy']); + + poSchemaService = jasmine.createSpyObj('PoSchemaService', [ + 'limitedCallWrap', + 'destroySchemasRecords', + 'updateAll' + ]); poSync = new PoSyncService( - poEventSourcing.object, - http.object, - poNetworkServiceMock.object, - poSchemaDefinition.object, - poSchemaService.object + poEventSourcing as any, + http as any, + poNetworkServiceMock as any, + poSchemaDefinition as any, + poSchemaService as any ); }); @@ -112,36 +113,30 @@ xdescribe('PoSyncService:', () => { describe('Methods:', () => { it('destroy: should call poSchemaService.limitedCallWrap and return its value', async () => { const limitedCallWrapReturn = 'limitedCallWrap return'; - - spyOn(poSync['poSchemaService'], 'limitedCallWrap').and.returnValue(limitedCallWrapReturn); + poSchemaService.limitedCallWrap.and.returnValue(limitedCallWrapReturn as any); const result = await poSync.destroy(); - expect(poSync['poSchemaService']['limitedCallWrap']).toHaveBeenCalled(); + expect(poSchemaService.limitedCallWrap).toHaveBeenCalled(); expect(result).toBe(limitedCallWrapReturn); }); it('destroy: should call poSchemaDefinitionService.destroy, destroySchemasRecords, destroyEventSourcingQueue', async () => { - poSync['schemas'] = [customerSchema]; - - spyOn(poSync['poSchemaService'], 'limitedCallWrap').and.callFake(callback => callback()); - - spyOn(poSync['poSchemaDefinitionService'], 'destroy'); - spyOn(poSync['poSchemaService'], 'destroySchemasRecords'); - spyOn(poSync['poEventSourcingService'], 'destroyEventSourcingQueue'); + poSchemaService.limitedCallWrap.and.callFake((callback: any) => callback()); + poSchemaDefinition.destroy.and.returnValue(Promise.resolve()); + poSchemaService.destroySchemasRecords.and.returnValue(Promise.resolve()); + poEventSourcing.destroyEventSourcingQueue.and.returnValue(Promise.resolve()); await poSync.destroy(); - expect(poSync['poSchemaDefinitionService'].destroy).toHaveBeenCalled(); - expect(poSync['poSchemaService'].destroySchemasRecords).toHaveBeenCalled(); - expect(poSync['poEventSourcingService'].destroyEventSourcingQueue).toHaveBeenCalled(); + expect(poSchemaDefinition.destroy).toHaveBeenCalled(); + expect(poSchemaService.destroySchemasRecords).toHaveBeenCalled(); + expect(poEventSourcing.destroyEventSourcingQueue).toHaveBeenCalled(); }); it('disableSync: should set isSyncEnabled with false', () => { poSync['isSyncEnabled'] = true; - poSync.disableSync(); - expect(poSync['isSyncEnabled']).toBeFalsy(); }); @@ -149,37 +144,28 @@ xdescribe('PoSyncService:', () => { const fakeThis = { isSyncEnabled: true, timer: 'mock timer', - subscription: { - unsubscribe: () => {} - } + subscription: { unsubscribe: jasmine.createSpy('unsubscribe') } }; - spyOn(fakeThis.subscription, 'unsubscribe'); - poSync.disableSync.apply(fakeThis); - expect(fakeThis['subscription'].unsubscribe).toHaveBeenCalled(); + expect(fakeThis.subscription.unsubscribe).toHaveBeenCalled(); }); - it('disableSync: should not call subscription.unsubscribe if timer is undefined and subscription is defined', () => { + it('disableSync: should not call subscription.unsubscribe if timer is undefined', () => { const fakeThis = { isSyncEnabled: true, timer: undefined, - subscription: { - unsubscribe: () => {} - } + subscription: { unsubscribe: jasmine.createSpy('unsubscribe') } }; - spyOn(fakeThis.subscription, 'unsubscribe'); - poSync.disableSync.apply(fakeThis); - expect(fakeThis['subscription'].unsubscribe).not.toHaveBeenCalled(); + expect(fakeThis.subscription.unsubscribe).not.toHaveBeenCalled(); }); it('enableSync: should set isSyncEnabled with true and call createSubscribe', () => { poSync['isSyncEnabled'] = false; - spyOn(poSync, 'createSubscribe'); poSync.enableSync(); @@ -189,10 +175,10 @@ xdescribe('PoSyncService:', () => { }); it('getResponses: should call responsesSubject', done => { - spyOn(poSync['poEventSourcingService'], 'responsesSubject').and.returnValue(of({})); + poEventSourcing.responsesSubject.and.returnValue(of({}) as any); poSync.getResponses().subscribe(() => { - expect(poSync['poEventSourcingService']['responsesSubject']).toHaveBeenCalled(); + expect(poEventSourcing.responsesSubject).toHaveBeenCalled(); done(); }); }); @@ -209,30 +195,26 @@ xdescribe('PoSyncService:', () => { expect(result).toThrowError(Error, 'Model not found: Clients'); }); - it(`insertHttpCommand: should call validateParameter with records inside an object and httpCommand with PoHttpRequestData`, async () => { + it('insertHttpCommand: should call validateParameter and httpCommand', async () => { const requestDataMock: PoHttpRequestData = { url: 'http://url-test.com', method: PoHttpRequestType.GET }; - spyOn(utilsFunctions, 'validateParameter'); - spyOn(poSync['poEventSourcingService'], 'httpCommand').and.returnValue(Promise.resolve()); + poEventSourcing.httpCommand.and.returnValue(Promise.resolve(1)); await poSync.insertHttpCommand(requestDataMock); - expect(poSync['poEventSourcingService']['httpCommand']).toHaveBeenCalledWith(requestDataMock, undefined); + expect(poEventSourcing.httpCommand).toHaveBeenCalledWith(requestDataMock, undefined); expect(utilsFunctions.validateParameter).toHaveBeenCalledWith({ requestData: requestDataMock }); }); - it(`insertHttpCommand: should should call validateParameter with records inside an object and httpCommand with - customRequestId`, async () => { + it('insertHttpCommand: should call httpCommand with customRequestId', async () => { const requestDataMock: PoHttpRequestData = { url: 'http://url-test.com', method: PoHttpRequestType.GET }; - const customRequestId: string = '123'; - + const customRequestId = '123'; spyOn(utilsFunctions, 'validateParameter'); - spyOn(poSync['poEventSourcingService'], 'httpCommand').and.returnValue(Promise.resolve()); + poEventSourcing.httpCommand.and.returnValue(Promise.resolve(1)); await poSync.insertHttpCommand(requestDataMock, customRequestId); - expect(poSync['poEventSourcingService']['httpCommand']).toHaveBeenCalledWith(requestDataMock, customRequestId); - expect(utilsFunctions.validateParameter).toHaveBeenCalledWith({ requestData: requestDataMock }); + expect(poEventSourcing.httpCommand).toHaveBeenCalledWith(requestDataMock, customRequestId); }); it('loadData: should load api data', done => { @@ -251,15 +233,10 @@ xdescribe('PoSyncService:', () => { it('onSync: should return the same eventSub observable', done => { poSync['eventSub'] = of({ data: 'value' }); - poSync.onSync().subscribe( - result => { - expect(result).toEqual({ data: 'value' }); - done(); - }, - err => { - fail(err); - } - ); + poSync.onSync().subscribe(result => { + expect(result).toEqual({ data: 'value' }); + done(); + }); }); it('onSync: should emitter to be a Subscriber instance', () => { @@ -268,19 +245,16 @@ xdescribe('PoSyncService:', () => { expect(poSync['emitter'] instanceof Subscriber).toBeTruthy(); }); - it('prepare: should call validateArray with mySchemas inside an object', async () => { + it('prepare: should call validateArray with schemas', async () => { const mySchemas = [customerSchema]; - const validateArrayParam = { schemas: mySchemas }; - spyOn(poSync, 'startTimer'); spyOn(poSync, 'reactiveSync'); spyOn(utilsFunctions, 'validateArray'); - spyOn(poSync['poEventSourcingService'], 'onSaveData').and.returnValue(of()); - spyOn(poSync, 'saveSchemas').and.returnValue({ then: () => {} }); + spyOn(poSync, 'saveSchemas').and.returnValue(Promise.resolve()); await poSync.prepare(mySchemas); - expect(utilsFunctions.validateArray).toHaveBeenCalledWith(validateArrayParam); + expect(utilsFunctions.validateArray).toHaveBeenCalledWith({ schemas: mySchemas }); }); it('prepare: should prepare all configs to sync', async () => { @@ -289,13 +263,11 @@ xdescribe('PoSyncService:', () => { period: 30, dataTransform: new CustomDataTransform() }; - const mySchemas = [customerSchema]; spyOn(poSync, 'startTimer'); spyOn(poSync, 'reactiveSync'); spyOn(utilsFunctions, 'validateArray'); - spyOn(poSync['poEventSourcingService'], 'onSaveData').and.returnValue(of()); spyOn(poSync, 'saveSchemas').and.returnValue(Promise.resolve()); await poSync.prepare(mySchemas, myConfig); @@ -305,282 +277,192 @@ xdescribe('PoSyncService:', () => { expect(poSync['poEventSourcingService']['config']).toEqual(myConfig); expect(poSync['startTimer']).toHaveBeenCalled(); expect(poSync['reactiveSync']).toHaveBeenCalled(); - expect(poSync['poEventSourcingService']['onSaveData']).toHaveBeenCalled(); expect(poSync['saveSchemas']).toHaveBeenCalled(); expect(poSync['models']['Customers'] instanceof PoEntity).toBeTruthy(); - expect(poSync['models']['Customers']['schema']).toEqual(customerSchema); }); - it('prepare: should set default config to sync', async () => { - const defaultConfig: PoSyncConfig = { - type: poSync['poNetworkService']['getConnectionStatus']().type, - period: 60, - dataTransform: new PoDataMessage() - }; - + it('prepare: should set default config when no config is passed', async () => { const mySchemas = [customerSchema]; + spyOn(poSync, 'startTimer'); + spyOn(poSync, 'reactiveSync'); + spyOn(poSync, 'saveSchemas').and.returnValue(Promise.resolve()); await poSync.prepare(mySchemas); - expect(poSync['config']).toEqual(defaultConfig); + expect(poSync['config'].period).toBe(60); + expect(poSync['config'].dataTransform instanceof PoDataMessage).toBeTruthy(); }); - it('prepare: should set config without DataTransform', async () => { + it('prepare: should set dataTransform to PoDataMessage when config has no dataTransform', async () => { const mySchemas = [customerSchema]; - const myConfig: PoSyncConfig = { - type: PoNetworkType.wifi, - period: 60 - }; + const myConfig: PoSyncConfig = { type: PoNetworkType.wifi, period: 60 }; + + spyOn(poSync, 'startTimer'); + spyOn(poSync, 'reactiveSync'); + spyOn(poSync, 'saveSchemas').and.returnValue(Promise.resolve()); await poSync.prepare(mySchemas, myConfig); - expect(poSync['config']['dataTransform']).toEqual(new PoDataMessage()); + expect(poSync['config']['dataTransform'] instanceof PoDataMessage).toBeTruthy(); }); - it('removeItemOfSync: should call poEventSourcingService.removeItemEventSourcing with id', async () => { - const idEventSourcingMock = jasmine.any(Number); - spyOn(poSync['poEventSourcingService'], 'removeEventSourcingItem').and.returnValue(Promise.resolve()); - - await poSync.removeItemOfSync(idEventSourcingMock); - - expect(poSync['poEventSourcingService']['removeEventSourcingItem']).toHaveBeenCalledWith(idEventSourcingMock); + it('removeItemOfSync: should call removeEventSourcingItem with id', async () => { + poEventSourcing.removeEventSourcingItem.and.returnValue(Promise.resolve()); + await poSync.removeItemOfSync(123); + expect(poEventSourcing.removeEventSourcingItem).toHaveBeenCalledWith(123); }); - it('resumeSync: should call sync and finishSyncSubject.asObservable when canSync is false', async () => { - spyOn(poSync, 'canSync').and.returnValue(false); - const spySync = spyOn(poSync, 'sync').and.returnValue(Promise.resolve()); - spyOn(poSync['finishSyncSubject'], 'asObservable').and.callThrough(); + it('resumeSync: should call sync when canSync is true', async () => { + spyOn(poSync, 'canSync').and.returnValue(true); + spyOn(poSync, 'sync').and.returnValue(Promise.resolve()); await poSync.resumeSync(); - poSync['finishSyncSubject']['next'](null); - - expect(poSync['finishSyncSubject']['asObservable']).toHaveBeenCalledBefore(spySync); expect(poSync.sync).toHaveBeenCalled(); }); - it(`resumeSync: should call sync and not call finishSyncSubject.asObservable - when canSync is true`, async () => { - spyOn(poSync, 'canSync').and.returnValue(true); - spyOn(poSync, 'sync'); - spyOn(poSync['finishSyncSubject'], 'asObservable').and.returnValue(of()); + it('resumeSync: should subscribe to finishSyncSubject when canSync is false', async () => { + spyOn(poSync, 'canSync').and.returnValue(false); + const spySync = spyOn(poSync, 'sync').and.returnValue(Promise.resolve()); + spyOn(poSync['finishSyncSubject'], 'asObservable').and.callThrough(); await poSync.resumeSync(); + poSync['finishSyncSubject'].next(null); + + expect(poSync['finishSyncSubject'].asObservable).toHaveBeenCalledBefore(spySync); expect(poSync.sync).toHaveBeenCalled(); - expect(poSync['finishSyncSubject']['asObservable']).not.toHaveBeenCalled(); }); - it('sync: syncError should be called when syncGet error happen', done => { + it('sync: should call startSync and finishSync when canSync returns true', async () => { spyOn(poSync, 'canSync').and.returnValue(true); spyOn(poSync, 'startSync'); - spyOn(poSync['poEventSourcingService'], 'syncGet').and.throwError('Error on sync'); - spyOn(poSync, 'syncError'); + spyOn(poSync, 'finishSync'); - poSync - .sync() - .then(() => { - expect(poSync['startSync']).toHaveBeenCalled(); - expect(poSync['syncError']).toHaveBeenCalled(); - done(); - }) - .catch(err => { - fail(); - }); - }); + await poSync.sync(); - it('sync: should call startSync and finishSync when canSync returns true', done => { - spyOn(poSync, 'canSync').and.returnValue(true); - spyOn(poSync, 'startSync'); - spyOn(poSync, 'finishSync'); - poSync - .sync() - .then(() => { - expect(poSync['startSync']).toHaveBeenCalled(); - expect(poSync['finishSync']).toHaveBeenCalled(); - done(); - }) - .catch(err => { - fail(err); - }); + expect(poSync['startSync']).toHaveBeenCalled(); + expect(poSync['finishSync']).toHaveBeenCalled(); }); - it('sync: should not call startSync and finishSync when canSync returns false', done => { + it('sync: should not call startSync when canSync returns false', async () => { spyOn(poSync, 'canSync').and.returnValue(false); spyOn(poSync, 'startSync'); spyOn(poSync, 'finishSync'); - poSync - .sync() - .then(() => { - expect(poSync['startSync']).not.toHaveBeenCalled(); - expect(poSync['finishSync']).not.toHaveBeenCalled(); - done(); - }) - .catch(err => { - fail(err); - }); + + await poSync.sync(); + + expect(poSync['startSync']).not.toHaveBeenCalled(); + expect(poSync['finishSync']).not.toHaveBeenCalled(); }); it('sync: should call emitter.next() when emitter is defined', async () => { spyOn(poSync, 'canSync').and.returnValue(true); - spyOn(poSync['poEventSourcingService'], 'syncGet').and.returnValue(Promise.resolve()); - spyOn(poSync['poEventSourcingService'], 'syncSend').and.returnValue(Promise.resolve()); - poSync['emitter'] = { - next: () => {} - }; - spyOn(poSync['emitter'], 'next'); + poSync['emitter'] = { next: jasmine.createSpy('next') }; + await poSync.sync(); - expect(poSync['emitter']['next']).toHaveBeenCalled(); - }); - it('sync: should call canSync always', done => { - spyOn(poSync, 'canSync'); - poSync - .sync() - .then(() => { - expect(poSync['canSync']).toHaveBeenCalledTimes(1); - done(); - }) - .catch(err => { - fail(err); - }); + expect(poSync['emitter'].next).toHaveBeenCalled(); }); - it('canSync: should returns false if syncing is true and isSyncEnabled is false', () => { - poSync['syncing'] = true; - poSync['isSyncEnabled'] = false; + it('sync: syncError should be called when syncGet throws error', async () => { + spyOn(poSync, 'canSync').and.returnValue(true); + spyOn(poSync, 'startSync'); + spyOn(poSync, 'syncError'); + poEventSourcing.syncSend.and.returnValue(Promise.resolve()); + poEventSourcing.syncGet.and.returnValue(Promise.reject('Error')); - const canSync = poSync['canSync'](); + await poSync.sync(); - expect(canSync).toBeFalsy(); + expect(poSync['startSync']).toHaveBeenCalled(); + expect(poSync['syncError']).toHaveBeenCalled(); }); - it('canSync: should returns false if syncing is true and isSyncEnabled is true', () => { + it('canSync: should return false if syncing is true', () => { poSync['syncing'] = true; poSync['isSyncEnabled'] = true; - - const canSync = poSync['canSync'](); - - expect(canSync).toBeFalsy(); + expect(poSync['canSync']()).toBeFalsy(); }); - it('canSync: should returns false if syncing is false and isSyncEnabled is false', () => { + it('canSync: should return false if isSyncEnabled is false', () => { poSync['syncing'] = false; poSync['isSyncEnabled'] = false; - - const canSync = poSync['canSync'](); - - expect(canSync).toBeFalsy(); + expect(poSync['canSync']()).toBeFalsy(); }); - it('canSync: should returns false if network status is false and config is undefined', () => { + it('canSync: should return true if network status is true and config is undefined', () => { poSync['syncing'] = false; poSync['isSyncEnabled'] = true; poSync['config'] = undefined; + poNetworkServiceMock.getConnectionStatus.and.returnValue({ status: true, type: undefined } as any); - spyOn(poSync['poNetworkService'], 'getConnectionStatus').and.returnValue({ status: false, type: undefined }); - - const canSync = poSync['canSync'](); - expect(canSync).toBeFalsy(); + expect(poSync['canSync']()).toBeTruthy(); }); - it('canSync: should returns true if network status is true and config is undefined', () => { + it('canSync: should return false if network status is false', () => { poSync['syncing'] = false; poSync['isSyncEnabled'] = true; poSync['config'] = undefined; + poNetworkServiceMock.getConnectionStatus.and.returnValue({ status: false, type: undefined } as any); - spyOn(poSync['poNetworkService'], 'getConnectionStatus').and.returnValue({ status: true, type: undefined }); - - const canSync = poSync['canSync'](); - expect(canSync).toBeTruthy(); + expect(poSync['canSync']()).toBeFalsy(); }); - it('canSync: should returns false if network status is true, network type != ethernet', () => { + it('canSync: should return true if network type matches config type', () => { poSync['syncing'] = false; poSync['isSyncEnabled'] = true; - poSync['config'] = { type: PoNetworkType.ethernet }; - - spyOn(poSync['poNetworkService'], 'getConnectionStatus').and.returnValue({ - status: true, - type: PoNetworkType.wifi - }); - - const canSync = poSync['canSync'](); + poSync['config'] = { type: PoNetworkType.wifi }; + poNetworkServiceMock.getConnectionStatus.and.returnValue({ status: true, type: PoNetworkType.wifi } as any); - expect(canSync).toBeFalsy(); + expect(poSync['canSync']()).toBeTruthy(); }); - it('canSync: should returns true if network status is true, network type == wifi', () => { + it('canSync: should return false if network type does not match config type', () => { poSync['syncing'] = false; poSync['isSyncEnabled'] = true; - poSync['config'] = { type: PoNetworkType.wifi }; - spyOn(poSync['poNetworkService'], 'getConnectionStatus').and.returnValue({ - status: true, - type: PoNetworkType.wifi - }); - - const canSync = poSync['canSync'](); + poSync['config'] = { type: PoNetworkType.ethernet }; + poNetworkServiceMock.getConnectionStatus.and.returnValue({ status: true, type: PoNetworkType.wifi } as any); - expect(canSync).toBeTruthy(); + expect(poSync['canSync']()).toBeFalsy(); }); - it('canSync: should returns true if network status is true and isConfigIncludesType is true', () => { + it('canSync: should return true if config type is an array and includes current type', () => { poSync['syncing'] = false; poSync['isSyncEnabled'] = true; poSync['config'] = { type: [PoNetworkType.wifi, PoNetworkType._2g] }; + poNetworkServiceMock.getConnectionStatus.and.returnValue({ status: true, type: PoNetworkType.wifi } as any); - spyOn(poSync['poNetworkService'], 'getConnectionStatus').and.returnValue({ - status: true, - type: PoNetworkType.wifi - }); - - const canSync = poSync['canSync'](); - - expect(canSync).toBeTruthy(); + expect(poSync['canSync']()).toBeTruthy(); }); - it(`canSync: should returns false if network status is true, isConfiguredConnection and isConfigIncludesType is false`, () => { + it('canSync: should return false if config type is an array and does not include current type', () => { poSync['syncing'] = false; poSync['isSyncEnabled'] = true; poSync['config'] = { type: [PoNetworkType.wifi, PoNetworkType._2g] }; + poNetworkServiceMock.getConnectionStatus.and.returnValue({ status: true, type: PoNetworkType.ethernet } as any); - spyOn(poSync['poNetworkService'], 'getConnectionStatus').and.returnValue({ - status: true, - type: PoNetworkType.ethernet - }); - - const canSync = poSync['canSync'](); - - expect(canSync).toBeFalsy(); + expect(poSync['canSync']()).toBeFalsy(); }); - it('createSubscribe: should call sync and startTimer if timer is undefined', () => { - const fakeThis = { - timer: undefined, - sync: () => {}, - startTimer: () => {} - }; + it('createSubscribe: should not call sync if timer is undefined', () => { + poSync['timer'] = undefined; + spyOn(poSync, 'sync'); - spyOn(fakeThis, 'sync'); - spyOn(fakeThis, 'startTimer'); + poSync['createSubscribe'](); - poSync['createSubscribe'].call(fakeThis); - expect(fakeThis.timer).toBeUndefined(); - expect(fakeThis.sync).not.toHaveBeenCalled(); - expect(fakeThis.startTimer).not.toHaveBeenCalled(); + expect(poSync.sync).not.toHaveBeenCalled(); }); - it('createSubscribe: should call sync and startTimer', fakeAsync(() => { + it('createSubscribe: should call sync and startTimer when timer emits', fakeAsync(() => { spyOn(poSync, 'sync').and.returnValue(Promise.resolve()); spyOn(poSync, 'startTimer'); poSync['timer'] = of(0); - poSync['config'] = { type: poSync['poNetworkService']['getConnectionStatus']().type, period: 10 }; + poSync['config'] = { type: PoNetworkType.wifi, period: 10 }; poSync['createSubscribe'](); - tick(300); - expect(poSync['sync']).toHaveBeenCalled(); + expect(poSync.sync).toHaveBeenCalled(); expect(poSync['timer']).toBeNull(); expect(poSync['subscription']).toBeNull(); expect(poSync['startTimer']).toHaveBeenCalledWith(10); @@ -588,165 +470,92 @@ xdescribe('PoSyncService:', () => { it('finishSync: should set syncing to false and call finishSyncSubject.next', () => { poSync['syncing'] = true; - spyOn(poSync['finishSyncSubject'], 'next'); + spyOn(poSync['finishSyncSubject'], 'next'); poSync['finishSync'](); expect(poSync['syncing']).toBeFalsy(); - expect(poSync['finishSyncSubject']['next']).toHaveBeenCalled(); + expect(poSync['finishSyncSubject'].next).toHaveBeenCalled(); }); - describe('getOnePage: ', () => { - const myItems = [ - { id: 1, name: 'Customer Z' }, - { id: 2, name: 'Customer X' } - ]; - const response = of(new HttpResponse({ body: { hasNext: true, items: myItems }, status: 200 })); - const correctlyUrl = 'http://localhost:8200/api/v1/customers?pageSize=2&page='; - - it('should add sync fields to body.items and call http.get with correctly url', done => { - spyOn(poSync['poHttpClient'], 'get').and.returnValue(response); - poSync['config'] = { - type: PoNetworkType.wifi, - period: 10, - dataTransform: new PoDataMessage() - }; + it('startSync: should set syncing to true', () => { + poSync['syncing'] = false; + poSync['startSync'](); + expect(poSync['syncing']).toBeTruthy(); + }); - spyOn(poSync['poSchemaService'], 'updateAll').and.returnValue(Promise.resolve()); + it('startTimer: should call createSubscribe if period and isSyncEnabled are truthy', () => { + poSync['isSyncEnabled'] = true; + spyOn(poSync, 'createSubscribe'); - poSync['getOnePage'](customerSchema).subscribe(body => { - expect(body.items[0].id).toBe(1); - expect(body.items[0].name).toBe('Customer Z'); - expect(body.items[0].SyncUpdatedDateTime).toBeNull(); - expect(body.items[0].SyncExclusionDateTime).toBeNull(); - expect(body.items[0].SyncDeleted).toBeFalsy(); - expect(body.items[0].SyncStatus).toBe(2); - expect(poSync['poHttpClient']['get']).toHaveBeenCalledWith(`${correctlyUrl}1`); - done(); - }); - }); + poSync['startTimer'](5); - it('should call http.get with correctly url and the page 2', done => { - spyOn(poSync['poSchemaService'], 'updateAll').and.returnValue(Promise.resolve()); - spyOn(poSync['poHttpClient'], 'get').and.returnValue(response); - poSync['config'] = { - type: PoNetworkType.wifi, - period: 10, - dataTransform: new PoDataMessage() - }; - - poSync['getOnePage'](customerSchema, 2).subscribe(body => { - expect(poSync['poHttpClient']['get']).toHaveBeenCalledWith(`${correctlyUrl}2`); - done(); - }); - }); + expect(poSync['createSubscribe']).toHaveBeenCalled(); + expect(poSync['timer']).toBeDefined(); + }); - it('should call poSchemaService.updateAll with schema', done => { - spyOn(poSync['poHttpClient'], 'get').and.returnValue(response); - spyOn(poSync['poSchemaService'], 'updateAll').and.returnValue(Promise.resolve()); + it('startTimer: should not call createSubscribe if period is undefined', () => { + poSync['isSyncEnabled'] = true; + spyOn(poSync, 'createSubscribe'); - poSync['config'] = { - type: PoNetworkType.wifi, - period: 10, - dataTransform: new PoDataMessage() - }; + poSync['startTimer'](undefined); - poSync['getOnePage'](customerSchema).subscribe(body => { - expect(poSync['poSchemaService'].updateAll).toHaveBeenCalled(); - done(); - }); - }); + expect(poSync['createSubscribe']).not.toHaveBeenCalled(); }); - it('loadEntityData: should request data from schema url', done => { - const pageOneData = [ - { id: 1, name: 'Customer 1' }, - { id: 2, name: 'Customer 2' } - ]; - const pageTwoData = [ - { id: 3, name: 'Customer 3' }, - { id: 4, name: 'Customer 4' } - ]; - - poSync['config'] = { - type: PoNetworkType.wifi, - period: 10, - dataTransform: new PoDataMessage() - }; + it('startTimer: should not call createSubscribe if period is zero', () => { + poSync['isSyncEnabled'] = true; + spyOn(poSync, 'createSubscribe'); - spyOn(poSync, 'getOnePage').and.returnValues( - of({ hasNext: true, items: pageOneData }), - of({ hasNext: false, items: pageTwoData }) - ); + poSync['startTimer'](0); - poSync['loadEntityData'](customerSchema).subscribe(entity => { - expect(entity.entity).toBe(customerSchema.name); - expect(entity.data).toEqual([...pageOneData, ...pageTwoData]); - done(); - }); + expect(poSync['createSubscribe']).not.toHaveBeenCalled(); }); - it('reactiveSync: should call unsubscribe when is defined and network status is undefined', () => { - const fakeThis = { - subscription: { unsubscribe: () => {} }, - poNetworkService: { onChange: () => of({ type: undefined }) } - }; + it('startTimer: should not call createSubscribe if isSyncEnabled is false', () => { + poSync['isSyncEnabled'] = false; + spyOn(poSync, 'createSubscribe'); - spyOn(fakeThis.subscription, 'unsubscribe'); + poSync['startTimer'](5); - poSync['reactiveSync'].call(fakeThis); + expect(poSync['createSubscribe']).not.toHaveBeenCalled(); + }); - expect(fakeThis.subscription.unsubscribe).toHaveBeenCalled(); + it('syncError: should call finishSync', () => { + spyOn(poSync, 'finishSync'); + poSync['syncError'](); + expect(poSync['finishSync']).toHaveBeenCalled(); }); - it('reactiveSync: should call start, sync and not unsubscribe', () => { - const periodConfig = jasmine.any(Number); + it('reactiveSync: should call startTimer and sync when network status is true', () => { + const networkSubject = new Subject(); + poNetworkServiceMock.onChange.and.returnValue(networkSubject.asObservable()); - const fakeThis = { - subscription: { unsubscribe: () => {} }, - startTimer: (period: number) => {}, - config: { period: periodConfig }, - sync: () => {}, - poNetworkService: { - onChange: () => of({ status: true }) - } - }; + spyOn(poSync, 'startTimer'); + spyOn(poSync, 'sync'); - spyOn(fakeThis.subscription, 'unsubscribe'); - spyOn(fakeThis, 'startTimer'); - spyOn(fakeThis, 'sync'); + poSync['config'] = { period: 10 } as any; + poSync['reactiveSync'](); - poSync['reactiveSync'].call(fakeThis); + networkSubject.next({ status: true }); - expect(fakeThis.subscription.unsubscribe).not.toHaveBeenCalled(); - expect(fakeThis.startTimer).toHaveBeenCalledWith(periodConfig); - expect(fakeThis.sync).toHaveBeenCalled(); + expect(poSync['startTimer']).toHaveBeenCalledWith(10); + expect(poSync.sync).toHaveBeenCalled(); }); - it(`reactiveSync: should not call unsubscribe, startTimer and sync when subscription and - networkStatus is undefined`, () => { - const fakeThis = { - subscription: '', - unsubscribe: () => {}, - startTimer: () => {}, - sync: () => {}, - poNetworkService: { onChange: () => of({ type: undefined }) } - }; + it('reactiveSync: should call subscription.unsubscribe when network status is falsy and subscription exists', () => { + const networkSubject = new Subject(); + poNetworkServiceMock.onChange.and.returnValue(networkSubject.asObservable()); - spyOn(fakeThis, 'unsubscribe'); - spyOn(fakeThis, 'startTimer'); - spyOn(fakeThis, 'sync'); + poSync['subscription'] = { unsubscribe: jasmine.createSpy('unsubscribe') } as any; + poSync['reactiveSync'](); - poSync['reactiveSync'].call(fakeThis); + networkSubject.next({ status: false }); - expect(fakeThis.unsubscribe).not.toHaveBeenCalled(); - expect(fakeThis.startTimer).not.toHaveBeenCalled(); - expect(fakeThis.sync).not.toHaveBeenCalled(); + expect(poSync['subscription'].unsubscribe).toHaveBeenCalled(); }); it('saveSchemas: should call poSchemaDefinitionService.getAll and saveAll', async () => { - spyOn(PoSchemaUtil, 'getLastSync'); - const schemasStorage: Array = [ { idField: '', @@ -760,136 +569,85 @@ xdescribe('PoSyncService:', () => { ]; poSync['schemas'] = [customerSchema, userSchema]; - spyOn(poSync['poSchemaDefinitionService'], 'getAll').and.returnValue(schemasStorage); - spyOn(poSync['poSchemaDefinitionService'], 'saveAll'); + poSchemaDefinition.getAll.and.returnValue(Promise.resolve(schemasStorage) as any); + poSchemaDefinition.saveAll.and.returnValue(Promise.resolve([]) as any); + spyOn(PoSchemaUtil, 'getLastSync'); await poSync['saveSchemas'](); - expect(poSync['poSchemaDefinitionService']['saveAll']).toHaveBeenCalledWith([customerSchema, userSchema]); - expect(poSync['poSchemaDefinitionService']['getAll']).toHaveBeenCalled(); + expect(poSchemaDefinition.saveAll).toHaveBeenCalledWith([customerSchema, userSchema]); + expect(poSchemaDefinition.getAll).toHaveBeenCalled(); }); - it('saveSchemas: should update lastSync of schemas and call PoSchemaUtil.getLastSync', async () => { - const dateNow = new Date().toISOString(); - - spyOn(PoSchemaUtil, 'getLastSync').and.returnValue(dateNow); - - const schemasStorage: Array = [ - { - idField: '', - name: '', - getUrlApi: '', - diffUrlApi: 'http://localhost:8200/api/v1/customers/diff', - fields: ['code', 'name'], - pageSize: 20, - deletedField: 'deleted', - lastSync: dateNow - }, - { - idField: 'code', - name: 'Users', - getUrlApi: 'http://localhost:8200/api/v1/users', - diffUrlApi: 'http://localhost:8200/api/v1/users/diff', - fields: ['code', 'name'], - pageSize: 20, - deletedField: 'deleted', - lastSync: dateNow - } + describe('getOnePage:', () => { + const myItems = [ + { id: 1, name: 'Customer Z' }, + { id: 2, name: 'Customer X' } ]; - poSync['schemas'] = [customerSchema, userSchema]; - - spyOn(poSync['poSchemaDefinitionService'], 'getAll').and.returnValue(schemasStorage); - spyOn(poSync['poSchemaDefinitionService'], 'saveAll'); - - await poSync['saveSchemas'](); - - expect(PoSchemaUtil.getLastSync).toHaveBeenCalledWith(schemasStorage, poSync['schemas'][0].name); - expect(PoSchemaUtil.getLastSync).toHaveBeenCalledWith(schemasStorage, poSync['schemas'][1].name); - expect(poSync['schemas'][0].lastSync === dateNow); - expect(poSync['schemas'][1].lastSync === dateNow); - }); - - it('startSync: should set syncing to true', () => { - poSync['syncing'] = false; - poSync['startSync'](); - expect(poSync['syncing']).toBeTruthy(); - }); - - it(`startTimer: should call createSubscribe and set timer with observable emitted in 5000ms if period is defined and - isSyncEnabled is true`, () => { - scheduler.run(helpers => { - const { expectObservable } = helpers; - const period = 5; - poSync['isSyncEnabled'] = true; - const expected = '5000ms (a|)'; - - spyOn(poSync, 'createSubscribe'); - - poSync['startTimer'](period); + it('should add sync fields to body items and call http.get with correctly url', done => { + const response = of({ body: { hasNext: true, items: myItems } }); + http.get.and.returnValue(response as any); + poSchemaService.updateAll.and.returnValue(Promise.resolve()); + poSync['config'] = { type: PoNetworkType.wifi, period: 10, dataTransform: new PoDataMessage() }; - expectObservable(poSync['timer']).toBe(expected, { a: 0 }); - expect(poSync['createSubscribe']).toHaveBeenCalled(); + poSync['getOnePage'](customerSchema).subscribe(body => { + expect(body.items[0].SyncUpdatedDateTime).toBeNull(); + expect(body.items[0].SyncExclusionDateTime).toBeNull(); + expect(body.items[0].SyncDeleted).toBeFalsy(); + expect(body.items[0].SyncStatus).toBe(2); + expect(http.get).toHaveBeenCalledWith('http://localhost:8200/api/v1/customers?pageSize=2&page=1'); + done(); + }); }); - }); - it('startTimer: should not call createSubscribe if period of syncronize is undefined and isSyncEnabled is true.', () => { - poSync['isSyncEnabled'] = true; + it('should call http.get with page 2', done => { + const response = of({ body: { hasNext: true, items: myItems } }); + http.get.and.returnValue(response as any); + poSchemaService.updateAll.and.returnValue(Promise.resolve()); + poSync['config'] = { type: PoNetworkType.wifi, period: 10, dataTransform: new PoDataMessage() }; - spyOn(poSync, 'createSubscribe'); - - poSync['startTimer'](undefined); - - expect(poSync['createSubscribe']).not.toHaveBeenCalled(); - }); - - it('startTimer: should not call createSubscribe if period of syncronize is undefined and isSyncEnabled is false.', () => { - poSync['isSyncEnabled'] = false; - - spyOn(poSync, 'createSubscribe'); - - poSync['startTimer'](undefined); - - expect(poSync['createSubscribe']).not.toHaveBeenCalled(); - }); - - it('startTimer: should not call createSubscribe if period of syncronize is defined and isSyncEnabled is false.', () => { - poSync['isSyncEnabled'] = false; - const period = 1; - - spyOn(poSync, 'createSubscribe'); - - poSync['startTimer'](period); - - expect(poSync['createSubscribe']).not.toHaveBeenCalled(); - }); - - it('startTimer: should not call createSubscribe if period of syncronize is zero and isSyncEnabled is true.', () => { - poSync['isSyncEnabled'] = true; - - spyOn(poSync, 'createSubscribe'); + poSync['getOnePage'](customerSchema, 2).subscribe(() => { + expect(http.get).toHaveBeenCalledWith('http://localhost:8200/api/v1/customers?pageSize=2&page=2'); + done(); + }); + }); - poSync['startTimer'](0); + it('should call poSchemaService.updateAll', done => { + const response = of({ body: { hasNext: true, items: myItems } }); + http.get.and.returnValue(response as any); + poSchemaService.updateAll.and.returnValue(Promise.resolve()); + poSync['config'] = { type: PoNetworkType.wifi, period: 10, dataTransform: new PoDataMessage() }; - expect(poSync['createSubscribe']).not.toHaveBeenCalled(); + poSync['getOnePage'](customerSchema).subscribe(() => { + expect(poSchemaService.updateAll).toHaveBeenCalled(); + done(); + }); + }); }); - it('startTimer: should not call createSubscribe if period of syncronize is zero and isSyncEnabled is false.', () => { - poSync['isSyncEnabled'] = false; - - spyOn(poSync, 'createSubscribe'); - - poSync['startTimer'](0); - - expect(poSync['createSubscribe']).not.toHaveBeenCalled(); - }); + it('loadEntityData: should request data from schema url', done => { + const pageOneData = [ + { id: 1, name: 'Customer 1' }, + { id: 2, name: 'Customer 2' } + ]; + const pageTwoData = [ + { id: 3, name: 'Customer 3' }, + { id: 4, name: 'Customer 4' } + ]; - it('syncError: should call finishSync', () => { - spyOn(poSync, 'finishSync'); + poSync['config'] = { type: PoNetworkType.wifi, period: 10, dataTransform: new PoDataMessage() }; - poSync['syncError'](); + spyOn(poSync, 'getOnePage').and.returnValues( + of({ hasNext: true, items: pageOneData }), + of({ hasNext: false, items: pageTwoData }) + ); - expect(poSync['finishSync']).toHaveBeenCalled(); + poSync['loadEntityData'](customerSchema).subscribe(entity => { + expect(entity.entity).toBe(customerSchema.name); + expect(entity.data).toEqual([...pageOneData, ...pageTwoData]); + done(); + }); }); }); }); diff --git a/projects/sync/src/test.ts b/projects/sync/src/test.ts index 8f714a3c85..89c3949e89 100644 --- a/projects/sync/src/test.ts +++ b/projects/sync/src/test.ts @@ -1,11 +1,15 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files -import 'zone.js'; -import 'zone.js/testing'; +import { NgModule, provideZoneChangeDetection } from '@angular/core'; import { getTestBed } from '@angular/core/testing'; import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing'; +@NgModule({ + providers: [provideZoneChangeDetection()] +}) +class AppTestingModule {} + // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment(BrowserTestingModule, platformBrowserTesting(), { +getTestBed().initTestEnvironment([BrowserTestingModule, AppTestingModule], platformBrowserTesting(), { teardown: { destroyAfterEach: false } }); diff --git a/projects/sync/tsconfig.lib.json b/projects/sync/tsconfig.lib.json index e1f7191ad3..a422c21d91 100644 --- a/projects/sync/tsconfig.lib.json +++ b/projects/sync/tsconfig.lib.json @@ -12,7 +12,7 @@ "angularCompilerOptions": { "strictMetadataEmit": true, "skipTemplateCodegen": true, - "fullTemplateTypeCheck": true + "strictTemplates": false }, "exclude": ["node_modules", "src/test.ts", "**/*.spec.ts"] } diff --git a/projects/sync/tsconfig.schematics.json b/projects/sync/tsconfig.schematics.json index 529c70bcb4..a4df1c46f9 100644 --- a/projects/sync/tsconfig.schematics.json +++ b/projects/sync/tsconfig.schematics.json @@ -1,11 +1,10 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "baseUrl": "../..", "lib": ["es2022", "dom"], "declaration": true, - "module": "commonjs", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "noEmitOnError": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": false, diff --git a/projects/sync/tsconfig.spec.json b/projects/sync/tsconfig.spec.json index 519c167a68..92ff656bd5 100644 --- a/projects/sync/tsconfig.spec.json +++ b/projects/sync/tsconfig.spec.json @@ -6,5 +6,8 @@ "skipLibCheck": true }, "files": ["src/test.ts"], - "include": ["**/*.spec.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.d.ts"], + "angularCompilerOptions": { + "strictTemplates": false + } } diff --git a/projects/templates/.eslintrc.json b/projects/templates/.eslintrc.json deleted file mode 100644 index fea366f397..0000000000 --- a/projects/templates/.eslintrc.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "extends": "../../.eslintrc.json", - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": ["projects/templates/tsconfig.lib.json", "projects/templates/tsconfig.spec.json"], - "createDefaultProgram": true - }, - "plugins": ["sonarjs"], - "rules": { - "@angular-eslint/component-selector": [ - "error", - { - "type": ["element", "attribute"], - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/directive-class-suffix": "off", - "@angular-eslint/directive-selector": [ - "error", - { - "type": "attribute", - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/no-input-rename": "off", - "@angular-eslint/no-output-rename": "off", - "@typescript-eslint/array-type": [ - "error", - { - "default": "generic" - } - ], - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "off", - { - "types": { - "String": { - "message": "Use string instead", - "fixWith": "string" - }, - "Boolean": { - "message": "Use boolean instead", - "fixWith": "boolean" - }, - "Number": { - "message": "Use number instead", - "fixWith": "number" - } - } - } - ], - "@typescript-eslint/consistent-type-assertions": "off", - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/dot-notation": "off", - "@typescript-eslint/explicit-member-accessibility": [ - "off", - { - "accessibility": "explicit" - } - ], - "@typescript-eslint/member-delimiter-style": [ - "off", - { - "multiline": { - "delimiter": "none", - "requireLast": true - }, - "singleline": { - "delimiter": "semi", - "requireLast": false - } - } - ], - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": [ - "off", - { - "ignoreParameters": true - } - ], - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "@typescript-eslint/no-var-requires": "error", - "@typescript-eslint/prefer-for-of": "off", - "@typescript-eslint/quotes": [ - "off", - "single", - { - "allowTemplateLiterals": true - } - ], - "@typescript-eslint/require-array-sort-compare": [ - "error", - { - "ignoreStringArrays": true - } - ], - "@typescript-eslint/semi": ["off", null], - "@typescript-eslint/type-annotation-spacing": "off", - "arrow-parens": ["off", "always"], - "brace-style": ["off", "off"], - "default-case-last": "error", - "dot-notation": "off", - "eol-last": "off", - "id-blacklist": "off", - "id-match": "off", - "indent": "off", - "linebreak-style": "off", - "max-len": "off", - "max-lines-per-function": [ - "off", - { - "max": 200 - } - ], - "max-params": [ - "error", - { - "max": 8 - } - ], - "new-parens": "off", - "newline-per-chained-call": "off", - "no-empty-function": "off", - "no-empty-pattern": "off", - "no-extra-parens": "off", - "no-extra-semi": "error", - "no-irregular-whitespace": "off", - "no-multi-str": "error", - "no-self-assign": "error", - "no-shadow": "off", - "no-trailing-spaces": "off", - "no-underscore-dangle": "off", - "no-unused-expressions": "error", - "no-use-before-define": "off", - "object-shorthand": "off", - "padded-blocks": [ - "off", - { - "blocks": "never" - }, - { - "allowSingleLineBlocks": true - } - ], - "prefer-arrow/prefer-arrow-functions": "off", - "quote-props": "off", - "semi": "off", - "sonarjs/cognitive-complexity": "off", - "sonarjs/max-switch-cases": "error", - "sonarjs/no-all-duplicated-branches": "error", - "sonarjs/no-collapsible-if": "error", - "sonarjs/no-collection-size-mischeck": "error", - "sonarjs/no-duplicate-string": "off", - "sonarjs/no-duplicated-branches": "off", - "sonarjs/no-element-overwrite": "error", - "sonarjs/no-identical-conditions": "error", - "sonarjs/no-identical-expressions": "error", - "sonarjs/no-identical-functions": "off", - "sonarjs/no-inverted-boolean-check": "error", - "sonarjs/no-one-iteration-loop": "off", - "sonarjs/no-redundant-boolean": "error", - "sonarjs/no-redundant-jump": "error", - "sonarjs/no-same-line-conditional": "error", - "sonarjs/no-small-switch": "error", - "sonarjs/no-unused-collection": "error", - "sonarjs/no-use-of-empty-return-value": "error", - "sonarjs/no-useless-catch": "error", - "sonarjs/prefer-immediate-return": "error", - "space-before-function-paren": "off", - "space-in-parens": ["off", "never"] - } - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/projects/templates/karma.conf.js b/projects/templates/karma.conf.js index d847eb4547..e0d1c4119d 100644 --- a/projects/templates/karma.conf.js +++ b/projects/templates/karma.conf.js @@ -9,8 +9,7 @@ module.exports = function (config) { require('karma-jasmine'), require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), - require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('karma-coverage') ], client: { clearContext: false // leave Jasmine Spec Runner output visible in browser diff --git a/projects/templates/package.json b/projects/templates/package.json index d80c0725ab..38d0c30d5b 100644 --- a/projects/templates/package.json +++ b/projects/templates/package.json @@ -16,14 +16,12 @@ "tslib": "^2.6.2" }, "peerDependencies": { - "@angular/animations": "^21", - "@angular/common": "^21", - "@angular/compiler": "^21", - "@angular/core": "^21", - "@angular/forms": "^21", - "@angular/platform-browser": "^21", - "@angular/platform-browser-dynamic": "^21", - "@angular/router": "^21", + "@angular/common": "^22", + "@angular/compiler": "^22", + "@angular/core": "^22", + "@angular/forms": "^22", + "@angular/platform-browser": "^22", + "@angular/router": "^22", "@po-ui/ng-components": "0.0.0-PLACEHOLDER", "rxjs": "~7.8.1", "zone.js": "~0.15.0" diff --git a/projects/templates/schematics/collection.json b/projects/templates/schematics/collection.json index 6a0c1fa97a..25184461c2 100644 --- a/projects/templates/schematics/collection.json +++ b/projects/templates/schematics/collection.json @@ -5,46 +5,6 @@ "description": "Add my library to the project.", "factory": "./ng-add/index", "schema": "./ng-add/schema.json" - }, - "po-page-dynamic-table": { - "description": "Create a component with po-page-dynamic-table", - "factory": "./ng-generate/po-page-dynamic-table/index", - "schema": "./ng-generate/po-page-dynamic-table/schema.json" - }, - "po-page-dynamic-edit": { - "description": "Create a component with po-page-dynamic-edit", - "factory": "./ng-generate/po-page-dynamic-edit/index", - "schema": "./ng-generate/po-page-dynamic-edit/schema.json" - }, - "po-page-dynamic-detail": { - "description": "Create a component with po-page-dynamic-detail", - "factory": "./ng-generate/po-page-dynamic-detail/index", - "schema": "./ng-generate/po-page-dynamic-detail/schema.json" - }, - "po-page-dynamic-search": { - "description": "Create a component with po-page-dynamic-search", - "factory": "./ng-generate/po-page-dynamic-search/index", - "schema": "./ng-generate/po-page-dynamic-search/schema.json" - }, - "po-page-job-scheduler": { - "description": "Create a component with po-page-job-scheduler", - "factory": "./ng-generate/po-page-job-scheduler/index", - "schema": "./ng-generate/po-page-job-scheduler/schema.json" - }, - "po-page-blocked-user": { - "description": "Create a component with po-page-blocked-user", - "factory": "./ng-generate/po-page-blocked-user/index", - "schema": "./ng-generate/po-page-blocked-user/schema.json" - }, - "po-page-change-password": { - "description": "Create a component with po-page-change-password", - "factory": "./ng-generate/po-page-change-password/index", - "schema": "./ng-generate/po-page-change-password/schema.json" - }, - "po-page-login": { - "description": "Create a component with po-page-login", - "factory": "./ng-generate/po-page-login/index", - "schema": "./ng-generate/po-page-login/schema.json" } } } diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-blocked-user/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index bff95fdbbe..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-blocked-user/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 4e953e6dd2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,33 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageBlockedUserModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageBlockedUserModule - ], - providers: [provideHttpClient()] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-blocked-user/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index b91a580769..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,21 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { PoPageBlockedUserModule } from '@po-ui/ng-templates'; - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageBlockedUserModule, - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index bff95fdbbe..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index b6c5463286..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,34 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageBlockedUserModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageBlockedUserModule - ], - providers: [provideHttpClient()], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 021ed143f7..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index 4ab8315236..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoPageBlockedUserModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoPageBlockedUserModule,<% if (routing) { %> - <%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/index.spec.ts b/projects/templates/schematics/ng-generate/po-page-blocked-user/index.spec.ts deleted file mode 100644 index aa154e03e2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/index.spec.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-blocked-user:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic( - 'po-page-blocked-user', - { ...componentOptions, name: componentName }, - appTree - ); - - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-blocked-user', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-blocked-user', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-blocked-user', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-blocked-user', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-blocked-user', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-blocked-user', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-blocked-user', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-blocked-user', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-blocked-user', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-blocked-user', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-blocked-user', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/index.ts b/projects/templates/schematics/ng-generate/po-page-blocked-user/index.ts deleted file mode 100644 index f6d28becd1..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent } from '@po-ui/ng-schematics/build-component'; - -import { Schema as ComponentOptions } from './schema'; - -/** Scaffolds a new component with */ -export default function (options: ComponentOptions): Rule { - return chain([createPageBlockedUserComponent(options)]); -} - -function createPageBlockedUserComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/schema.json b/projects/templates/schematics/ng-generate/po-page-blocked-user/schema.json deleted file mode 100644 index 224c57c741..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/schema.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageBlockedUser", - "title": "Page Blocked User Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "alias": "S", - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "alias": "p", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - } - }, - "required": ["name"] -} diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/schema.ts b/projects/templates/schematics/ng-generate/po-page-blocked-user/schema.ts deleted file mode 100644 index 0e5e0a349d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-blocked-user/schema.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema {} diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-change-password/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-change-password/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index d6bcb9ba2d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-change-password/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 56429ded66..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,33 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageChangePasswordModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageChangePasswordModule - ], - providers: [provideHttpClient()] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-change-password/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index d288044213..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,21 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { PoPageChangePasswordModule } from '@po-ui/ng-templates'; - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageChangePasswordModule, - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index d6bcb9ba2d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index e4ca00dc7d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,34 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageChangePasswordModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageChangePasswordModule - ], - providers: [provideHttpClient()], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 021ed143f7..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index eca5dcff1c..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoPageChangePasswordModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoPageChangePasswordModule,<% if (routing) { %> - <%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/index.spec.ts b/projects/templates/schematics/ng-generate/po-page-change-password/index.spec.ts deleted file mode 100644 index 3744b1f20b..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/index.spec.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-change-password:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic( - 'po-page-change-password', - { ...componentOptions, name: componentName }, - appTree - ); - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-change-password', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-change-password', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-change-password', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-change-password', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-change-password', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-change-password', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-change-password', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-change-password', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-change-password', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-change-password', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-change-password', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/index.ts b/projects/templates/schematics/ng-generate/po-page-change-password/index.ts deleted file mode 100644 index 6cd8cedb0e..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent } from '@po-ui/ng-schematics/build-component'; - -import { Schema as ComponentOptions } from './schema'; - -/** Scaffolds a new component with */ -export default function (options: ComponentOptions): Rule { - return chain([createPageChangePasswordComponent(options)]); -} - -function createPageChangePasswordComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/schema.json b/projects/templates/schematics/ng-generate/po-page-change-password/schema.json deleted file mode 100644 index cb215dac8c..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/schema.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageChangePassword", - "title": "Page Change Password Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "alias": "S", - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "alias": "p", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - } - }, - "required": ["name"] -} diff --git a/projects/templates/schematics/ng-generate/po-page-change-password/schema.ts b/projects/templates/schematics/ng-generate/po-page-change-password/schema.ts deleted file mode 100644 index 0e5e0a349d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-change-password/schema.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema {} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 832b587fcf..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,5 +0,0 @@ - - diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 499addfd9f..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,33 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageDynamicDetailModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageDynamicDetailModule - ], - providers: [provideHttpClient()] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index dfcf705d11..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,28 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { PoPageDynamicDetailModule, PoPageDynamicDetailField } from '@po-ui/ng-templates'; - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageDynamicDetailModule - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - // PLEASE ADD THE API URL SERVICE HERE - readonly apiService = 'http://localhost:8080/api'; - - readonly fields: Array = [ - { property: 'id', label: 'User ID', key: true }, - ]; - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 832b587fcf..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,5 +0,0 @@ - - diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 45f5a0d6a6..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,34 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageDynamicDetailModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageDynamicDetailModule - ], - providers: [provideHttpClient()], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 8c1009db08..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,24 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { PoPageDynamicDetailField } from '@po-ui/ng-templates'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - // PLEASE ADD THE API URL SERVICE HERE - readonly apiService = 'http://localhost:8080/api'; - - readonly fields: Array = [ - { property: 'id', label: 'User ID', key: true }, - ]; - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index 20be42a154..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoPageDynamicDetailModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoPageDynamicDetailModule,<% if (routing) { %> - <%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/index.spec.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/index.spec.ts deleted file mode 100644 index 812da56c14..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/index.spec.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-dynamic-detail:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic( - 'po-page-dynamic-detail', - { ...componentOptions, name: componentName }, - appTree - ); - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-dynamic-detail', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-dynamic-detail', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-dynamic-detail', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-dynamic-detail', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-dynamic-detail', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-dynamic-detail', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-dynamic-detail', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-dynamic-detail', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-dynamic-detail', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-dynamic-detail', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-dynamic-detail', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/index.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/index.ts deleted file mode 100644 index 9339554327..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent } from '@po-ui/ng-schematics/build-component'; - -import { Schema as ComponentOptions } from './schema'; - -/** Scaffolds a new component with */ -export default function (options: ComponentOptions): Rule { - return chain([createPageDynamicDetailComponent(options)]); -} - -function createPageDynamicDetailComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/schema.json b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/schema.json deleted file mode 100644 index caff096c30..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/schema.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageDynamicDetail", - "title": "Page Dynamic Detail Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "alias": "S", - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "alias": "p", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - } - }, - "required": ["name"] -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/schema.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-detail/schema.ts deleted file mode 100644 index 0e5e0a349d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-detail/schema.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema {} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index c151d1a85b..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,5 +0,0 @@ - - diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 816e4b789e..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,33 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageDynamicEditModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageDynamicEditModule - ], - providers: [provideHttpClient()] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 175cbbb6c8..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,30 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { CommonModule } from '@angular/common'; - -import { PoPageDynamicEditModule } from '@po-ui/ng-templates'; -import { PoPageDynamicEditField } from '@po-ui/ng-templates'; - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageDynamicEditModule, - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - // PLEASE ADD THE API URL SERVICE HERE - readonly apiService = 'http://localhost:8080/api'; - - readonly fields: Array = [ - { property: 'id', label: 'User ID', key: true }, - ]; - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index c151d1a85b..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,5 +0,0 @@ - - diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index dd4b4e798e..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,34 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageDynamicEditModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageDynamicEditModule - ], - providers: [provideHttpClient()], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index a39deb9e81..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,24 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { PoPageDynamicEditField } from '@po-ui/ng-templates'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - // PLEASE ADD THE API URL SERVICE HERE - readonly apiService = 'http://localhost:8080/api'; - - readonly fields: Array = [ - { property: 'id', label: 'User ID', key: true }, - ]; - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index 54435e6e57..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoPageDynamicEditModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoPageDynamicEditModule,<% if (routing) { %> - <%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/index.spec.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/index.spec.ts deleted file mode 100644 index e692d04f7c..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/index.spec.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-dynamic-edit:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic( - 'po-page-dynamic-edit', - { ...componentOptions, name: componentName }, - appTree - ); - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-dynamic-edit', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-dynamic-edit', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-dynamic-edit', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-dynamic-edit', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-dynamic-edit', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-dynamic-edit', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-dynamic-edit', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-dynamic-edit', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-dynamic-edit', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-dynamic-edit', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-dynamic-edit', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/index.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/index.ts deleted file mode 100644 index bbd17c0903..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent } from '@po-ui/ng-schematics/build-component'; - -import { Schema as ComponentOptions } from './schema'; - -/** Scaffolds a new component with */ -export default function (options: ComponentOptions): Rule { - return chain([createPageDynamicEditComponent(options)]); -} - -function createPageDynamicEditComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/schema.json b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/schema.json deleted file mode 100644 index 3239d1a31a..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/schema.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageDynamicEdit", - "title": "Page Dynamic Edit Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "alias": "S", - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "alias": "p", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - } - }, - "required": ["name"] -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/schema.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-edit/schema.ts deleted file mode 100644 index 0e5e0a349d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-edit/schema.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema {} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-dynamic-search/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-dynamic-search/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 5293e89aaa..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,5 +0,0 @@ - - diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-search/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 6a1a71ee9f..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,33 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageDynamicSearchModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageDynamicSearchModule - ], - providers: [provideHttpClient()] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-search/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 12066e982e..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,35 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { PoPageDynamicSearchModule } from '@po-ui/ng-templates'; - -import { PoPageAction, PoDynamicFormField } from '@po-ui/ng-components'; - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageDynamicSearchModule, - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - readonly actions: Array = [ - { label: 'Adicionar', action: this.add.bind(this) } - ]; - - readonly filter: Array = [ - { property: 'name' } - ]; - - constructor() { } - - ngOnInit() { } - - add() { - alert('ADD'); - } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 5293e89aaa..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,5 +0,0 @@ - - diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 7fb5ca80aa..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,34 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageDynamicSearchModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageDynamicSearchModule - ], - providers: [provideHttpClient()], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 75ea9f7aaf..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,29 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { PoPageAction, PoDynamicFormField } from '@po-ui/ng-components'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - readonly actions: Array = [ - { label: 'Adicionar', action: this.add.bind(this) } - ]; - - readonly filter: Array = [ - { property: 'name' } - ]; - - constructor() { } - - ngOnInit() { } - - add() { - alert('ADD'); - } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index ab0d96885a..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoPageDynamicSearchModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoPageDynamicSearchModule,<% if (routing) { %> - <%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/index.spec.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-search/index.spec.ts deleted file mode 100644 index 602d1ddb5c..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/index.spec.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-dynamic-search:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic( - 'po-page-dynamic-search', - { ...componentOptions, name: componentName }, - appTree - ); - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-dynamic-search', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-dynamic-search', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-dynamic-search', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-dynamic-search', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-dynamic-search', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-dynamic-search', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-dynamic-search', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-dynamic-search', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-dynamic-search', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-dynamic-search', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-dynamic-search', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/index.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-search/index.ts deleted file mode 100644 index 0668538b7a..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent } from '@po-ui/ng-schematics/build-component'; - -import { Schema as ComponentOptions } from './schema'; - -/** Scaffolds a new component with */ -export default function (options: ComponentOptions): Rule { - return chain([createPageDynamicSearchComponent(options)]); -} - -function createPageDynamicSearchComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/schema.json b/projects/templates/schematics/ng-generate/po-page-dynamic-search/schema.json deleted file mode 100644 index da4609117c..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/schema.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageDynamicSearch", - "title": "Page Dynamic Search Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "alias": "S", - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "alias": "p", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - } - }, - "required": ["name"] -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-search/schema.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-search/schema.ts deleted file mode 100644 index 0e5e0a349d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-search/schema.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema {} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-dynamic-table/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-dynamic-table/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 80ab266341..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,5 +0,0 @@ - - diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-table/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index f89632cc51..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,33 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageDynamicTableModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageDynamicTableModule - ], - providers: [provideHttpClient()] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-table/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index d13df7e21a..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,27 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { PoPageDynamicTableModule } from '@po-ui/ng-templates'; -import { PoPageDynamicTableActions } from '@po-ui/ng-templates'; - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageDynamicTableModule, - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - // PLEASE ADD THE API URL SERVICE HERE - readonly apiService = 'http://localhost:8080/api'; - - readonly actions: PoPageDynamicTableActions = { }; - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 80ab266341..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,5 +0,0 @@ - - diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index fb2dd2f3c8..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,34 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageDynamicTableModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageDynamicTableModule - ], - providers: [provideHttpClient()], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index ca3eacb583..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,22 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { PoPageDynamicTableActions } from '@po-ui/ng-templates'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - // PLEASE ADD THE API URL SERVICE HERE - readonly apiService = 'http://localhost:8080/api'; - - readonly actions: PoPageDynamicTableActions = { }; - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index 87f5db5348..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoPageDynamicTableModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoPageDynamicTableModule,<% if (routing) { %> - <%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/index.spec.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-table/index.spec.ts deleted file mode 100644 index 9412be080f..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/index.spec.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-dynamic-table:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic( - 'po-page-dynamic-table', - { ...componentOptions, name: componentName }, - appTree - ); - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-dynamic-table', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-dynamic-table', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-dynamic-table', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-dynamic-table', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-dynamic-table', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-dynamic-table', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-dynamic-table', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-dynamic-table', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-dynamic-table', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-dynamic-table', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-dynamic-table', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/index.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-table/index.ts deleted file mode 100644 index 5d2392a7db..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent } from '@po-ui/ng-schematics/build-component'; - -import { Schema as ComponentOptions } from './schema'; - -/** Scaffolds a new component with */ -export default function (options: ComponentOptions): Rule { - return chain([createPageDynamicTableComponent(options)]); -} - -function createPageDynamicTableComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/schema.json b/projects/templates/schematics/ng-generate/po-page-dynamic-table/schema.json deleted file mode 100644 index 0e325e6778..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/schema.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageDynamicTable", - "title": "Page Dynamic Table Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "alias": "S", - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "alias": "p", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - } - }, - "required": ["name"] -} diff --git a/projects/templates/schematics/ng-generate/po-page-dynamic-table/schema.ts b/projects/templates/schematics/ng-generate/po-page-dynamic-table/schema.ts deleted file mode 100644 index 0e5e0a349d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-dynamic-table/schema.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema {} diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-job-scheduler/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-job-scheduler/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index a0f6a54bd2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,4 +0,0 @@ - - \ No newline at end of file diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-job-scheduler/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index dabeb530d9..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,33 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageJobSchedulerModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageJobSchedulerModule - ], - providers: [provideHttpClient()] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-job-scheduler/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 253d885129..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,24 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { PoPageJobSchedulerModule } from '@po-ui/ng-templates'; - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageJobSchedulerModule, - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - // PLEASE ADD THE API URL SERVICE HERE - readonly apiService = 'http://localhost:8080/api'; - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index a0f6a54bd2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,4 +0,0 @@ - - \ No newline at end of file diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 6d5b91b1ad..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,34 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageJobSchedulerModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageJobSchedulerModule - ], - providers: [provideHttpClient()], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 3c4ebde1fb..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,18 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - // PLEASE ADD THE API URL SERVICE HERE - readonly apiService = 'http://localhost:8080/api'; - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index a84063cc15..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoPageJobSchedulerModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoPageJobSchedulerModule,<% if (routing) { %> - <%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/index.spec.ts b/projects/templates/schematics/ng-generate/po-page-job-scheduler/index.spec.ts deleted file mode 100644 index c1b0f1f478..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/index.spec.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-job-scheduler:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic( - 'po-page-job-scheduler', - { ...componentOptions, name: componentName }, - appTree - ); - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-job-scheduler', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-job-scheduler', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-job-scheduler', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-job-scheduler', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-job-scheduler', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-job-scheduler', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-job-scheduler', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-job-scheduler', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-job-scheduler', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-job-scheduler', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-job-scheduler', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/index.ts b/projects/templates/schematics/ng-generate/po-page-job-scheduler/index.ts deleted file mode 100644 index 6aa9424ec3..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent } from '@po-ui/ng-schematics/build-component'; - -import { Schema as ComponentOptions } from './schema'; - -/** Scaffolds a new component with */ -export default function (options: ComponentOptions): Rule { - return chain([createPageJobSchedulerComponent(options)]); -} - -function createPageJobSchedulerComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/schema.json b/projects/templates/schematics/ng-generate/po-page-job-scheduler/schema.json deleted file mode 100644 index 0e28a7bdd2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/schema.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageJobScheduler", - "title": "Page Job Scheduler Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "alias": "S", - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "alias": "p", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - } - }, - "required": ["name"] -} diff --git a/projects/templates/schematics/ng-generate/po-page-job-scheduler/schema.ts b/projects/templates/schematics/ng-generate/po-page-job-scheduler/schema.ts deleted file mode 100644 index 0e5e0a349d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-job-scheduler/schema.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema {} diff --git a/projects/templates/schematics/ng-generate/po-page-login/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-login/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-login/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-login/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 1620011e8d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/projects/templates/schematics/ng-generate/po-page-login/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-login/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 14390f5afc..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,33 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageLoginModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageLoginModule - ], - providers: [provideHttpClient()] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-login/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-login/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index e0c8d6013a..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,22 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { PoPageLoginModule } from '@po-ui/ng-templates'; - - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageLoginModule, - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 1620011e8d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index ca22130871..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,34 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageLoginModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageLoginModule - ], - providers: [provideHttpClient()], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 021ed143f7..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index 05554564e9..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoPageLoginModule } from '@po-ui/ng-templates'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoPageLoginModule,<% if (routing) { %> - <%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/templates/schematics/ng-generate/po-page-login/index.spec.ts b/projects/templates/schematics/ng-generate/po-page-login/index.spec.ts deleted file mode 100644 index 34a64f5401..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/index.spec.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-login:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic('po-page-login', { ...componentOptions, name: componentName }, appTree); - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-login', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-login', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-login', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-login', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-login', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-login', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-login', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-login', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-login', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-login', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-login', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/templates/schematics/ng-generate/po-page-login/index.ts b/projects/templates/schematics/ng-generate/po-page-login/index.ts deleted file mode 100644 index 978e118f2e..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent } from '@po-ui/ng-schematics/build-component'; - -import { Schema as ComponentOptions } from './schema'; - -/** Scaffolds a new component with */ -export default function (options: ComponentOptions): Rule { - return chain([createPageLoginComponent(options)]); -} - -function createPageLoginComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/templates/schematics/ng-generate/po-page-login/schema.json b/projects/templates/schematics/ng-generate/po-page-login/schema.json deleted file mode 100644 index 536d54789a..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/schema.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageLogin", - "title": "Page Login Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "alias": "S", - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "alias": "p", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - } - }, - "required": ["name"] -} diff --git a/projects/templates/schematics/ng-generate/po-page-login/schema.ts b/projects/templates/schematics/ng-generate/po-page-login/schema.ts deleted file mode 100644 index 0e5e0a349d..0000000000 --- a/projects/templates/schematics/ng-generate/po-page-login/schema.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema {} diff --git a/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery-error-message/po-modal-password-recovery-error-message.component.ts b/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery-error-message/po-modal-password-recovery-error-message.component.ts index 88896971c0..244ab62e73 100644 --- a/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery-error-message/po-modal-password-recovery-error-message.component.ts +++ b/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery-error-message/po-modal-password-recovery-error-message.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; /** * @docsPrivate @@ -10,6 +10,7 @@ import { Component, Input } from '@angular/core'; @Component({ selector: 'po-modal-password-recovery-error-message', templateUrl: './po-modal-password-recovery-error-message.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoModalPasswordRecoveryErrorMessageComponent { diff --git a/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.html b/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.html index e1a7175094..0bed89b5cb 100644 --- a/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.html +++ b/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.html @@ -2,117 +2,134 @@ #recoveryModal p-hide-close p-size="auto" - [ngSwitch]="modalType" [p-components-size]="componentsSize" [p-primary-action]="primaryAction" [p-secondary-action]="secondaryAction" [p-title]="modalTitle" >
    -
    -
    - {{ emailModalPhrases.firstPhrase }} -
    -
    -
    -
    - - + @switch (modalType) { + @case ('email') { +
    +
    + {{ emailModalPhrases.firstPhrase }}
    +
    + + @if (modalPasswordRecoveryTypeAll) { +
    + + +
    + } -
    - - +
    + @if (type === 'email' || type === 'all') { + + + } - - -
    + @if (type === 'sms') { + + + } +
    -
    - - +
    + @if (invalidEmail && control.dirty) { + + + } +
    + +
    +
    + {{ emailModalPhrases.secondPhrase }} + @if (contactEmail) { + + {{ literals.prepositionIn }} + + {{ contactEmail }} + + + } + {{ endpoint }}
    - -
    -
    - {{ emailModalPhrases.secondPhrase }} - - {{ literals.prepositionIn }} - - {{ contactEmail }} - - - {{ endpoint }} -
    -
    +
    + } -
    -
    {{ literals.sentSmsCodePhrase }}
    -
    -
    - - -
    - - - - + @case ('smsCode') { +
    +
    {{ literals.sentSmsCodePhrase }}
    +
    + + + +
    + @if (invalidEmail) { + + + } + @if (showCustomCodeError) { + + + } +
    +
    - -
    -
    - {{ literals.sendAgainPhrase }} - {{ literals.sendAgain }} -
    -
    +
    + {{ literals.sendAgainPhrase }} + {{ literals.sendAgain }} +
    +
    + } -
    - -
    - {{ literals.emailSentConfirmationPhrase }} -
    -
    + @case ('confirmation') { +
    + +
    + {{ literals.emailSentConfirmationPhrase }} +
    +
    + } + }
    diff --git a/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.spec.ts b/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.spec.ts index be9120e833..9a8e482042 100644 --- a/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.spec.ts +++ b/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.spec.ts @@ -1,7 +1,8 @@ import { By } from '@angular/platform-browser'; import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { FormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; import { throwError } from 'rxjs'; @@ -16,7 +17,7 @@ import { PoModalPasswordRecoveryModalContent } from './enums/po-modal-password-r import { PoModalPasswordRecoveryService } from './po-modal-password-recovery.service'; import { PoModalPasswordRecoveryType } from './enums/po-modal-password-recovery-type.enum'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoModalPasswordRecoveryComponent:', () => { let component: PoModalPasswordRecoveryComponent; @@ -27,11 +28,12 @@ describe('PoModalPasswordRecoveryComponent:', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [PoModalPasswordRecoveryErrorMessageComponent, PoModalPasswordRecoveryComponent], - imports: [FormsModule, RouterTestingModule.withRoutes([]), PoFieldModule, PoModalModule], + imports: [FormsModule, RouterModule.forRoot([]), PoFieldModule, PoModalModule], providers: [ + provideLocationMocks(), PoI18nPipe, PoModalPasswordRecoveryService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }).compileComponents(); diff --git a/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.ts b/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.ts index ac3d4150f0..6b6b9ef519 100644 --- a/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.ts +++ b/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, ViewChild, inject } from '@angular/core'; +import { Component, OnDestroy, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { AbstractControl, NgForm } from '@angular/forms'; import { Router } from '@angular/router'; import { Subscription } from 'rxjs'; @@ -43,6 +43,7 @@ import { PoModalPasswordRecoveryService } from './po-modal-password-recovery.ser @Component({ selector: 'po-modal-password-recovery', templateUrl: './po-modal-password-recovery.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoModalPasswordRecoveryComponent extends PoModalPasswordRecoveryBaseComponent implements OnDestroy { diff --git a/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.service.spec.ts b/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.service.spec.ts index 9ec024a359..be465ef99d 100644 --- a/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.service.spec.ts +++ b/projects/templates/src/lib/components/po-modal-password-recovery/po-modal-password-recovery.service.spec.ts @@ -2,7 +2,7 @@ import { HttpTestingController, provideHttpClientTesting } from '@angular/common import { TestBed } from '@angular/core/testing'; import { PoModalPasswordRecoveryService } from './po-modal-password-recovery.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoModalPasswordRecoveryService:', () => { let poModalPasswordRecoveryService: PoModalPasswordRecoveryService; @@ -13,7 +13,7 @@ describe('PoModalPasswordRecoveryService:', () => { imports: [], providers: [ PoModalPasswordRecoveryService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }); diff --git a/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-basic/sample-po-modal-password-recovery-basic.component.ts b/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-basic/sample-po-modal-password-recovery-basic.component.ts index eaa9dfb95d..ce638dfefb 100644 --- a/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-basic/sample-po-modal-password-recovery-basic.component.ts +++ b/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-basic/sample-po-modal-password-recovery-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-modal-password-recovery-basic', templateUrl: './sample-po-modal-password-recovery-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoModalPasswordRecoveryBasicComponent {} diff --git a/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-labs/sample-po-modal-password-recovery-labs.component.ts b/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-labs/sample-po-modal-password-recovery-labs.component.ts index 62c49305a0..ea1194eb3f 100644 --- a/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-labs/sample-po-modal-password-recovery-labs.component.ts +++ b/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-labs/sample-po-modal-password-recovery-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoDialogService, PoRadioGroupOption, PoSelectOption } from '@po-ui/ng-components'; import { @@ -10,6 +10,7 @@ import { @Component({ selector: 'sample-po-modal-password-recovery-labs', templateUrl: './sample-po-modal-password-recovery-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoModalPasswordRecoveryLabsComponent implements OnInit { diff --git a/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-request/sample-po-modal-password-recovery-request.component.ts b/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-request/sample-po-modal-password-recovery-request.component.ts index 4ae608122d..51159c8c39 100644 --- a/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-request/sample-po-modal-password-recovery-request.component.ts +++ b/projects/templates/src/lib/components/po-modal-password-recovery/samples/sample-po-modal-password-recovery-request/sample-po-modal-password-recovery-request.component.ts @@ -1,10 +1,11 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoModalPasswordRecoveryComponent, PoModalPasswordRecoveryType } from '@po-ui/ng-templates'; @Component({ selector: 'sample-po-modal-password-recovery-request', templateUrl: './sample-po-modal-password-recovery-request.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoModalPasswordRecoveryRequestComponent { diff --git a/projects/templates/src/lib/components/po-page-background/po-page-background.component.ts b/projects/templates/src/lib/components/po-page-background/po-page-background.component.ts index 390a9821f6..0a6ce89cb2 100644 --- a/projects/templates/src/lib/components/po-page-background/po-page-background.component.ts +++ b/projects/templates/src/lib/components/po-page-background/po-page-background.component.ts @@ -1,4 +1,14 @@ -import { Component, EventEmitter, HostBinding, HostListener, Input, OnInit, Output, inject } from '@angular/core'; +import { + Component, + EventEmitter, + HostBinding, + HostListener, + Input, + OnInit, + Output, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { PoLanguage, poLanguageDefault, PoLanguageService, PoSelectOption } from '@po-ui/ng-components'; @@ -7,6 +17,7 @@ import { convertToBoolean, getDefaultSizeFn, validateSizeFn } from './../../util @Component({ selector: 'po-page-background', templateUrl: './po-page-background.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) diff --git a/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user-contacts/po-page-blocked-user-contacts.component.spec.ts b/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user-contacts/po-page-blocked-user-contacts.component.spec.ts index 2f9e7583ae..5d3c2d9e57 100644 --- a/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user-contacts/po-page-blocked-user-contacts.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user-contacts/po-page-blocked-user-contacts.component.spec.ts @@ -1,8 +1,9 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { FormsModule } from '@angular/forms'; import { HttpClient, HttpHandler } from '@angular/common/http'; -import { RouterTestingModule } from '@angular/router/testing'; import { PoPageBlockedUserContactsComponent } from './po-page-blocked-user-contacts.component'; @@ -13,9 +14,9 @@ describe('PoPageBlockedUserContactsComponent: ', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [FormsModule, RouterTestingModule.withRoutes([])], + imports: [FormsModule, RouterModule.forRoot([])], declarations: [PoPageBlockedUserContactsComponent], - providers: [HttpClient, HttpHandler], + providers: [provideLocationMocks(), HttpClient, HttpHandler], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user-reason/po-page-blocked-user-reason.component.ts b/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user-reason/po-page-blocked-user-reason.component.ts index 7173418381..f01abde7ae 100644 --- a/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user-reason/po-page-blocked-user-reason.component.ts +++ b/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user-reason/po-page-blocked-user-reason.component.ts @@ -1,4 +1,13 @@ -import { ChangeDetectorRef, Component, Input, OnChanges, OnInit, SimpleChanges, inject } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + Input, + OnChanges, + OnInit, + SimpleChanges, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { PoLanguageService, poLocaleDefault } from '@po-ui/ng-components'; @@ -9,6 +18,7 @@ import { PoPageBlockedUserReasonParams } from '../interfaces/po-page-blocked-use @Component({ selector: 'po-page-blocked-user-reason', templateUrl: './po-page-blocked-user-reason.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageBlockedUserReasonComponent implements OnChanges, OnInit { diff --git a/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user.component.spec.ts b/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user.component.spec.ts index 659fe1bf66..aaf1df5c63 100644 --- a/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { RouterTestingModule } from '@angular/router/testing'; import { PoUtils as utilsFunctions } from './../../utils/util'; @@ -15,9 +16,10 @@ describe('PoPageBlockedUserComponent:', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([])], + imports: [RouterModule.forRoot([])], declarations: [PoPageBlockedUserComponent], - schemas: [NO_ERRORS_SCHEMA] + schemas: [NO_ERRORS_SCHEMA], + providers: [provideLocationMocks()] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user.component.ts b/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user.component.ts index 9d2e3437fe..0194d82ff3 100644 --- a/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user.component.ts +++ b/projects/templates/src/lib/components/po-page-blocked-user/po-page-blocked-user.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { PoLanguageService, poLocaleDefault } from '@po-ui/ng-components'; @@ -51,6 +51,7 @@ export const poPageBlockedUserButtonLiterals: object = { @Component({ selector: 'po-page-blocked-user', templateUrl: './po-page-blocked-user.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageBlockedUserComponent extends PoPageBlockedUserBaseComponent implements OnInit { diff --git a/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-basic/sample-po-page-blocked-user-basic.component.ts b/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-basic/sample-po-page-blocked-user-basic.component.ts index de28d39c2b..0a73670a14 100644 --- a/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-basic/sample-po-page-blocked-user-basic.component.ts +++ b/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-basic/sample-po-page-blocked-user-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-blocked-user-basic', templateUrl: './sample-po-page-blocked-user-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageBlockedUserBasicComponent {} diff --git a/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-exceeded-attempts/sample-po-page-blocked-user-exceeded-attempts.component.ts b/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-exceeded-attempts/sample-po-page-blocked-user-exceeded-attempts.component.ts index 04124ac88a..0facbc0e70 100644 --- a/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-exceeded-attempts/sample-po-page-blocked-user-exceeded-attempts.component.ts +++ b/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-exceeded-attempts/sample-po-page-blocked-user-exceeded-attempts.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoPageBlockedUserReasonParams } from '@po-ui/ng-templates'; @Component({ selector: 'sample-po-page-blocked-user-exceeded-attempts', templateUrl: './sample-po-page-blocked-user-exceeded-attempts.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageBlockedUserExceededAttemptsComponent { diff --git a/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-expired-password/sample-po-page-blocked-user-expired-password.component.ts b/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-expired-password/sample-po-page-blocked-user-expired-password.component.ts index 507109682b..4fc6a53a2e 100644 --- a/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-expired-password/sample-po-page-blocked-user-expired-password.component.ts +++ b/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-expired-password/sample-po-page-blocked-user-expired-password.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-blocked-user-expired-password', templateUrl: './sample-po-page-blocked-user-expired-password.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageBlockedUserExpiredPasswordComponent { diff --git a/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-labs/sample-po-page-blocked-user-labs.component.ts b/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-labs/sample-po-page-blocked-user-labs.component.ts index a9ec0cb69a..d50fc9b36a 100644 --- a/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-labs/sample-po-page-blocked-user-labs.component.ts +++ b/projects/templates/src/lib/components/po-page-blocked-user/samples/sample-po-page-blocked-user-labs/sample-po-page-blocked-user-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoRadioGroupOption } from '@po-ui/ng-components'; import { PoPageBlockedUserReason, PoPageBlockedUserReasonParams } from '@po-ui/ng-templates'; @@ -6,6 +6,7 @@ import { PoPageBlockedUserReason, PoPageBlockedUserReasonParams } from '@po-ui/n @Component({ selector: 'sample-po-page-blocked-user-labs', templateUrl: './sample-po-page-blocked-user-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageBlockedUserLabsComponent implements OnInit { diff --git a/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.component.spec.ts b/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.component.spec.ts index 28e6ac8e4a..c57839893a 100644 --- a/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.component.spec.ts @@ -1,8 +1,9 @@ import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { EventEmitter, NO_ERRORS_SCHEMA, provideNgReflectAttributes } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpClient, HttpHandler } from '@angular/common/http'; -import { RouterTestingModule } from '@angular/router/testing'; import { PoModule } from '@po-ui/ng-components'; import { PoUtils as utilsFunctions } from './../../utils/util'; @@ -23,9 +24,15 @@ describe('PoPageChangePasswordComponent:', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [FormsModule, RouterTestingModule.withRoutes([]), PoModule, PoPageBackgroundModule], + imports: [FormsModule, RouterModule.forRoot([]), PoModule, PoPageBackgroundModule], declarations: [PoPageChangePasswordComponent], - providers: [HttpClient, HttpHandler, PoPageChangePasswordService, provideNgReflectAttributes()] + providers: [ + provideLocationMocks(), + HttpClient, + HttpHandler, + PoPageChangePasswordService, + provideNgReflectAttributes() + ] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.component.ts b/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.component.ts index d79df56678..3364bb853b 100644 --- a/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.component.ts +++ b/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.component.ts @@ -6,7 +6,8 @@ import { OnInit, ViewChild, ViewContainerRef, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; @@ -65,6 +66,7 @@ import { PoPageChangePasswordService } from './po-page-change-password.service'; @Component({ selector: 'po-page-change-password', templateUrl: './po-page-change-password.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageChangePasswordComponent diff --git a/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.service.spec.ts b/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.service.spec.ts index 5ad1ce94fb..b28eed79c1 100644 --- a/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.service.spec.ts +++ b/projects/templates/src/lib/components/po-page-change-password/po-page-change-password.service.spec.ts @@ -1,7 +1,7 @@ import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { PoPageChangePasswordService } from './po-page-change-password.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoPageChangePasswordService:', () => { let poPageChangePasswordService: PoPageChangePasswordService; @@ -10,7 +10,11 @@ describe('PoPageChangePasswordService:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoPageChangePasswordService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoPageChangePasswordService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); poPageChangePasswordService = TestBed.inject(PoPageChangePasswordService); diff --git a/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-basic/sample-po-page-change-password-basic.component.ts b/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-basic/sample-po-page-change-password-basic.component.ts index 3cb5f86572..1d2132e207 100644 --- a/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-basic/sample-po-page-change-password-basic.component.ts +++ b/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-basic/sample-po-page-change-password-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-change-password-basic', templateUrl: './sample-po-page-change-password-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageChangePasswordBasicComponent {} diff --git a/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-create/sample-po-page-change-password-create.component.ts b/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-create/sample-po-page-change-password-create.component.ts index 48f2e98404..221b2faeab 100644 --- a/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-create/sample-po-page-change-password-create.component.ts +++ b/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-create/sample-po-page-change-password-create.component.ts @@ -1,9 +1,10 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoPageChangePasswordComponent, PoPageChangePasswordRequirement } from '@po-ui/ng-templates'; @Component({ selector: 'sample-po-page-change-password-create', templateUrl: './sample-po-page-change-password-create.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageChangePasswordCreateComponent { diff --git a/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-labs/sample-po-page-change-password-labs.component.ts b/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-labs/sample-po-page-change-password-labs.component.ts index 75709f4ed7..ef738c72b3 100644 --- a/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-labs/sample-po-page-change-password-labs.component.ts +++ b/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-labs/sample-po-page-change-password-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoDialogService, PoRadioGroupOption } from '@po-ui/ng-components'; import { @@ -10,6 +10,7 @@ import { @Component({ selector: 'sample-po-page-change-password-labs', templateUrl: './sample-po-page-change-password-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageChangePasswordLabsComponent implements OnInit { diff --git a/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-modify/sample-po-page-change-password-modify.component.ts b/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-modify/sample-po-page-change-password-modify.component.ts index 7bef4291d3..340c61f64c 100644 --- a/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-modify/sample-po-page-change-password-modify.component.ts +++ b/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-modify/sample-po-page-change-password-modify.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoPageChangePasswordComponent } from '@po-ui/ng-templates'; @@ -7,6 +7,7 @@ import { PoBreadcrumb, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-page-change-password-modify', templateUrl: './sample-po-page-change-password-modify.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageChangePasswordModifyComponent implements OnInit { diff --git a/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-request/sample-po-page-change-password-request.component.ts b/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-request/sample-po-page-change-password-request.component.ts index 8f04ef7d1c..c569ecbe35 100644 --- a/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-request/sample-po-page-change-password-request.component.ts +++ b/projects/templates/src/lib/components/po-page-change-password/samples/sample-po-page-change-password-request/sample-po-page-change-password-request.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-change-password-request', templateUrl: './sample-po-page-change-password-request.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageChangePasswordRequestComponent {} diff --git a/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail-actions.service.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail-actions.service.spec.ts index 444ef14b79..9cd7fd0db2 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail-actions.service.spec.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail-actions.service.spec.ts @@ -2,7 +2,7 @@ import { HttpTestingController, provideHttpClientTesting } from '@angular/common import { TestBed, fakeAsync, tick } from '@angular/core/testing'; import { PoPageDynamicDetailActionsService } from './po-page-dynamic-detail-actions.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoPageDynamicDetailActionsService', () => { let service: PoPageDynamicDetailActionsService; @@ -13,7 +13,7 @@ describe('PoPageDynamicDetailActionsService', () => { imports: [], providers: [ PoPageDynamicDetailActionsService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }); diff --git a/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail.component.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail.component.spec.ts index a0f856ea1e..1af5553e00 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail.component.spec.ts @@ -1,8 +1,9 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { FormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; import { of, throwError } from 'rxjs'; @@ -11,7 +12,7 @@ import { PoDialogService, PoThemeA11yEnum } from '@po-ui/ng-components'; import { expectPropertiesValues } from '../../util-test/util-expect.spec'; import { PoUtils as util } from '../../utils/util'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { PoPageDynamicDetailActions } from './interfaces/po-page-dynamic-detail-actions.interface'; import { PoPageDynamicDetailBeforeRemove } from './interfaces/po-page-dynamic-detail-before-remove.interface'; import { PoPageDynamicDetailComponent } from './po-page-dynamic-detail.component'; @@ -24,8 +25,13 @@ describe('PoPageDynamicDetailComponent:', () => { TestBed.configureTestingModule({ declarations: [PoPageDynamicDetailComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [FormsModule, RouterTestingModule.withRoutes([])], - providers: [PoDialogService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + imports: [FormsModule, RouterModule.forRoot([])], + providers: [ + provideLocationMocks(), + PoDialogService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail.component.ts b/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail.component.ts index ed1ac70dc3..b5a9fa7d29 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-detail/po-page-dynamic-detail.component.ts @@ -1,4 +1,13 @@ -import { Component, HostBinding, HostListener, Input, OnDestroy, OnInit, inject } from '@angular/core'; +import { + Component, + HostBinding, + HostListener, + Input, + OnDestroy, + OnInit, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { ActivatedRoute, Route, Router } from '@angular/router'; import { EMPTY, Observable, Subscription, concat, of, throwError } from 'rxjs'; @@ -161,6 +170,7 @@ export const poPageDynamicDetailLiteralsDefault = { selector: 'po-page-dynamic-detail', templateUrl: './po-page-dynamic-detail.component.html', providers: [PoPageDynamicService, PoPageDynamicDetailActionsService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageDynamicDetailComponent implements OnInit, OnDestroy { diff --git a/projects/templates/src/lib/components/po-page-dynamic-detail/samples/sample-po-page-dynamic-detail-user/sample-po-page-dynamic-detail-user.component.ts b/projects/templates/src/lib/components/po-page-dynamic-detail/samples/sample-po-page-dynamic-detail-user/sample-po-page-dynamic-detail-user.component.ts index cbf928f79b..d0140c6d45 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-detail/samples/sample-po-page-dynamic-detail-user/sample-po-page-dynamic-detail-user.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-detail/samples/sample-po-page-dynamic-detail-user/sample-po-page-dynamic-detail-user.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoBreadcrumb } from '@po-ui/ng-components'; import { PoPageDynamicDetailActions, PoPageDynamicDetailField } from '@po-ui/ng-templates'; @@ -6,6 +6,7 @@ import { PoPageDynamicDetailActions, PoPageDynamicDetailField } from '@po-ui/ng- @Component({ selector: 'sample-po-page-dynamic-detail-user', templateUrl: './sample-po-page-dynamic-detail-user.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDynamicDetailUserComponent { diff --git a/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit-actions.service.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit-actions.service.spec.ts index 0beff9e334..84931cdd98 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit-actions.service.spec.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit-actions.service.spec.ts @@ -2,7 +2,7 @@ import { TestBed, tick, fakeAsync } from '@angular/core/testing'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { PoPageDynamicEditActionsService } from './po-page-dynamic-edit-actions.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoPageDynamicEditActions:', () => { let service: PoPageDynamicEditActionsService; @@ -19,7 +19,7 @@ describe('PoPageDynamicEditActions:', () => { imports: [], providers: [ PoPageDynamicEditActionsService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }); diff --git a/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit.component.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit.component.spec.ts index 835e3994f0..3a426aa7d4 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit.component.spec.ts @@ -1,9 +1,10 @@ -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { FormControl, FormsModule, NgForm, Validators } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; import { of, throwError } from 'rxjs'; @@ -28,8 +29,12 @@ describe('PoPageDynamicEditComponent: ', () => { TestBed.configureTestingModule({ declarations: [PoPageDynamicEditComponent, PoDynamicFormStubComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [FormsModule, RouterTestingModule.withRoutes([]), PoDialogModule], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + imports: [FormsModule, RouterModule.forRoot([]), PoDialogModule], + providers: [ + provideLocationMocks(), + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit.component.ts b/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit.component.ts index 96ccea58a1..28404b39b1 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-edit/po-page-dynamic-edit.component.ts @@ -1,4 +1,14 @@ -import { Component, HostBinding, HostListener, Input, OnDestroy, OnInit, ViewChild, inject } from '@angular/core'; +import { + Component, + HostBinding, + HostListener, + Input, + OnDestroy, + OnInit, + ViewChild, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { concat, EMPTY, Observable, of, Subscription, throwError } from 'rxjs'; @@ -204,6 +214,7 @@ export const poPageDynamicEditLiteralsDefault = { selector: 'po-page-dynamic-edit', templateUrl: './po-page-dynamic-edit.component.html', providers: [PoPageDynamicService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageDynamicEditComponent implements OnInit, OnDestroy { diff --git a/projects/templates/src/lib/components/po-page-dynamic-edit/samples/sample-po-page-dynamic-edit-basic/sample-po-page-dynamic-edit-basic.component.ts b/projects/templates/src/lib/components/po-page-dynamic-edit/samples/sample-po-page-dynamic-edit-basic/sample-po-page-dynamic-edit-basic.component.ts index 70e07fed44..9869330d74 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-edit/samples/sample-po-page-dynamic-edit-basic/sample-po-page-dynamic-edit-basic.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-edit/samples/sample-po-page-dynamic-edit-basic/sample-po-page-dynamic-edit-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-dynamic-edit-basic', templateUrl: './sample-po-page-dynamic-edit-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDynamicEditBasicComponent {} diff --git a/projects/templates/src/lib/components/po-page-dynamic-edit/samples/sample-po-page-dynamic-edit-user/sample-po-page-dynamic-edit-user.component.ts b/projects/templates/src/lib/components/po-page-dynamic-edit/samples/sample-po-page-dynamic-edit-user/sample-po-page-dynamic-edit-user.component.ts index c15a7255f9..002571af8f 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-edit/samples/sample-po-page-dynamic-edit-user/sample-po-page-dynamic-edit-user.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-edit/samples/sample-po-page-dynamic-edit-user/sample-po-page-dynamic-edit-user.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoBreadcrumb, PoDynamicFormField } from '@po-ui/ng-components'; @@ -7,6 +7,7 @@ import { PoPageDynamicEditActions, PoPageDynamicEditComponent, PoPageDynamicEdit @Component({ selector: 'sample-po-page-dynamic-edit-user', templateUrl: './sample-po-page-dynamic-edit-user.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDynamicEditUserComponent { diff --git a/projects/templates/src/lib/components/po-page-dynamic-edit/test/po-dynamic-form-stub-component.ts b/projects/templates/src/lib/components/po-page-dynamic-edit/test/po-dynamic-form-stub-component.ts index ec07e20075..a2fb1c6bf2 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-edit/test/po-dynamic-form-stub-component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-edit/test/po-dynamic-form-stub-component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoDynamicFormComponent } from '@po-ui/ng-components'; @@ -11,6 +11,7 @@ import { PoDynamicFormComponent } from '@po-ui/ng-components'; useClass: PoDynamicFormStubComponent } ], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoDynamicFormStubComponent { diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/po-advanced-filter/po-advanced-filter.component.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-search/po-advanced-filter/po-advanced-filter.component.spec.ts index 646677e451..a64d1be884 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-search/po-advanced-filter/po-advanced-filter.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-search/po-advanced-filter/po-advanced-filter.component.spec.ts @@ -7,7 +7,7 @@ import { PoDynamicModule, PoFieldModule, PoModalModule } from '@po-ui/ng-compone import { PoAdvancedFilterBaseComponent } from './po-advanced-filter-base.component'; import { PoAdvancedFilterComponent } from './po-advanced-filter.component'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoAdvancedFilterComponent', () => { let component: PoAdvancedFilterComponent; @@ -18,7 +18,7 @@ describe('PoAdvancedFilterComponent', () => { TestBed.configureTestingModule({ declarations: [PoAdvancedFilterComponent], imports: [FormsModule, PoDynamicModule, PoFieldModule, PoModalModule], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting()] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/po-advanced-filter/po-advanced-filter.component.ts b/projects/templates/src/lib/components/po-page-dynamic-search/po-advanced-filter/po-advanced-filter.component.ts index d2a00e06de..aa5837bc71 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-search/po-advanced-filter/po-advanced-filter.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-search/po-advanced-filter/po-advanced-filter.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnDestroy, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { Subscription } from 'rxjs'; import { PoComboOption, PoDynamicFormComponent, PoLanguageService } from '@po-ui/ng-components'; @@ -21,6 +21,7 @@ import { PoAdvancedFilterBaseComponent } from './po-advanced-filter-base.compone @Component({ selector: 'po-advanced-filter', templateUrl: './po-advanced-filter.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoAdvancedFilterComponent extends PoAdvancedFilterBaseComponent implements OnDestroy, OnInit { diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.spec.ts index 57e9e50150..0e0b82fbda 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search-base.component.spec.ts @@ -2,7 +2,7 @@ import { expectPropertiesValues } from '../../util-test/util-expect.spec'; import { poLocaleDefault } from './../../../../../ui/src/lib/services/po-language/po-language.constant'; import { PoLanguageService } from './../../../../../ui/src/lib/services/po-language/po-language.service'; -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoThemeA11yEnum } from '@po-ui/ng-components'; import { convertToBoolean } from '../../utils/util'; import { PoPageDynamicSearchFilters } from './interfaces/po-page-dynamic-search-filters.interface'; @@ -16,6 +16,7 @@ import { @Component({ selector: 'mock-component', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class MockComponent extends PoPageDynamicSearchBaseComponent { diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.spec.ts index b33cfadca3..78e5fb41ed 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.spec.ts @@ -1,7 +1,7 @@ import { ComponentFixture, TestBed, fakeAsync, tick, waitForAsync } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; import { FormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; -import { Routes } from '@angular/router'; +import { Routes, RouterModule } from '@angular/router'; import { TitleCasePipe } from '@angular/common'; import { NO_ERRORS_SCHEMA, SimpleChanges } from '@angular/core'; @@ -12,7 +12,7 @@ import { PoAdvancedFilterComponent } from './po-advanced-filter/po-advanced-filt import { PoPageCustomizationModule } from '../../services/po-page-customization/po-page-customization.module'; import { expectBrowserLanguageMethod } from './../../util-test/util-expect.spec'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; export const routes: Routes = []; @@ -24,8 +24,13 @@ describe('PoPageDynamicSearchComponent:', () => { TestBed.configureTestingModule({ declarations: [PoPageDynamicSearchComponent, PoAdvancedFilterComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [FormsModule, RouterTestingModule.withRoutes(routes), PoPageCustomizationModule, PoDynamicModule], - providers: [TitleCasePipe, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + imports: [FormsModule, RouterModule.forRoot(routes), PoPageCustomizationModule, PoDynamicModule], + providers: [ + provideLocationMocks(), + TitleCasePipe, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.ts b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.ts index f7eb28f01d..3041dea4f4 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-search/po-page-dynamic-search.component.ts @@ -7,7 +7,8 @@ import { OnInit, SimpleChanges, ViewChild, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { @@ -56,6 +57,7 @@ type UrlOrPoCustomizationFunction = string | (() => PoPageDynamicSearchOptions); @Component({ selector: 'po-page-dynamic-search', templateUrl: './po-page-dynamic-search.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageDynamicSearchComponent diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/samples/sample-po-page-dynamic-search-basic/sample-po-page-dynamic-search-basic.component.ts b/projects/templates/src/lib/components/po-page-dynamic-search/samples/sample-po-page-dynamic-search-basic/sample-po-page-dynamic-search-basic.component.ts index 30a26531cb..151b4b11e9 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-search/samples/sample-po-page-dynamic-search-basic/sample-po-page-dynamic-search-basic.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-search/samples/sample-po-page-dynamic-search-basic/sample-po-page-dynamic-search-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-dynamic-search-basic', templateUrl: './sample-po-page-dynamic-search-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDynamicSearchBasicComponent {} diff --git a/projects/templates/src/lib/components/po-page-dynamic-search/samples/sample-po-page-dynamic-search-hiring-processes/sample-po-page-dynamic-search-hiring-processes.component.ts b/projects/templates/src/lib/components/po-page-dynamic-search/samples/sample-po-page-dynamic-search-hiring-processes/sample-po-page-dynamic-search-hiring-processes.component.ts index e4ca6ba8e6..7d96e7e44e 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-search/samples/sample-po-page-dynamic-search-hiring-processes/sample-po-page-dynamic-search-hiring-processes.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-search/samples/sample-po-page-dynamic-search-hiring-processes/sample-po-page-dynamic-search-hiring-processes.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; import { PoPageDynamicSearchLiterals, PoPageDynamicSearchFilters } from '@po-ui/ng-templates'; @@ -18,6 +18,7 @@ import { SamplePoPageDynamicSearchHiringProcessesService } from './sample-po-pag selector: 'sample-po-page-dynamic-search-hiring-processes', templateUrl: './sample-po-page-dynamic-search-hiring-processes.component.html', providers: [SamplePoPageDynamicSearchHiringProcessesService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDynamicSearchHiringProcessesComponent implements OnInit { diff --git a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table-actions.service.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table-actions.service.spec.ts index 6429a4f21f..7cb1906514 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table-actions.service.spec.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table-actions.service.spec.ts @@ -1,7 +1,7 @@ import { TestBed, fakeAsync, tick } from '@angular/core/testing'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { PoPageDynamicTableActionsService } from './po-page-dynamic-table-actions.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoPageDynamicTableActionsService:', () => { let service: PoPageDynamicTableActionsService; @@ -12,7 +12,7 @@ describe('PoPageDynamicTableActionsService:', () => { imports: [], providers: [ PoPageDynamicTableActionsService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }); diff --git a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.spec.ts b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.spec.ts index c9fac2752f..f82caae2d6 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.spec.ts @@ -1,8 +1,9 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { FormsModule } from '@angular/forms'; -import { RouterTestingModule } from '@angular/router/testing'; import { EMPTY, of } from 'rxjs'; @@ -19,7 +20,7 @@ import { expectPropertiesValues } from '../../util-test/util-expect.spec'; import { PoUtils as utilsFunctions } from '../../utils/util'; import { PoPageDynamicDetailComponent } from '../po-page-dynamic-detail/po-page-dynamic-detail.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { PoPageDynamicTableBeforeRemoveAll } from './interfaces/po-page-dynamic-table-before-remove-all.interface'; import { PoPageDynamicTableBeforeRemove } from './interfaces/po-page-dynamic-table-before-remove.interface'; import { PoPageDynamicTableComponent } from './po-page-dynamic-table.component'; @@ -32,8 +33,12 @@ describe('PoPageDynamicTableComponent:', () => { TestBed.configureTestingModule({ declarations: [PoPageDynamicTableComponent], schemas: [NO_ERRORS_SCHEMA], - imports: [FormsModule, RouterTestingModule.withRoutes([]), PoNotificationModule, PoDialogModule], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + imports: [FormsModule, RouterModule.forRoot([]), PoNotificationModule, PoDialogModule], + providers: [ + provideLocationMocks(), + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }).compileComponents(); })); @@ -831,7 +836,7 @@ describe('PoPageDynamicTableComponent:', () => { component.items = [{ name: 'Anne', id: 2, seqItem: 9 }]; spyOn(component['poPageDynamicService'], 'getResources').and.returnValue(of(response)); - spyOn(utilsFunctions, 'removeDuplicateItemsWithArrayKey'); + spyOn(utilsFunctions, 'removeDuplicateItemsWithArrayKey').and.returnValue(undefined); component['loadData']({ page: 2 }).subscribe(); diff --git a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.ts b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.ts index 9699d1079b..cfc30456d9 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-table/po-page-dynamic-table.component.ts @@ -1,4 +1,13 @@ -import { Component, HostBinding, HostListener, Input, OnDestroy, OnInit, inject } from '@angular/core'; +import { + Component, + HostBinding, + HostListener, + Input, + OnDestroy, + OnInit, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { ActivatedRoute, Route, Router } from '@angular/router'; import { EMPTY, Observable, Subscription, of } from 'rxjs'; @@ -17,12 +26,11 @@ import { poLocaleDefault } from '@po-ui/ng-components'; -import { convertToBoolean, getDefaultSizeFn, validateSizeFn, PoUtils as util } from '../../utils/util'; +import { convertToBoolean, getDefaultSizeFn, validateSizeFn, PoUtils as util, isExternalLink } from '../../utils/util'; import { PoPageDynamicDetailComponent } from '../po-page-dynamic-detail/po-page-dynamic-detail.component'; import { PoPageDynamicService } from '../../services/po-page-dynamic/po-page-dynamic.service'; -import { isExternalLink, removeDuplicateItemsWithArrayKey, PoUtils } from '../../utils/util'; import { PoPageDynamicSearchLiterals } from '../po-page-dynamic-search/interfaces/po-page-dynamic-search-literals.interface'; import { PoPageCustomizationService } from './../../services/po-page-customization/po-page-customization.service'; import { PoPageDynamicOptionsSchema } from './../../services/po-page-customization/po-page-dynamic-options.interface'; @@ -160,6 +168,7 @@ type UrlOrPoCustomizationFunction = string | (() => PoPageDynamicTableOptions); selector: 'po-page-dynamic-table', templateUrl: './po-page-dynamic-table.component.html', providers: [PoPageDynamicService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageDynamicTableComponent extends PoPageDynamicListBaseComponent implements OnInit, OnDestroy { @@ -869,9 +878,9 @@ export class PoPageDynamicTableComponent extends PoPageDynamicListBaseComponent tap(response => { let newArray; if (fullParams.page === 1) { - newArray = removeDuplicateItemsWithArrayKey(response.items, response.items, this.keys); + newArray = util.removeDuplicateItemsWithArrayKey(response.items, response.items, this.keys); } else { - newArray = removeDuplicateItemsWithArrayKey(this.items, response.items, this.keys); + newArray = util.removeDuplicateItemsWithArrayKey(this.items, response.items, this.keys); } this.items = newArray ? [...newArray] : this.items; this.page = fullParams.page; @@ -913,7 +922,7 @@ export class PoPageDynamicTableComponent extends PoPageDynamicListBaseComponent forceStopAutoRouter: boolean = false ) { if (isExternalLink(route.path)) { - return PoUtils.openExternalLink(route.path); + return util.openExternalLink(route.path); } this.router.navigate([route.url || route.path], { queryParams: route.params }).catch(() => { @@ -1281,7 +1290,7 @@ export class PoPageDynamicTableComponent extends PoPageDynamicListBaseComponent this.subscriptions.add(sendCustomActionSubscription); } else if (customAction.url) { if (isExternalLink(customAction.url)) { - PoUtils.openExternalLink(this.createConcatenatedUrl(customAction.concatKeys, customAction.url, selectedItem)); + util.openExternalLink(this.createConcatenatedUrl(customAction.concatKeys, customAction.url, selectedItem)); } else { this.navigateTo({ path: this.createConcatenatedUrl(customAction.concatKeys, customAction.url, selectedItem) diff --git a/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-basic/sample-po-page-dynamic-table-basic.component.ts b/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-basic/sample-po-page-dynamic-table-basic.component.ts index 0186b7bfab..502fecdfe5 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-basic/sample-po-page-dynamic-table-basic.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-basic/sample-po-page-dynamic-table-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-dynamic-table-basic', templateUrl: './sample-po-page-dynamic-table-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDynamicTableBasicComponent {} diff --git a/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-drag-and-drop/sample-po-page-dynamic-table-drag-and-drop.component.ts b/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-drag-and-drop/sample-po-page-dynamic-table-drag-and-drop.component.ts index e883dd0dad..a6f30eed10 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-drag-and-drop/sample-po-page-dynamic-table-drag-and-drop.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-drag-and-drop/sample-po-page-dynamic-table-drag-and-drop.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-dynamic-table-drag-and-drop', templateUrl: './sample-po-page-dynamic-table-drag-and-drop.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDynamicTableDragAndDropComponent { diff --git a/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-hotels/sample-po-page-dynamic-table-hotels.component.ts b/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-hotels/sample-po-page-dynamic-table-hotels.component.ts index 7729c75f04..e74080549e 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-hotels/sample-po-page-dynamic-table-hotels.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-hotels/sample-po-page-dynamic-table-hotels.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoBreadcrumb, PoDynamicViewField, PoModalComponent } from '@po-ui/ng-components'; import { @@ -10,6 +10,7 @@ import { @Component({ selector: 'sample-po-page-dynamic-table-hotels', templateUrl: './sample-po-page-dynamic-table-hotels.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDynamicTableHotelsComponent { diff --git a/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-people/sample-po-page-dynamic-table-people.component.ts b/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-people/sample-po-page-dynamic-table-people.component.ts index 5c5ef7ecf3..6aedab0bdc 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-people/sample-po-page-dynamic-table-people.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-people/sample-po-page-dynamic-table-people.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-dynamic-table-people', templateUrl: './sample-po-page-dynamic-table-people.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDynamicTablePeopleComponent { diff --git a/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-users/sample-po-page-dynamic-table-users.component.ts b/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-users/sample-po-page-dynamic-table-users.component.ts index 061bbdcc7b..8389c1e09d 100644 --- a/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-users/sample-po-page-dynamic-table-users.component.ts +++ b/projects/templates/src/lib/components/po-page-dynamic-table/samples/sample-po-page-dynamic-table-users/sample-po-page-dynamic-table-users.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoBreadcrumb, PoDynamicViewField, PoModalComponent } from '@po-ui/ng-components'; @@ -15,6 +15,7 @@ import { SamplePoPageDynamicTableUsersService } from './sample-po-page-dynamic-t selector: 'sample-po-page-dynamic-table-users', templateUrl: './sample-po-page-dynamic-table-users.component.html', providers: [SamplePoPageDynamicTableUsersService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDynamicTableUsersComponent implements OnInit { diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.spec.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.spec.ts index e9efdc7ac6..cc318a6762 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.spec.ts @@ -6,7 +6,7 @@ import { throwError } from 'rxjs'; import { getObservable } from '../../util-test/util-expect.spec'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { PoStepperOrientation, PoThemeA11yEnum } from '@po-ui/ng-components'; import { expectPropertiesValues } from './../../util-test/util-expect.spec'; import { PoJobSchedulerInternal } from './interfaces/po-job-scheduler-internal.interface'; @@ -21,7 +21,11 @@ describe('PoPageJobSchedulerBaseComponent:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoPageJobSchedulerService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoPageJobSchedulerService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); serviceJobScheduler = TestBed.inject(PoPageJobSchedulerService); diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.spec.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.spec.ts index 190e27568c..79777b774f 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.spec.ts @@ -1,5 +1,6 @@ import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { throwError } from 'rxjs'; @@ -9,7 +10,7 @@ import { getObservable } from '../../../util-test/util-expect.spec'; import { PoPageJobSchedulerExecutionComponent } from './po-page-job-scheduler-execution.component'; import { PoPageJobSchedulerModule } from '../po-page-job-scheduler.module'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoPageJobSchedulerExecutionComponent:', () => { let component: PoPageJobSchedulerExecutionComponent; @@ -19,8 +20,12 @@ describe('PoPageJobSchedulerExecutionComponent:', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([]), PoPageJobSchedulerModule], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + imports: [RouterModule.forRoot([]), PoPageJobSchedulerModule], + providers: [ + provideLocationMocks(), + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.ts index becedb0b79..b82e2f8f4b 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.ts @@ -7,7 +7,8 @@ import { Output, TemplateRef, ViewChild, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; @@ -21,6 +22,7 @@ import { PoPageJobSchedulerService } from '../po-page-job-scheduler.service'; @Component({ selector: 'po-page-job-scheduler-execution', templateUrl: 'po-page-job-scheduler-execution.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageJobSchedulerExecutionComponent implements OnInit, AfterViewInit { diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-lookup.service.spec.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-lookup.service.spec.ts index 6cafe3b1cd..46d882df36 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-lookup.service.spec.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-lookup.service.spec.ts @@ -3,7 +3,7 @@ import { TestBed } from '@angular/core/testing'; import { PoPageJobSchedulerLookupService } from './po-page-job-scheduler-lookup.service'; import { PoPageJobSchedulerService } from './po-page-job-scheduler.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoPageJobSchedulerLookupService:', () => { let poPageJobSchedulerLookupService: PoPageJobSchedulerLookupService; @@ -14,7 +14,7 @@ describe('PoPageJobSchedulerLookupService:', () => { providers: [ PoPageJobSchedulerLookupService, PoPageJobSchedulerService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }); diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-parameters/po-page-job-scheduler-parameters.component.spec.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-parameters/po-page-job-scheduler-parameters.component.spec.ts index ebc0bda66b..2aa385b74a 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-parameters/po-page-job-scheduler-parameters.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-parameters/po-page-job-scheduler-parameters.component.spec.ts @@ -1,12 +1,13 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { getObservable } from '../../../util-test/util-expect.spec'; import { PoPageJobSchedulerModule } from '../po-page-job-scheduler.module'; import { PoPageJobSchedulerParametersComponent } from './po-page-job-scheduler-parameters.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoPageJobSchedulerParametersComponent:', () => { let component: PoPageJobSchedulerParametersComponent; @@ -16,8 +17,12 @@ describe('PoPageJobSchedulerParametersComponent:', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([]), PoPageJobSchedulerModule], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + imports: [RouterModule.forRoot([]), PoPageJobSchedulerModule], + providers: [ + provideLocationMocks(), + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-parameters/po-page-job-scheduler-parameters.component.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-parameters/po-page-job-scheduler-parameters.component.ts index 9c109bfae1..9d98b3c4bd 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-parameters/po-page-job-scheduler-parameters.component.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-parameters/po-page-job-scheduler-parameters.component.ts @@ -1,4 +1,12 @@ -import { AfterViewInit, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { + AfterViewInit, + Component, + EventEmitter, + Input, + Output, + ViewChild, + ChangeDetectionStrategy +} from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoDynamicFormField } from '@po-ui/ng-components'; @@ -6,6 +14,7 @@ import { PoDynamicFormField } from '@po-ui/ng-components'; @Component({ selector: 'po-page-job-scheduler-parameters', templateUrl: 'po-page-job-scheduler-parameters.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageJobSchedulerParametersComponent implements AfterViewInit { diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.spec.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.spec.ts index 4d8c62f061..8619dcdba1 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.spec.ts @@ -1,13 +1,14 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { PoLanguageService, poLocaleDefault } from '@po-ui/ng-components'; import { poPageJobSchedulerLiteralsDefault } from '../po-page-job-scheduler-literals'; import { PoPageJobSchedulerModule } from '../po-page-job-scheduler.module'; import { PoPageJobSchedulerSummaryComponent } from './po-page-job-scheduler-summary.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoPageJobSchedulerSummaryComponent:', () => { const languageService: PoLanguageService = new PoLanguageService(); @@ -19,8 +20,12 @@ describe('PoPageJobSchedulerSummaryComponent:', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([]), PoPageJobSchedulerModule], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + imports: [RouterModule.forRoot([]), PoPageJobSchedulerModule], + providers: [ + provideLocationMocks(), + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.ts index e016d21786..d524604597 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.ts @@ -1,5 +1,5 @@ import { DatePipe } from '@angular/common'; -import { Component, Input, OnInit, inject } from '@angular/core'; +import { Component, Input, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoDynamicViewField, PoInfoOrientation } from '@po-ui/ng-components'; @@ -8,6 +8,7 @@ import { PoJobSchedulerInternal } from '../interfaces/po-job-scheduler-internal. @Component({ selector: 'po-page-job-scheduler-summary', templateUrl: 'po-page-job-scheduler-summary.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageJobSchedulerSummaryComponent implements OnInit { diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.component.spec.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.component.spec.ts index c28bcf71a4..b2673cf804 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.component.spec.ts @@ -1,6 +1,7 @@ import { QueryList } from '@angular/core'; import { ComponentFixture, discardPeriodicTasks, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { NgForm } from '@angular/forms'; import { Observable, of, throwError } from 'rxjs'; @@ -14,7 +15,7 @@ import { PoJobSchedulerParametersTemplateDirective } from './po-page-job-schedul import { PoPageJobSchedulerComponent } from './po-page-job-scheduler.component'; import { PoPageJobSchedulerModule } from './po-page-job-scheduler.module'; import { PoStepperOrientation, PoStepperStatus } from '@po-ui/ng-components'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoPageJobSchedulerComponent:', () => { let component: PoPageJobSchedulerComponent; @@ -22,8 +23,12 @@ describe('PoPageJobSchedulerComponent:', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([]), PoPageJobSchedulerModule], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + imports: [RouterModule.forRoot([]), PoPageJobSchedulerModule], + providers: [ + provideLocationMocks(), + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.component.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.component.ts index 47be4d6f70..475e3ea74f 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.component.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.component.ts @@ -7,7 +7,8 @@ import { QueryList, ViewChild, ViewEncapsulation, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; @@ -60,6 +61,7 @@ import { PoPageJobSchedulerService } from './po-page-job-scheduler.service'; templateUrl: './po-page-job-scheduler.component.html', encapsulation: ViewEncapsulation.None, styles: [], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageJobSchedulerComponent extends PoPageJobSchedulerBaseComponent implements OnInit, AfterContentInit { diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.spec.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.spec.ts index 480ebca98a..7d9a4c6ed8 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.spec.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.spec.ts @@ -9,7 +9,7 @@ import { PoUtils as utilsFunctions } from '../../utils/util'; import { PoJobScheduler } from './interfaces/po-job-scheduler.interface'; import { PoJobSchedulerInternal } from './interfaces/po-job-scheduler-internal.interface'; import { PoPageJobSchedulerService } from './po-page-job-scheduler.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoPageJobSchedulerService:', () => { let poPageJobSchedulerService: PoPageJobSchedulerService; @@ -18,7 +18,11 @@ describe('PoPageJobSchedulerService:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoPageJobSchedulerService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoPageJobSchedulerService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); poPageJobSchedulerService = TestBed.inject(PoPageJobSchedulerService); diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/samples/sample-po-page-job-scheduler-background-process/sample-po-page-job-scheduler-background-process.component.ts b/projects/templates/src/lib/components/po-page-job-scheduler/samples/sample-po-page-job-scheduler-background-process/sample-po-page-job-scheduler-background-process.component.ts index a0e6ad7895..b5ac08e854 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/samples/sample-po-page-job-scheduler-background-process/sample-po-page-job-scheduler-background-process.component.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/samples/sample-po-page-job-scheduler-background-process/sample-po-page-job-scheduler-background-process.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoBreadcrumb } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-page-job-scheduler-background-process', templateUrl: './sample-po-page-job-scheduler-background-process.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageJobSchedulerBackgroundProcessComponent { diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/samples/sample-po-page-job-scheduler-directives/sample-po-page-job-scheduler-directives.component.ts b/projects/templates/src/lib/components/po-page-job-scheduler/samples/sample-po-page-job-scheduler-directives/sample-po-page-job-scheduler-directives.component.ts index 60409c0a06..85c15adf50 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/samples/sample-po-page-job-scheduler-directives/sample-po-page-job-scheduler-directives.component.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/samples/sample-po-page-job-scheduler-directives/sample-po-page-job-scheduler-directives.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoDynamicFormField, PoDynamicViewField } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-page-job-scheduler-directives', templateUrl: './sample-po-page-job-scheduler-directives.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageJobSchedulerDirectivesComponent { diff --git a/projects/templates/src/lib/components/po-page-login/po-page-login-popover/po-page-login-popover.component.spec.ts b/projects/templates/src/lib/components/po-page-login/po-page-login-popover/po-page-login-popover.component.spec.ts index 6f30d8e997..002392604e 100644 --- a/projects/templates/src/lib/components/po-page-login/po-page-login-popover/po-page-login-popover.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-login/po-page-login-popover/po-page-login-popover.component.spec.ts @@ -1,6 +1,7 @@ import { provideNgReflectAttributes } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { PoPageLoginPopoverComponent } from './po-page-login-popover.component'; @@ -13,9 +14,9 @@ describe('ThPageLoginPopoverComponent: ', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([])], + imports: [RouterModule.forRoot([])], declarations: [PoI18nPipe, PoPageLoginPopoverComponent], - providers: [provideNgReflectAttributes()] + providers: [provideLocationMocks(), provideNgReflectAttributes()] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-login/po-page-login-popover/po-page-login-popover.component.ts b/projects/templates/src/lib/components/po-page-login/po-page-login-popover/po-page-login-popover.component.ts index 62aa14a515..3bc5af8e6c 100644 --- a/projects/templates/src/lib/components/po-page-login/po-page-login-popover/po-page-login-popover.component.ts +++ b/projects/templates/src/lib/components/po-page-login/po-page-login-popover/po-page-login-popover.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from '@angular/core'; import { isExternalLink, isTypeof } from '../../../utils/util'; @@ -8,6 +8,7 @@ import { PoPageLoginRecovery } from '../interfaces/po-page-login-recovery.interf @Component({ selector: 'po-page-login-popover', templateUrl: './po-page-login-popover.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) diff --git a/projects/templates/src/lib/components/po-page-login/po-page-login.component.spec.ts b/projects/templates/src/lib/components/po-page-login/po-page-login.component.spec.ts index 2bb19cde5e..c0ad14e183 100644 --- a/projects/templates/src/lib/components/po-page-login/po-page-login.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-login/po-page-login.component.spec.ts @@ -1,8 +1,9 @@ import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { FormsModule } from '@angular/forms'; import { HttpClient, HttpHandler } from '@angular/common/http'; import { NO_ERRORS_SCHEMA, provideNgReflectAttributes } from '@angular/core'; -import { RouterTestingModule } from '@angular/router/testing'; import { PoButtonComponent, @@ -37,7 +38,7 @@ describe('PoPageLoginComponent: ', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [FormsModule, OverlayModule, RouterTestingModule.withRoutes([])], + imports: [FormsModule, OverlayModule, RouterModule.forRoot([])], declarations: [ PoButtonComponent, PoComboComponent, @@ -48,7 +49,7 @@ describe('PoPageLoginComponent: ', () => { PoSelectComponent, PoSwitchComponent ], - providers: [HttpClient, HttpHandler, PoPageLoginService, provideNgReflectAttributes()], + providers: [provideLocationMocks(), HttpClient, HttpHandler, PoPageLoginService, provideNgReflectAttributes()], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); })); diff --git a/projects/templates/src/lib/components/po-page-login/po-page-login.component.ts b/projects/templates/src/lib/components/po-page-login/po-page-login.component.ts index 5e1f1ca73b..c45fb6fc9e 100644 --- a/projects/templates/src/lib/components/po-page-login/po-page-login.component.ts +++ b/projects/templates/src/lib/components/po-page-login/po-page-login.component.ts @@ -7,7 +7,8 @@ import { OnInit, ViewChild, ViewContainerRef, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { AbstractControl, NgForm } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; @@ -57,6 +58,7 @@ import { PoPageLoginService } from './po-page-login.service'; @Component({ selector: 'po-page-login', templateUrl: './po-page-login.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageLoginComponent extends PoPageLoginBaseComponent implements AfterViewChecked, OnInit { diff --git a/projects/templates/src/lib/components/po-page-login/po-page-login.service.spec.ts b/projects/templates/src/lib/components/po-page-login/po-page-login.service.spec.ts index e331d3bc24..6d41d585fd 100644 --- a/projects/templates/src/lib/components/po-page-login/po-page-login.service.spec.ts +++ b/projects/templates/src/lib/components/po-page-login/po-page-login.service.spec.ts @@ -3,7 +3,7 @@ import { TestBed } from '@angular/core/testing'; import { PoPageLoginAuthenticationType } from './enums/po-page-login-authentication-type.enum'; import { PoPageLoginService } from './po-page-login.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoPageLoginService:', () => { let httpMock: HttpTestingController; @@ -12,7 +12,11 @@ describe('PoPageLoginService:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoPageLoginService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoPageLoginService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); poPageLoginService = TestBed.inject(PoPageLoginService); diff --git a/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-automatic-service/sample-po-page-login-automatic-service.component.ts b/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-automatic-service/sample-po-page-login-automatic-service.component.ts index bff914fdc0..355f13cc68 100644 --- a/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-automatic-service/sample-po-page-login-automatic-service.component.ts +++ b/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-automatic-service/sample-po-page-login-automatic-service.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoLanguage } from '@po-ui/ng-components'; import { PoPageLoginLiterals } from '@po-ui/ng-templates'; @Component({ selector: 'sample-po-page-login-automatic-service', templateUrl: './sample-po-page-login-automatic-service.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageLoginAutomaticServiceComponent { diff --git a/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-basic/sample-po-page-login-basic.component.ts b/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-basic/sample-po-page-login-basic.component.ts index 5d85d408c7..9d00c1e3b9 100644 --- a/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-basic/sample-po-page-login-basic.component.ts +++ b/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-basic/sample-po-page-login-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-login-basic', templateUrl: './sample-po-page-login-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageLoginBasicComponent {} diff --git a/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-human-resources/sample-po-page-login-human-resources.component.ts b/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-human-resources/sample-po-page-login-human-resources.component.ts index e90e86442e..0d4ef62056 100644 --- a/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-human-resources/sample-po-page-login-human-resources.component.ts +++ b/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-human-resources/sample-po-page-login-human-resources.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit, inject } from '@angular/core'; +import { Component, OnDestroy, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { Subscription } from 'rxjs'; @@ -14,6 +14,7 @@ import { @Component({ selector: 'sample-po-page-login-human-resources', templateUrl: './sample-po-page-login-human-resources.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageLoginHumanResourcesComponent implements OnDestroy, OnInit { diff --git a/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-labs/sample-po-page-login-labs.component.ts b/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-labs/sample-po-page-login-labs.component.ts index 9704f779be..df73516f50 100644 --- a/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-labs/sample-po-page-login-labs.component.ts +++ b/projects/templates/src/lib/components/po-page-login/samples/sample-po-page-login-labs/sample-po-page-login-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoDialogService, PoRadioGroupOption, PoSelectOption } from '@po-ui/ng-components'; @@ -7,6 +7,7 @@ import { PoPageLogin, PoPageLoginCustomField, PoPageLoginLiterals } from '@po-ui @Component({ selector: 'sample-po-page-login-labs', templateUrl: './sample-po-page-login-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageLoginLabsComponent implements OnInit { diff --git a/projects/templates/src/lib/services/po-page-customization/po-page-customization.service.spec.ts b/projects/templates/src/lib/services/po-page-customization/po-page-customization.service.spec.ts index 75e61d0bd9..6f74832ded 100644 --- a/projects/templates/src/lib/services/po-page-customization/po-page-customization.service.spec.ts +++ b/projects/templates/src/lib/services/po-page-customization/po-page-customization.service.spec.ts @@ -4,7 +4,7 @@ import { HttpTestingController, provideHttpClientTesting } from '@angular/common import { PoPageCustomizationService } from './po-page-customization.service'; import { PoPageDynamicSearchOptions } from '../../components/po-page-dynamic-search/interfaces/po-page-dynamic-search-options.interface'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; const originalPageOptions: PoPageDynamicSearchOptions = { title: 'Original Title', @@ -93,7 +93,11 @@ describe('PoPageCustomizationService:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoPageCustomizationService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoPageCustomizationService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); poPageCustomizationService = TestBed.inject(PoPageCustomizationService); diff --git a/projects/templates/src/lib/services/po-page-dynamic/po-page-dynamic.service.spec.ts b/projects/templates/src/lib/services/po-page-dynamic/po-page-dynamic.service.spec.ts index 87a4ed6614..802f7b5d28 100644 --- a/projects/templates/src/lib/services/po-page-dynamic/po-page-dynamic.service.spec.ts +++ b/projects/templates/src/lib/services/po-page-dynamic/po-page-dynamic.service.spec.ts @@ -1,6 +1,12 @@ import { TestBed, fakeAsync, tick } from '@angular/core/testing'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; -import { HttpParams, HttpErrorResponse, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { + HttpParams, + HttpErrorResponse, + provideHttpClient, + withInterceptorsFromDi, + withXhr +} from '@angular/common/http'; import { PoPageDynamicService, poPageDynamicLiterals } from './po-page-dynamic.service'; import { PoPageDynamicTableMetaData } from '../../components'; @@ -12,7 +18,11 @@ describe('PoPageDynamicService:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoPageDynamicService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoPageDynamicService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); poPageDynamicService = TestBed.inject(PoPageDynamicService); diff --git a/projects/templates/src/lib/utils/util.spec.ts b/projects/templates/src/lib/utils/util.spec.ts index b23b540a78..7fc063f4b4 100644 --- a/projects/templates/src/lib/utils/util.spec.ts +++ b/projects/templates/src/lib/utils/util.spec.ts @@ -29,14 +29,12 @@ import { removeDuplicateItems, removeDuplicateItemsWithArrayKey, sortArrayOfObjects, - getDefaultSize, getDefaultSizeFn, - validateSize, validateSizeFn } from './util'; import { changeChromeProperties } from '../util-test/util-expect.spec'; -import { PoThemeA11yEnum, PoThemeService } from '@po-ui/ng-components'; -import { PoFieldSize } from 'projects/ui/src/lib/enums/po-field-size.enum'; +import { PoThemeA11yEnum } from '@po-ui/ng-components'; +import { PoFieldSize } from '../../../../ui/src/lib/enums/po-field-size.enum'; describe('Language:', () => { let navigatorLanguageSpy; @@ -1213,13 +1211,7 @@ describe('Function sortArrayOfObjects:', () => { }); describe('accessibility level: ', () => { - describe('getDefaultSize', () => { - let poThemeServiceMock: jasmine.SpyObj; - - beforeEach(() => { - poThemeServiceMock = jasmine.createSpyObj('PoThemeService', ['getA11yLevel', 'getA11yDefaultSize']); - }); - + describe('getDefaultSizeFn', () => { beforeEach(() => { document.documentElement.removeAttribute('data-a11y'); localStorage.removeItem('po-default-size'); @@ -1230,13 +1222,6 @@ describe('accessibility level: ', () => { localStorage.removeItem('po-default-size'); }); - it('should return `small` when the default component size is `small` in accessibility level AA (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AA); - poThemeServiceMock.getA11yDefaultSize.and.returnValue('small'); - - expect(getDefaultSize(poThemeServiceMock)).toBe(PoFieldSize.Small); - }); - it('should return `small` when the default component size is `small` in accessibility level AA', () => { document.documentElement.setAttribute('data-a11y', PoThemeA11yEnum.AA); localStorage.setItem('po-default-size', 'small'); @@ -1244,12 +1229,6 @@ describe('accessibility level: ', () => { expect(getDefaultSizeFn()).toBe(PoFieldSize.Small); }); - it('should return `medium` if accessibility AA and default size is not set (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AA); - - expect(getDefaultSize(poThemeServiceMock)).toBe(PoFieldSize.Medium); - }); - it('should return `medium` if accessibility AA and default size is not set', () => { document.documentElement.setAttribute('data-a11y', PoThemeA11yEnum.AA); localStorage.removeItem('po-default-size'); @@ -1257,12 +1236,6 @@ describe('accessibility level: ', () => { expect(getDefaultSizeFn()).toBe(PoFieldSize.Medium); }); - it('should return `medium` when the accessibility level is AAA (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AAA); - - expect(getDefaultSize(poThemeServiceMock)).toBe(PoFieldSize.Medium); - }); - it('should return `medium` when the accessibility level is AAA', () => { document.documentElement.setAttribute('data-a11y', PoThemeA11yEnum.AAA); @@ -1270,13 +1243,7 @@ describe('accessibility level: ', () => { }); }); - describe('validateSize', () => { - let poThemeServiceMock: jasmine.SpyObj; - - beforeEach(() => { - poThemeServiceMock = jasmine.createSpyObj('PoThemeService', ['getA11yLevel', 'getA11yDefaultSize']); - }); - + describe('validateSizeFn', () => { beforeEach(() => { document.documentElement.removeAttribute('data-a11y'); localStorage.removeItem('po-default-size'); @@ -1287,13 +1254,6 @@ describe('accessibility level: ', () => { localStorage.removeItem('po-default-size'); }); - it('should return valid values based on accessibility level (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AA); - - expect(validateSize(PoFieldSize.Small, poThemeServiceMock)).toBe(PoFieldSize.Small); - expect(validateSize(PoFieldSize.Medium, poThemeServiceMock)).toBe(PoFieldSize.Medium); - }); - it('should return valid values based on accessibility level', () => { document.documentElement.setAttribute('data-a11y', PoThemeA11yEnum.AA); @@ -1301,24 +1261,12 @@ describe('accessibility level: ', () => { expect(validateSizeFn(PoFieldSize.Medium)).toBe(PoFieldSize.Medium); }); - it('should return `medium` when the value is `small` but the accessibility level is not AA (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AAA); - - expect(validateSize(PoFieldSize.Small, poThemeServiceMock)).toBe(PoFieldSize.Medium); - }); - it('should return `medium` when the value is `small` but the accessibility level is not AA', () => { document.documentElement.setAttribute('data-a11y', PoThemeA11yEnum.AAA); expect(validateSizeFn(PoFieldSize.Small)).toBe(PoFieldSize.Medium); }); - it('should return the default size when an invalid value is provided (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AA); - - expect(validateSize('xxg', poThemeServiceMock)).toBe(PoFieldSize.Medium); - }); - it('should return the default size when an invalid value is provided', () => { expect(validateSizeFn('xxg')).toBe(PoFieldSize.Medium); }); diff --git a/projects/templates/src/lib/utils/util.ts b/projects/templates/src/lib/utils/util.ts index 43373580c9..6d2e56fdbb 100644 --- a/projects/templates/src/lib/utils/util.ts +++ b/projects/templates/src/lib/utils/util.ts @@ -1,4 +1,4 @@ -import { poLocaleDefault, poLocales, PoThemeA11yEnum, PoThemeService } from '@po-ui/ng-components'; +import { poLocaleDefault, poLocales, PoThemeA11yEnum } from '@po-ui/ng-components'; import { PoPageComponentsSize } from '../components/enums/po-page-components-size.enum'; /** @@ -143,15 +143,6 @@ export function formatYear(year: number) { } } -/** - * @deprecated use getDefaultSizeFn - * - * Retorna o tamanho padrão dos componentes conforme o nível de acessibilidade. - */ -export function getDefaultSize(poThemeService: PoThemeService): string { - return poThemeService.getA11yDefaultSize() === 'small' ? PoPageComponentsSize.Small : PoPageComponentsSize.Medium; -} - /** * Retorna o tamanho padrão dos componentes conforme o nível de acessibilidade. */ @@ -485,21 +476,6 @@ export function sortArrayOfObjects(items, key, isAscendingOrder) { }); } -/** - * @deprecated use validateSizeFn - * - * Valida e retorna um tamanho permitido para os componentes, considerando a acessibilidade. - */ -export function validateSize(value: string, poThemeService: PoThemeService): string { - if (value && Object.values(PoPageComponentsSize).includes(value as PoPageComponentsSize)) { - if (value === PoPageComponentsSize.Small && poThemeService.getA11yLevel() !== 'AA') { - return PoPageComponentsSize.Medium; - } - return value; - } - return getDefaultSize(poThemeService); -} - /** * Valida e retorna um tamanho permitido para os componentes, considerando a acessibilidade. */ diff --git a/projects/templates/src/test.ts b/projects/templates/src/test.ts index 6ccaa451b4..89c3949e89 100644 --- a/projects/templates/src/test.ts +++ b/projects/templates/src/test.ts @@ -1,8 +1,5 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files -import 'zone.js'; -import 'zone.js/testing'; - import { NgModule, provideZoneChangeDetection } from '@angular/core'; import { getTestBed } from '@angular/core/testing'; import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing'; diff --git a/projects/templates/tsconfig.lib.json b/projects/templates/tsconfig.lib.json index cf6fbcdce5..7033507129 100644 --- a/projects/templates/tsconfig.lib.json +++ b/projects/templates/tsconfig.lib.json @@ -10,9 +10,9 @@ "angularCompilerOptions": { "skipTemplateCodegen": true, "strictMetadataEmit": true, - "fullTemplateTypeCheck": true, "strictInjectionParameters": true, - "enableResourceInlining": true + "enableResourceInlining": true, + "strictTemplates": false }, "exclude": ["src/test.ts", "**/*.spec.ts"] } diff --git a/projects/templates/tsconfig.schematics.json b/projects/templates/tsconfig.schematics.json index bc534f2dd4..ef56acf655 100644 --- a/projects/templates/tsconfig.schematics.json +++ b/projects/templates/tsconfig.schematics.json @@ -1,11 +1,10 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "baseUrl": "../../", "lib": ["es2022", "dom"], "declaration": true, - "module": "commonjs", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "noEmitOnError": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": false, diff --git a/projects/templates/tsconfig.spec.json b/projects/templates/tsconfig.spec.json index 519c167a68..92ff656bd5 100644 --- a/projects/templates/tsconfig.spec.json +++ b/projects/templates/tsconfig.spec.json @@ -6,5 +6,8 @@ "skipLibCheck": true }, "files": ["src/test.ts"], - "include": ["**/*.spec.ts", "**/*.d.ts"] + "include": ["**/*.spec.ts", "**/*.d.ts"], + "angularCompilerOptions": { + "strictTemplates": false + } } diff --git a/projects/ui/.eslintrc.json b/projects/ui/.eslintrc.json deleted file mode 100644 index 280fa24b75..0000000000 --- a/projects/ui/.eslintrc.json +++ /dev/null @@ -1,194 +0,0 @@ -{ - "extends": "../../.eslintrc.json", - "ignorePatterns": ["!**/*", "**/util-expect.spec.ts"], - "overrides": [ - { - "files": ["*.ts"], - "parserOptions": { - "project": ["projects/ui/tsconfig.lib.json", "projects/ui/tsconfig.spec.json"], - "createDefaultProgram": true - }, - "plugins": ["sonarjs"], - "excludedFiles": [ - "test.ts", - "**/*.spec.ts", - "**/*.po.ts", - "./node_modules/", - "./projects/ui/src/lib/util-test/util-expect.spec.ts" - ], - "rules": { - "@angular-eslint/component-selector": [ - "error", - { - "type": ["element", "attribute"], - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/directive-class-suffix": "off", - "@angular-eslint/no-host-metadata-property": "off", - "prefer-spread": "off", - "@angular-eslint/directive-selector": [ - "warn", - { - "type": "attribute", - "prefix": "", - "style": "kebab-case" - } - ], - "@angular-eslint/no-input-rename": "off", - "@angular-eslint/no-output-rename": "off", - "@typescript-eslint/array-type": [ - "error", - { - "default": "generic" - } - ], - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "off", - { - "types": { - "String": { - "message": "Use string instead", - "fixWith": "string" - }, - "Boolean": { - "message": "Use boolean instead", - "fixWith": "boolean" - }, - "Number": { - "message": "Use number instead", - "fixWith": "number" - } - } - } - ], - "@typescript-eslint/consistent-type-assertions": "off", - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/dot-notation": "off", - "@typescript-eslint/explicit-member-accessibility": [ - "off", - { - "accessibility": "explicit" - } - ], - "@typescript-eslint/member-delimiter-style": [ - "off", - { - "multiline": { - "delimiter": "none", - "requireLast": true - }, - "singleline": { - "delimiter": "semi", - "requireLast": false - } - } - ], - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": [ - "off", - { - "ignoreParameters": true - } - ], - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "@typescript-eslint/no-var-requires": "error", - "@typescript-eslint/prefer-for-of": "off", - "@typescript-eslint/quotes": [ - "off", - "single", - { - "allowTemplateLiterals": true - } - ], - "@typescript-eslint/require-array-sort-compare": [ - "error", - { - "ignoreStringArrays": true - } - ], - "@typescript-eslint/semi": ["off", null], - "@typescript-eslint/type-annotation-spacing": "off", - "arrow-parens": ["off", "always"], - "brace-style": ["off", "off"], - "default-case-last": "error", - "dot-notation": "off", - "eol-last": "off", - "id-blacklist": "off", - "id-match": "off", - "indent": "off", - "linebreak-style": "off", - "max-len": "off", - "max-lines-per-function": [ - "off", - { - "max": 200 - } - ], - "max-params": [ - "error", - { - "max": 8 - } - ], - "new-parens": "off", - "newline-per-chained-call": "off", - "no-empty-function": "off", - "no-empty-pattern": "off", - "no-extra-parens": "off", - "no-extra-semi": "error", - "no-irregular-whitespace": "off", - "no-multi-str": "error", - "no-self-assign": "error", - "no-shadow": "off", - "no-trailing-spaces": "off", - "no-underscore-dangle": "off", - "no-unused-expressions": "error", - "no-use-before-define": "off", - "object-shorthand": "off", - "padded-blocks": [ - "off", - { - "blocks": "never" - }, - { - "allowSingleLineBlocks": true - } - ], - "prefer-arrow/prefer-arrow-functions": "off", - "quote-props": "off", - "semi": "off", - "sonarjs/cognitive-complexity": "off", - "sonarjs/max-switch-cases": "error", - "sonarjs/no-all-duplicated-branches": "error", - "sonarjs/no-collapsible-if": "error", - "sonarjs/no-collection-size-mischeck": "error", - "sonarjs/no-duplicate-string": "off", - "sonarjs/no-duplicated-branches": "off", - "sonarjs/no-element-overwrite": "error", - "sonarjs/no-identical-conditions": "error", - "sonarjs/no-identical-expressions": "error", - "sonarjs/no-identical-functions": "off", - "sonarjs/no-inverted-boolean-check": "error", - "sonarjs/no-one-iteration-loop": "off", - "sonarjs/no-redundant-boolean": "error", - "sonarjs/no-redundant-jump": "error", - "sonarjs/no-same-line-conditional": "error", - "sonarjs/no-small-switch": "error", - "sonarjs/no-unused-collection": "error", - "sonarjs/no-use-of-empty-return-value": "error", - "sonarjs/no-useless-catch": "error", - "sonarjs/prefer-immediate-return": "error", - "space-before-function-paren": "off", - "space-in-parens": ["off", "never"] - } - }, - { - "files": ["*.html"], - "rules": {} - } - ] -} diff --git a/projects/ui/README.md b/projects/ui/README.md index ba3983fb88..f9dc90304f 100644 --- a/projects/ui/README.md +++ b/projects/ui/README.md @@ -12,14 +12,14 @@ Biblioteca de componentes de UI para Angular. --- -### Adiconando o pacote @po-ui/ng-components +### Adicionando o pacote @po-ui/ng-components Utilizando o comando `ng add` do [Angular CLI](https://cli.angular.io/), vamos adicionar o **Po** em seu projeto e o mesmo se encarregará de configurar o tema, instalar o pacote e importar o módulo do **Po**. Além de importar também o modulo **HttpClientModule**. Execute o comando abaixo na pasta raiz do seu projeto: ``` -ng add @po-ui/ng-components +ng add @po-ui/ng-components@next ``` diff --git a/projects/ui/karma.conf.js b/projects/ui/karma.conf.js index 6d5a4a799d..33b8217951 100644 --- a/projects/ui/karma.conf.js +++ b/projects/ui/karma.conf.js @@ -4,17 +4,12 @@ module.exports = function (config) { config.set({ basePath: '', - files: [ - { pattern: './src/lib/util-test/util-setup.spec.ts', watched: false, type: 'js' }, - { pattern: './src/**/*.spec.ts', watched: false, type: 'js' } - ], frameworks: ['jasmine', '@angular-devkit/build-angular'], plugins: [ require('karma-jasmine'), require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), - require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('karma-coverage') ], client: { clearContext: false // leave Jasmine Spec Runner output visible in browser @@ -40,7 +35,8 @@ module.exports = function (config) { branches: 99, statements: 99, lines: 99, - functions: 99 + functions: 99, + excludes: ['**/po-grid/**'] } } }, diff --git a/projects/ui/package.json b/projects/ui/package.json index 1528bb57aa..ab51aa1267 100644 --- a/projects/ui/package.json +++ b/projects/ui/package.json @@ -21,7 +21,7 @@ ] }, "dependencies": { - "@angular/cdk": "~21.2.14", + "@angular/cdk": "~22.2.1", "@po-ui/style": "0.0.0-PLACEHOLDER", "@po-ui/ng-schematics": "0.0.0-PLACEHOLDER", "driver.js": "~1.4.0", @@ -29,16 +29,14 @@ "tslib": "^2.6.2" }, "peerDependencies": { - "@angular/animations": "^21", - "@angular/cdk": "^21", - "@angular/common": "^21", - "@angular/compiler": "^21", - "@angular/core": "^21", - "@angular/forms": "^21", - "@angular/platform-browser": "^21", - "@angular/platform-browser-dynamic": "^21", - "@angular/router": "^21", - "@angular-devkit/schematics": "^21", + "@angular/cdk": "^22", + "@angular/common": "^22", + "@angular/compiler": "^22", + "@angular/core": "^22", + "@angular/forms": "^22", + "@angular/platform-browser": "^22", + "@angular/router": "^22", + "@angular-devkit/schematics": "^22", "@po-ui/style": "0.0.0-PLACEHOLDER", "rxjs": "~7.8.1", "zone.js": "~0.15.0" diff --git a/projects/ui/schematics/collection.json b/projects/ui/schematics/collection.json index 7ab5b42261..a74207451f 100644 --- a/projects/ui/schematics/collection.json +++ b/projects/ui/schematics/collection.json @@ -15,26 +15,6 @@ "description": "Crate a app.component with sidemenu layout configured and create a component how sample", "factory": "./ng-generate/sidemenu/index", "schema": "./ng-generate/sidemenu/schema.json" - }, - "po-page-list": { - "description": "Crate a component with po-page-list", - "factory": "./ng-generate/po-page-list/index", - "schema": "./ng-generate/po-page-list/schema.json" - }, - "po-page-edit": { - "description": "Crate a component with po-page-edit", - "factory": "./ng-generate/po-page-edit/index", - "schema": "./ng-generate/po-page-edit/schema.json" - }, - "po-page-detail": { - "description": "Crate a component with po-page-detail", - "factory": "./ng-generate/po-page-detail/index", - "schema": "./ng-generate/po-page-detail/schema.json" - }, - "po-page-default": { - "description": "Crate a component with po-page-default", - "factory": "./ng-generate/po-page-default/index", - "schema": "./ng-generate/po-page-default/schema.json" } } } diff --git a/projects/ui/schematics/migrations.json b/projects/ui/schematics/migrations.json index 7b93aa0e67..e125bbfc7c 100644 --- a/projects/ui/schematics/migrations.json +++ b/projects/ui/schematics/migrations.json @@ -65,6 +65,11 @@ "version": "21", "description": "Atualiza @po-ui/ng-components para v21", "factory": "./ng-update/v21/index" + }, + "migration-v22": { + "version": "22", + "description": "Atualiza @po-ui/ng-components para v22", + "factory": "./ng-update/v22/index" } } } diff --git a/projects/ui/schematics/ng-add/setup-project.ts b/projects/ui/schematics/ng-add/setup-project.ts index f080b124f9..8aca74f7b5 100644 --- a/projects/ui/schematics/ng-add/setup-project.ts +++ b/projects/ui/schematics/ng-add/setup-project.ts @@ -25,6 +25,7 @@ const httpClientModuleSourcePath = '@angular/common/http'; * - Add PO Module to app root module * - Adds themes to styles * - Run sidemenu schematic + * - Add provideZoneChangeDetection: standalone via app.config.ts, module-based via main.ts */ export default function (options: any): Rule { return chain([ @@ -33,6 +34,7 @@ export default function (options: any): Rule { addProviderToAppModule(options, 'provideHttpClient(withInterceptorsFromDi())'), addThemeToAppStyles(options), addPolyfillsZoneJS(options), + addZoneChangeDetection(options), updateAppConfigFileRule(options), configureSideMenu(options) ]); @@ -159,7 +161,7 @@ export function addProviderToModuleProvider( ) { const moduleSource = getSourceFile(tree, modulePath); const changes = addProviderToModule( - moduleSource as any, + moduleSource, modulePath, ` ${provider}`, @@ -243,3 +245,116 @@ function addPolyfillsZoneJS(options: any): (tree: Tree) => Tree { return tree; }; } + +/** + * Adiciona provideZoneChangeDetection ao main.ts de apps module-based. + * + * Para apps standalone, o provider já é adicionado no app.config.ts por + * `updateAppConfigFileRule`, então esta rule ignora esse caso para evitar + * a duplicação de providers (NG0408). + */ +function addZoneChangeDetection(options: any): (tree: Tree) => Tree { + return function (tree: Tree): Tree { + const workspace = getWorkspaceConfigGracefully(tree) ?? ({} as WorkspaceSchema); + const project: any = getProjectFromWorkspace(workspace, options.project); + const browserEntryPoint = getProjectMainFile(project); + + // Apps standalone são tratados por updateAppConfigFileRule (app.config.ts) + if (isStandaloneApp(tree, browserEntryPoint)) { + return tree; + } + + // O browserEntryPoint já vem como caminho relativo ao workspace root + // Exemplo: "projects/test-app/src/main.ts" + const mainFilePath = browserEntryPoint; + + if (!tree.exists(mainFilePath)) { + return tree; + } + + const content = tree.read(mainFilePath)?.toString('utf-8') || ''; + + // Verifica se já tem provideZoneChangeDetection + if (content.includes('provideZoneChangeDetection')) { + return tree; + } + + const modifiedContent = updateMainFile(content); + + // Se nada mudou (padrão de bootstrap não reconhecido), não sobrescreve + if (modifiedContent === content) { + return tree; + } + + tree.overwrite(mainFilePath, modifiedContent); + + return tree; + }; +} + +/** + * Atualiza o main.ts de um app module-based para incluir provideZoneChangeDetection + * via `applicationProviders` (opção correta para platformBrowser().bootstrapModule). + * + * Também garante o import de `provideZoneChangeDetection` a partir de '@angular/core'. + */ +function updateMainFile(content: string): string { + if (!content.includes('platformBrowser()') || !content.includes('bootstrapModule')) { + return content; + } + + // Já configurado; evita duplicar o provider (NG0408) + if (content.includes('provideZoneChangeDetection')) { + return content; + } + + let updated = content; + + const provider = 'provideZoneChangeDetection({ eventCoalescing: true })'; + + // bootstrapModule(AppModule, { ... }) -> injeta applicationProviders no objeto existente + const regexWithOptions = /(bootstrapModule\([^,]+,\s*\{)/; + // bootstrapModule(AppModule) -> reconstrói a chamada adicionando o objeto de opções + // Captura o argumento do módulo (grupo 1) para reinserir dentro dos parênteses. + const regexNoOptions = /bootstrapModule\(\s*([^,)]+?)\s*\)/; + + if (regexWithOptions.test(updated)) { + updated = updated.replace(regexWithOptions, `$1\n applicationProviders: [${provider}],`); + } else if (regexNoOptions.test(updated)) { + updated = updated.replace(regexNoOptions, `bootstrapModule($1, { applicationProviders: [${provider}] })`); + } else { + return content; + } + + updated = ensureCoreImport(updated); + + return updated; +} + +/** + * Garante que `provideZoneChangeDetection` esteja importado de '@angular/core'. + * - Se já existe um import de '@angular/core', adiciona o símbolo à lista. + * - Caso contrário, insere uma nova linha de import no topo do arquivo. + */ +function ensureCoreImport(content: string): string { + if (content.includes('provideZoneChangeDetection')) { + // símbolo já usado; verifica se está de fato importado + const alreadyImported = + /import\s*\{[^}]*\bprovideZoneChangeDetection\b[^}]*\}\s*from\s*['"]@angular\/core['"]/.test(content); + if (alreadyImported) { + return content; + } + } + + const coreImportRegex = /import\s*\{([^}]*)\}\s*from\s*['"]@angular\/core['"];?/; + + if (coreImportRegex.test(content)) { + return content.replace(coreImportRegex, (_match, symbols) => { + const trimmed = symbols.trim().replace(/,\s*$/, ''); + return `import { ${trimmed}, provideZoneChangeDetection } from '@angular/core';`; + }); + } + + // Não há import de @angular/core; adiciona no topo + return `import { provideZoneChangeDetection } from '@angular/core';\n${content}`; +} diff --git a/projects/ui/schematics/ng-generate/po-page-default/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/ui/schematics/ng-generate/po-page-default/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/ui/schematics/ng-generate/po-page-default/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/ui/schematics/ng-generate/po-page-default/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 1fb992b060..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/projects/ui/schematics/ng-generate/po-page-default/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/ui/schematics/ng-generate/po-page-default/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index c25f19db8d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,31 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { PoPageModule } from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageModule - ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/ui/schematics/ng-generate/po-page-default/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/ui/schematics/ng-generate/po-page-default/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 630b3b95dc..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,23 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { PoPageAction, PoPageModule } from '@po-ui/ng-components'; - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageModule, - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - readonly pageActions: Array = []; - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 1fb992b060..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 99b200753e..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,32 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { PoPageModule } from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageModule - ], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 9e8a445023..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { PoPageAction } from '@po-ui/ng-components'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - readonly pageActions: Array = []; - - constructor() { } - - ngOnInit() { } - -} diff --git a/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index f3494af238..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoModule } from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoModule,<% if (routing) { %> -<%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/ui/schematics/ng-generate/po-page-default/index.spec.ts b/projects/ui/schematics/ng-generate/po-page-default/index.spec.ts deleted file mode 100644 index 9aa1bc38c4..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/index.spec.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-default:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic('po-page-default', { ...componentOptions, name: componentName }, appTree); - - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-default', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-default', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-default', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-default', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-default', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-default', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-default', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-default', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-default', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-default', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-default', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/ui/schematics/ng-generate/po-page-default/index.ts b/projects/ui/schematics/ng-generate/po-page-default/index.ts deleted file mode 100644 index 60d04b816a..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent } from '@po-ui/ng-schematics/build-component'; - -import { Schema as ComponentOptions } from './schema'; - -/** Scaffolds a new component with */ -export default function (options: ComponentOptions): Rule { - return chain([createPageDefaultComponent(options)]); -} - -function createPageDefaultComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/ui/schematics/ng-generate/po-page-default/schema.json b/projects/ui/schematics/ng-generate/po-page-default/schema.json deleted file mode 100644 index 202ce55072..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/schema.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageDefault", - "title": "Page Default Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "alias": "S", - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "alias": "p", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - } - }, - "required": ["name"] -} diff --git a/projects/ui/schematics/ng-generate/po-page-default/schema.ts b/projects/ui/schematics/ng-generate/po-page-default/schema.ts deleted file mode 100644 index 0e5e0a349d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-default/schema.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema {} diff --git a/projects/ui/schematics/ng-generate/po-page-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/ui/schematics/ng-generate/po-page-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/ui/schematics/ng-generate/po-page-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/ui/schematics/ng-generate/po-page-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index c0bbb1685d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/projects/ui/schematics/ng-generate/po-page-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/ui/schematics/ng-generate/po-page-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index c25f19db8d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,31 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { PoPageModule } from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageModule - ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/ui/schematics/ng-generate/po-page-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/ui/schematics/ng-generate/po-page-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index c772b5bc52..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,33 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { PoPageModule } from '@po-ui/ng-components'; - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageModule, - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - constructor() { } - - ngOnInit() { } - - back() { - // back action here - } - - edit() { - // edit action here - } - - remove() { - // remove action here - } - -} diff --git a/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index c0bbb1685d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 99b200753e..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,32 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { PoPageModule } from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageModule - ], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 60c88c144a..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,27 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - constructor() { } - - ngOnInit() { } - - back() { - // back action here - } - - edit() { - // edit action here - } - - remove() { - // remove action here - } - -} diff --git a/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index f3494af238..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoModule } from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoModule,<% if (routing) { %> -<%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/ui/schematics/ng-generate/po-page-detail/index.spec.ts b/projects/ui/schematics/ng-generate/po-page-detail/index.spec.ts deleted file mode 100644 index fadc4ebd71..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/index.spec.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-detail:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic('po-page-detail', { ...componentOptions, name: componentName }, appTree); - - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-detail', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-detail', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-detail', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-detail', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-detail', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-detail', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-detail', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-detail', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-detail', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-detail', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-detail', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/ui/schematics/ng-generate/po-page-detail/index.ts b/projects/ui/schematics/ng-generate/po-page-detail/index.ts deleted file mode 100644 index e3914b6bec..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent, Schema as ComponentOptions } from '@po-ui/ng-schematics/build-component'; - -/** Scaffolds a new component with */ -export default function (options: ComponentOptions): Rule { - return chain([createPageDetailComponent(options)]); -} - -function createPageDetailComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/ui/schematics/ng-generate/po-page-detail/schema.json b/projects/ui/schematics/ng-generate/po-page-detail/schema.json deleted file mode 100644 index 75ed730e9c..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/schema.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageDetail", - "title": "Page Detail Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "alias": "S", - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "alias": "p", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - } - }, - "required": ["name"] -} diff --git a/projects/ui/schematics/ng-generate/po-page-detail/schema.ts b/projects/ui/schematics/ng-generate/po-page-detail/schema.ts deleted file mode 100644 index 0e5e0a349d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-detail/schema.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema {} diff --git a/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 1546109fb6..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index c25f19db8d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,31 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { PoPageModule } from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageModule - ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 8496bcb050..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,33 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { PoPageModule } from '@po-ui/ng-components'; - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageModule, - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - constructor() { } - - ngOnInit() { } - - cancel() { - // cancel action here - } - - save() { - // save action here - } - - saveNew() { - // saveNew action here - } - -} diff --git a/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 1546109fb6..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 99b200753e..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,32 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { PoPageModule } from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageModule - ], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 0d33db922d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,27 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - constructor() { } - - ngOnInit() { } - - cancel() { - // cancel action here - } - - save() { - // save action here - } - - saveNew() { - // saveNew action here - } - -} diff --git a/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index f3494af238..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoModule } from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoModule,<% if (routing) { %> -<%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/ui/schematics/ng-generate/po-page-edit/index.spec.ts b/projects/ui/schematics/ng-generate/po-page-edit/index.spec.ts deleted file mode 100644 index 938f7a5f15..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/index.spec.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-edit:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic('po-page-edit', { ...componentOptions, name: componentName }, appTree); - - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-edit', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-edit', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-edit', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-edit', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-edit', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-edit', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-edit', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-edit', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-edit', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-edit', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-edit', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/ui/schematics/ng-generate/po-page-edit/index.ts b/projects/ui/schematics/ng-generate/po-page-edit/index.ts deleted file mode 100644 index 106a2d6795..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent, Schema as ComponentOptions } from '@po-ui/ng-schematics/build-component'; - -/** Scaffolds a new component with */ -export default function (options: ComponentOptions): Rule { - return chain([createPageEditComponent(options)]); -} - -function createPageEditComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/ui/schematics/ng-generate/po-page-edit/schema.json b/projects/ui/schematics/ng-generate/po-page-edit/schema.json deleted file mode 100644 index c80c593cc9..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/schema.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageEdit", - "title": "Page Edit Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "alias": "S", - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "alias": "p", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - } - }, - "required": ["name"] -} diff --git a/projects/ui/schematics/ng-generate/po-page-edit/schema.ts b/projects/ui/schematics/ng-generate/po-page-edit/schema.ts deleted file mode 100644 index 0e5e0a349d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-edit/schema.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema {} diff --git a/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 7edb5d0c0d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,28 +0,0 @@ - -<% if(dataView === 'table') { %> - - -<% } else { %> - - - -
    - - - - - -
    -
    - -
    -<% }%> -
    diff --git a/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 21df6c66b3..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,36 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageModule, PoInfoModule<% if(dataView === 'table') { %>, PoTableModule <% } else { %>, PoListViewModule <% } %>} from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageModule, - PoInfoModule,<% if(dataView === 'table') { %> - PoTableModule<% } else {%> - PoListViewModule<% } %> - ], - providers: [provideHttpClient()] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 90d38a2b25..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,42 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -import { PoPageAction<% if(dataView === 'table') { %>, PoTableColumn<%} %> } from '@po-ui/ng-components'; -import { PoPageModule } from '@po-ui/ng-components'; -import { PoModule } from '@po-ui/ng-components'; - - -@Component({ - selector: '<%= selector %>', - imports: [ - CommonModule, - PoPageModule, - PoModule - ], - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'] -}) -export class <%= classify(name) %>Component implements OnInit { - - readonly actions: Array = [ - // actions of table here - ];<% if(dataView === 'table') { %> - - readonly columns: Array = [ - // columns of table here - { property: 'name', width: '50%' }, - { property: 'age', width: '15%' }, - { property: 'email', width: '35%' } - ]; -<%} %> - items: Array = []; - - constructor() { } - - ngOnInit() { - this.items = [ - { name: 'John Doe', age: 33, email: 'johndoe@example.com' } - ]; - } - -} diff --git a/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template b/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template deleted file mode 100644 index 08a37212f2..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__-routing.module.ts.template +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -const routes: Routes = [ - { path: '', component: <%= classify(name) %>Component } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class <%= classify(name) %>RoutingModule { } diff --git a/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template b/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template deleted file mode 100644 index 7edb5d0c0d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.component.html.template +++ /dev/null @@ -1,28 +0,0 @@ - -<% if(dataView === 'table') { %> - - -<% } else { %> - - - -
    - - - - - -
    -
    - -
    -<% }%> -
    diff --git a/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template b/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template deleted file mode 100644 index 8484fd57c5..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.component.spec.ts.template +++ /dev/null @@ -1,37 +0,0 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { provideHttpClient } from '@angular/common/http'; - -import { PoPageModule, PoInfoModule<% if(dataView === 'table') { %>, PoTableModule <% } else { %>, PoListViewModule <% } %>} from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component'; - -describe('<%= classify(name) %>Component', () => { - let component: <%= classify(name) %>Component; - let fixture: ComponentFixture<<%= classify(name) %>Component>; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - PoPageModule, - PoInfoModule,<% if(dataView === 'table') { %> - PoTableModule<% } else {%> - PoListViewModule<% } %> - ], - providers: [provideHttpClient()], - declarations: [ <%= classify(name) %>Component ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(<%= classify(name) %>Component); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template b/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template deleted file mode 100644 index 546297171d..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.component.ts.template +++ /dev/null @@ -1,34 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { PoPageAction<% if(dataView === 'table') { %>, PoTableColumn<%} %> } from '@po-ui/ng-components'; - -@Component({ - selector: '<%= selector %>', - templateUrl: './<%= dasherize(name) %>.component.html', - styleUrls: ['./<%= dasherize(name) %>.component.<%= style %>'], - standalone: false -}) -export class <%= classify(name) %>Component implements OnInit { - - readonly actions: Array = [ - // actions of table here - ];<% if(dataView === 'table') { %> - - readonly columns: Array = [ - // columns of table here - { property: 'name', width: '50%' }, - { property: 'age', width: '15%' }, - { property: 'email', width: '35%' } - ]; -<%} %> - items: Array = []; - - constructor() { } - - ngOnInit() { - this.items = [ - { name: 'John Doe', age: 33, email: 'johndoe@example.com' } - ]; - } - -} diff --git a/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template b/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template deleted file mode 100644 index 4bbac8a5c0..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/files/__path__/__name@dasherize__/__name@dasherize__.module.ts.template +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoModule } from '@po-ui/ng-components'; - -import { <%= classify(name) %>Component } from './<%= dasherize(name) %>.component';<% if (routing) { %> -import { <%= classify(name) %>RoutingModule } from './<%= dasherize(name) %>-routing.module';<% } %> - -@NgModule({ - declarations: [ - <%= classify(name) %>Component - ], - imports: [ - CommonModule, - PoModule,<% if (routing) { %> - <%= classify(name) %>RoutingModule<% } %> - ] -}) -export class <%= classify(name) %>Module { } diff --git a/projects/ui/schematics/ng-generate/po-page-list/index.spec.ts b/projects/ui/schematics/ng-generate/po-page-list/index.spec.ts deleted file mode 100644 index d22ff4c204..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/index.spec.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { Tree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema'; -import * as path from 'path'; - -const collectionPath = path.join(__dirname, '../../collection.json'); - -xdescribe('po-page-list:', () => { - const runner = new SchematicTestRunner('schematics', collectionPath); - - const workspaceOptions: WorkspaceOptions = { - name: 'workspace', - newProjectRoot: 'projects', - version: '6.0.0' - }; - - const componentOptions: any = { - name: 'po', - style: 'css', - skipTests: false - }; - - let appTree: UnitTestTree; - - beforeEach(async () => { - appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); - }); - - it('should create component', async () => { - const componentName = 'supply'; - const tree = await runner.runSchematic('po-page-list', { ...componentOptions, name: componentName }, appTree); - - const files: Array = tree.files; - - const fullFilePath = (ext: string) => - `/projects/${componentOptions.name}/src/app/${componentName}/${componentName}.component.${ext}`; - - expect(files).toContain(fullFilePath('ts')); - expect(files).toContain(fullFilePath('html')); - expect(files).toContain(fullFilePath('spec.ts')); - expect(files).toContain(fullFilePath(componentOptions.style)); - }); - - it('should create component and module', async () => { - const componentName = 'supply'; - const createModule = true; - - const options = { ...componentOptions, name: componentName, createModule, project: 'po' }; - - const tree = await runner.runSchematic('po-page-list', options, appTree); - - const files: Array = tree.files; - - expect(files).toContain(`/projects/${options.project}/src/app/${componentName}/${componentName}.module.ts`); - }); - - it('should add declaration component in closest module by default', async () => { - const options = { ...componentOptions, name: 'customers' }; - const tree = await runner.runSchematic('po-page-list', options, appTree); - - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersComponent.*from '.\/customers\/customers.component'/); - expect(moduleContent).toMatch(/declarations:\s*\[[^\]]+?,\r?\n\s+CustomersComponent\r?\n/m); - }); - - it('should import component module if createModule is true', async () => { - const options = { ...componentOptions, name: 'customers', createModule: true }; - - const tree = await runner.runSchematic('po-page-list', options, appTree); - const moduleContent = getFileContent(tree, `/projects/${componentOptions.name}/src/app/app.module.ts`); - - expect(moduleContent).toMatch(/import.*CustomersModule.*from '.\/customers\/customers.module'/); - expect(moduleContent).toMatch(/imports:\s*\[[^\]]+?,\r?\n\s+CustomersModule\r?\n/m); - }); - - it('should generate component.less if style is `less`', async () => { - const options = { ...componentOptions, name: 'customers', style: 'less' }; - const tree = await runner.runSchematic('po-page-list', options, appTree); - - const files = tree.files; - - expect(files).toContain( - `/projects/${componentOptions.name}/src/app/customers/customers.component.${options.style}` - ); - }); - - it('should generate component with stylesheet `css` if options.style is empty', async () => { - const options = { ...componentOptions, name: 'customers', style: '' }; - - const tree = await runner.runSchematic('po-page-list', options, appTree); - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.css`); - }); - - it('shouldn`t generate component spec if `skipTests` is true', async () => { - const options = { ...componentOptions, name: 'customers', skipTests: true }; - const tree = await runner.runSchematic('po-page-list', options, appTree); - - const files = tree.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.ts`); - expect(files).not.toContain(`/projects/${componentOptions.name}/src/app/customers/customers.component.spec.ts`); - }); - - it('should generate component in path informed', async () => { - // create customers component module to use with path option - const options = { ...componentOptions, name: 'customers', createModule: true }; - await runner.runSchematic('po-page-list', options, appTree); - - const optionsPath = { - ...componentOptions, - name: 'wms', - path: `/projects/${componentOptions.name}/src/app/customers` - }; - - const treePath = await runner.runSchematic('po-page-list', optionsPath, appTree); - - const files = treePath.files; - - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.spec.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/customers/wms/wms.component.${options.style}`); - }); - - it('should use the custom prefix when create component', async () => { - const prefix = 'wms'; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-list', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: '${prefix}-customers'`)); - }); - - it('should use the default prefix when create component if prefix is null', async () => { - const prefix = undefined; - - const options = { ...componentOptions, name: 'customers', sample: true, prefix }; - const tree = await runner.runSchematic('po-page-list', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'app-customers'`)); - }); - - it('should use only the name how prefix when create component if prefix is ""', async () => { - const prefix = ''; - - const options = { ...componentOptions, name: 'customers', prefix }; - const tree = await runner.runSchematic('po-page-list', options, appTree); - - const componentContent = getFileContent( - tree, - `/projects/${componentOptions.name}/src/app/customers/customers.component.ts` - ); - - expect(componentContent).toMatch(new RegExp(`selector: 'customers'`)); - }); -}); - -/** Gets the content of a specified file from a schematic tree. */ -function getFileContent(tree: Tree, filePath: string): string { - const contentBuffer = tree.read(filePath); - - if (!contentBuffer) { - throw new Error(`Cannot read "${filePath}" because it does not exist.`); - } - - return contentBuffer.toString(); -} diff --git a/projects/ui/schematics/ng-generate/po-page-list/index.ts b/projects/ui/schematics/ng-generate/po-page-list/index.ts deleted file mode 100644 index ee46878aba..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { chain, Rule } from '@angular-devkit/schematics'; - -import { buildComponent, Schema as ComponentOptions } from '@po-ui/ng-schematics/build-component'; - -/** - * Scaffolds a new component with - * - The property dataView set which component will be used to display data. - */ -export default function (options: ComponentOptions): Rule { - return chain([createPageListComponent(options)]); -} - -function createPageListComponent(options: ComponentOptions): Rule { - return buildComponent(options); -} diff --git a/projects/ui/schematics/ng-generate/po-page-list/schema.json b/projects/ui/schematics/ng-generate/po-page-list/schema.json deleted file mode 100644 index 79c69e33c2..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/schema.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "SchematicsPOPageList", - "title": "PageList Options Schema", - "type": "object", - "properties": { - "style": { - "description": "The file extension or preprocessor to use for style files.", - "type": "string", - "default": "css" - }, - "project": { - "type": "string", - "description": "The name of the project.", - "$default": { - "$source": "projectName" - } - }, - "routing": { - "type": "boolean", - "description": "When true, creates a routing module.", - "default": false - }, - "createModule": { - "type": "boolean", - "description": "When true, do not create a component module.", - "default": false - }, - "name": { - "type": "string", - "description": "The name to use for the component", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the component?" - }, - "skipTests": { - "description": "When true, does not create \"spec.ts\" test files for the app.", - "type": "boolean", - "default": false, - "x-user-analytics": 12 - }, - "path": { - "type": "string", - "format": "path", - "description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.", - "visible": false - }, - "prefix": { - "type": "string", - "description": "The prefix to apply to the generated component selector.", - "oneOf": [ - { - "maxLength": 0 - }, - { - "minLength": 1, - "format": "html-selector" - } - ] - }, - "dataView": { - "description": "Component to show datas.", - "type": "string", - "default": "table", - "x-prompt": { - "message": "Which component would you like to use to display data?", - "type": "list", - "items": [ - { "value": "table", "label": "PO Table [ https://po-ui.io/documentation/po-table ]" }, - { "value": "list", "label": "PO List View [ https://po-ui.io/documentation/po-list-view ]" } - ] - } - } - }, - "required": ["name"] -} diff --git a/projects/ui/schematics/ng-generate/po-page-list/schema.ts b/projects/ui/schematics/ng-generate/po-page-list/schema.ts deleted file mode 100644 index b508f0efbe..0000000000 --- a/projects/ui/schematics/ng-generate/po-page-list/schema.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Schema as ComponentSchema } from '@po-ui/ng-schematics/build-component'; - -export interface Schema extends ComponentSchema { - /** Which component will be used to display the data. */ - dataView?: 'table' | 'list'; -} diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/ui/schematics/ng-generate/sidemenu/files-standalone/__appFileName__.__style__.template similarity index 100% rename from projects/templates/schematics/ng-generate/po-page-blocked-user/files-standalone/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template rename to projects/ui/schematics/ng-generate/sidemenu/files-standalone/__appFileName__.__style__.template diff --git a/projects/ui/schematics/ng-generate/sidemenu/files-standalone/app.html.template b/projects/ui/schematics/ng-generate/sidemenu/files-standalone/__appFileName__.html.template similarity index 100% rename from projects/ui/schematics/ng-generate/sidemenu/files-standalone/app.html.template rename to projects/ui/schematics/ng-generate/sidemenu/files-standalone/__appFileName__.html.template diff --git a/projects/ui/schematics/ng-generate/sidemenu/files-standalone/app.spec.ts.template b/projects/ui/schematics/ng-generate/sidemenu/files-standalone/__appFileName__.spec.ts.template similarity index 61% rename from projects/ui/schematics/ng-generate/sidemenu/files-standalone/app.spec.ts.template rename to projects/ui/schematics/ng-generate/sidemenu/files-standalone/__appFileName__.spec.ts.template index 82477a939f..3424e8e601 100644 --- a/projects/ui/schematics/ng-generate/sidemenu/files-standalone/app.spec.ts.template +++ b/projects/ui/schematics/ng-generate/sidemenu/files-standalone/__appFileName__.spec.ts.template @@ -2,17 +2,17 @@ import { TestBed } from '@angular/core/testing'; import { PoMenuModule, PoPageModule, PoToolbarModule } from '@po-ui/ng-components'; -import { App } from './app'; +import { <%= appClassName %> } from './<%= appFileName %>'; -describe('App', () => { +describe('<%= appClassName %>', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [PoToolbarModule, PoMenuModule, PoPageModule, App], + imports: [PoToolbarModule, PoMenuModule, PoPageModule, <%= appClassName %>], }).compileComponents(); }); it('should create the app', () => { - const fixture = TestBed.createComponent(App); + const fixture = TestBed.createComponent(<%= appClassName %>); fixture.detectChanges(); const app = fixture.componentInstance; expect(app).toBeTruthy(); diff --git a/projects/ui/schematics/ng-generate/sidemenu/files-standalone/app.ts.template b/projects/ui/schematics/ng-generate/sidemenu/files-standalone/__appFileName__.ts.template similarity index 79% rename from projects/ui/schematics/ng-generate/sidemenu/files-standalone/app.ts.template rename to projects/ui/schematics/ng-generate/sidemenu/files-standalone/__appFileName__.ts.template index 48f6f5f0ca..351ffc66b9 100644 --- a/projects/ui/schematics/ng-generate/sidemenu/files-standalone/app.ts.template +++ b/projects/ui/schematics/ng-generate/sidemenu/files-standalone/__appFileName__.ts.template @@ -16,10 +16,10 @@ import { PoMenuModule, PoPageModule ], - templateUrl: './app.html', - styleUrls: ['./app.<%= style %>'], + templateUrl: './<%= appFileName %>.html', + styleUrls: ['./<%= appFileName %>.<%= style %>'], }) -export class App { +export class <%= appClassName %> { readonly menus: Array = [ { label: 'Home', action: this.onClick.bind(this) }, ]; diff --git a/projects/ui/schematics/ng-generate/sidemenu/files-standalone/app.__style__.template b/projects/ui/schematics/ng-generate/sidemenu/files-standalone/app.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template b/projects/ui/schematics/ng-generate/sidemenu/files/__appFileName__.__style__.template similarity index 100% rename from projects/templates/schematics/ng-generate/po-page-blocked-user/files/__path__/__name@dasherize__/__name@dasherize__.component.__style__.template rename to projects/ui/schematics/ng-generate/sidemenu/files/__appFileName__.__style__.template diff --git a/projects/ui/schematics/ng-generate/sidemenu/files/app.html.template b/projects/ui/schematics/ng-generate/sidemenu/files/__appFileName__.html.template similarity index 100% rename from projects/ui/schematics/ng-generate/sidemenu/files/app.html.template rename to projects/ui/schematics/ng-generate/sidemenu/files/__appFileName__.html.template diff --git a/projects/ui/schematics/ng-generate/sidemenu/files/__appFileName__.spec.ts.template b/projects/ui/schematics/ng-generate/sidemenu/files/__appFileName__.spec.ts.template new file mode 100644 index 0000000000..8d2332605d --- /dev/null +++ b/projects/ui/schematics/ng-generate/sidemenu/files/__appFileName__.spec.ts.template @@ -0,0 +1,35 @@ +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { TestBed } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; +import { provideHttpClient } from '@angular/common/http'; + +import { + PoMenuModule, + PoPageModule, + PoToolbarModule, +} from '@po-ui/ng-components'; + +import { <%= appClassName %> } from './<%= appFileName %>'; + +describe('<%= appClassName %>', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + PoMenuModule, + PoPageModule, + PoToolbarModule, + RouterModule.forRoot([]), + ], + declarations: [<%= appClassName %>], + providers: [provideLocationMocks(), provideHttpClient(), provideHttpClientTesting()] + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(<%= appClassName %>); + fixture.detectChanges(); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); +}); diff --git a/projects/ui/schematics/ng-generate/sidemenu/files/app.ts.template b/projects/ui/schematics/ng-generate/sidemenu/files/__appFileName__.ts.template similarity index 71% rename from projects/ui/schematics/ng-generate/sidemenu/files/app.ts.template rename to projects/ui/schematics/ng-generate/sidemenu/files/__appFileName__.ts.template index 6d99986da3..fcebecfc57 100644 --- a/projects/ui/schematics/ng-generate/sidemenu/files/app.ts.template +++ b/projects/ui/schematics/ng-generate/sidemenu/files/__appFileName__.ts.template @@ -4,11 +4,11 @@ import { PoMenuItem } from '@po-ui/ng-components'; @Component({ selector: 'app-root', - templateUrl: './app.html', - styleUrls: ['./app.<%= style %>'], + templateUrl: './<%= appFileName %>.html', + styleUrls: ['./<%= appFileName %>.<%= style %>'], standalone: false }) -export class App { +export class <%= appClassName %> { readonly menus: Array = [ { label: 'Home', action: this.onClick.bind(this) }, ]; diff --git a/projects/ui/schematics/ng-generate/sidemenu/files/app.__style__.template b/projects/ui/schematics/ng-generate/sidemenu/files/app.__style__.template deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/projects/ui/schematics/ng-generate/sidemenu/files/app.spec.ts.template b/projects/ui/schematics/ng-generate/sidemenu/files/app.spec.ts.template deleted file mode 100644 index b1f767117d..0000000000 --- a/projects/ui/schematics/ng-generate/sidemenu/files/app.spec.ts.template +++ /dev/null @@ -1,33 +0,0 @@ -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { - PoMenuModule, - PoPageModule, - PoToolbarModule, -} from '@po-ui/ng-components'; - -import { App } from './app'; - -describe('App', () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ - PoMenuModule, - PoPageModule, - PoToolbarModule, - HttpClientTestingModule, - RouterTestingModule, - ], - declarations: [App], - }).compileComponents(); - }); - - it('should create the app', () => { - const fixture = TestBed.createComponent(App); - fixture.detectChanges(); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); -}); diff --git a/projects/ui/schematics/ng-generate/sidemenu/index.spec.ts b/projects/ui/schematics/ng-generate/sidemenu/index.spec.ts index 26c42438a7..a061b2fd79 100644 --- a/projects/ui/schematics/ng-generate/sidemenu/index.spec.ts +++ b/projects/ui/schematics/ng-generate/sidemenu/index.spec.ts @@ -5,7 +5,7 @@ import * as path from 'path'; const collectionPath = path.join(__dirname, '../../collection.json'); -xdescribe('sidemenu:', () => { +describe('sidemenu:', () => { const runner = new SchematicTestRunner('schematics', collectionPath); const workspaceOptions: WorkspaceOptions = { @@ -14,55 +14,171 @@ xdescribe('sidemenu:', () => { version: '6.0.0' }; - const componentOptions: any = { + const applicationOptions: any = { name: 'po', style: 'css', skipTests: false }; + const sidemenuOptions: any = { + appName: 'AppName', + style: 'css', + skipTests: false, + project: 'po' + }; + let appTree: UnitTestTree; beforeEach(async () => { appTree = await runner.runExternalSchematic('@schematics/angular', 'workspace', workspaceOptions); - appTree = await runner.runExternalSchematic('@schematics/angular', 'application', componentOptions, appTree); + appTree = await runner.runExternalSchematic('@schematics/angular', 'application', applicationOptions, appTree); }); - describe('Imports:', () => { - it('should add the RouterModule to the project module', async () => { - const routerModuleName = 'RouterModule'; + describe('auto-detected style on a project using the current Angular convention:', () => { + it('should create the app files without type suffix and use the `App` class', async () => { + const tree = await runner.runSchematic('sidemenu', sidemenuOptions, appTree); + + const appDir = `/projects/${sidemenuOptions.project}/src/app`; + + expect(tree.files).toContain(`${appDir}/app.ts`); + expect(tree.files).toContain(`${appDir}/app.html`); + expect(tree.files).toContain(`${appDir}/app.${sidemenuOptions.style}`); + expect(getFileContent(tree, `${appDir}/app.ts`)).toContain('export class App {'); + }); + + it('should contain `po-wrapper`, `po-toolbar` and `po-menu` in the app template', async () => { + const tree = await runner.runSchematic('sidemenu', sidemenuOptions, appTree); - const tree = await runner.runSchematic('sidemenu', componentOptions, appTree); - const fileContent = getFileContent(tree, `projects/${componentOptions.name}/src/app/app.module.ts`); + const fileContent = getFileContent(tree, `/projects/${sidemenuOptions.project}/src/app/app.html`); - expect(fileContent).toContain(routerModuleName); + expect(fileContent).toContain('
    '); + expect(fileContent).toContain('po-toolbar'); + expect(fileContent).toContain(''); }); }); - describe('Component: ', () => { - it('should create app.component.ts|html|css', async () => { - const tree = await runner.runSchematic('sidemenu', componentOptions, appTree); + describe('fileNameStyleGuide 2016 (classic suffixes):', () => { + it('should create the app files with the `.component` suffix while preserving the bootstrapped class', async () => { + const options = { ...sidemenuOptions, fileNameStyleGuide: '2016' }; + const tree = await runner.runSchematic('sidemenu', options, appTree); + + const appDir = `/projects/${sidemenuOptions.project}/src/app`; - const files: Array = tree.files; + expect(tree.files).toContain(`${appDir}/app.component.ts`); + expect(tree.files).toContain(`${appDir}/app.component.html`); + expect(tree.files).toContain(`${appDir}/app.component.${sidemenuOptions.style}`); + // The option only controls the file-name suffix. The class name still follows the + // component bootstrapped by the base app (the CLI's standalone `App`) so the + // overwritten component keeps matching the existing import. + expect(getFileContent(tree, `${appDir}/app.component.ts`)).toContain('export class App {'); + }); + }); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/app.component.ts`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/app.component.html`); - expect(files).toContain(`/projects/${componentOptions.name}/src/app/app.component.${componentOptions.style}`); + describe('auto-detected style on a project using the classic (2016) convention:', () => { + beforeEach(() => { + appTree.overwrite( + '/projects/po/src/main.ts', + `import { bootstrapApplication } from '@angular/platform-browser';\n` + + `import { App } from './app/app.component';\n` + + `import { appConfig } from './app/app.config';\n` + + `bootstrapApplication(App, appConfig);\n` + ); + appTree.create( + '/projects/po/src/app/app.component.ts', + `import { Component } from '@angular/core';\n@Component({ selector: 'app-root', template: '' })\nexport class App {}\n` + ); }); - it('should contains `po-wrapper`, `po-toolbar` and `po-menu` in app.component.html', async () => { - const poWrapper = '
    '; - const poToolbar = 'po-toolbar'; - const poMenu = ''; + it('should generate the app files with the classic `.component` suffix without passing the option', async () => { + const tree = await runner.runSchematic('sidemenu', sidemenuOptions, appTree); - const htmlComponent = `projects/${componentOptions.name}/src/app/app.component.html`; + expect(tree.files).toContain(`/projects/${sidemenuOptions.project}/src/app/app.component.ts`); + }); + }); + + describe('auto-detected style on an NgModule project with a chained bootstrapModule call:', () => { + beforeEach(() => { + // Mirrors the CLI v22 NgModule main.ts, where the bootstrap call is chained off + // `platformBrowser()` (a property-access callee) rather than a bare identifier. + appTree.overwrite( + '/projects/po/src/main.ts', + `import { platformBrowser } from '@angular/platform-browser';\n` + + `import { AppModule } from './app/app.module';\n` + + `platformBrowser().bootstrapModule(AppModule).catch(err => console.error(err));\n` + ); + appTree.create( + '/projects/po/src/app/app.component.ts', + `import { Component } from '@angular/core';\n@Component({ selector: 'app-root', template: '' })\nexport class App {}\n` + ); + appTree.create( + '/projects/po/src/app/app.module.ts', + `import { NgModule } from '@angular/core';\n` + + `import { BrowserModule } from '@angular/platform-browser';\n` + + `import { App } from './app.component';\n` + + `@NgModule({\n` + + ` declarations: [App],\n` + + ` imports: [BrowserModule],\n` + + ` bootstrap: [App]\n` + + `})\n` + + `export class AppModule {}\n` + ); + }); + + it('should overwrite the existing `.component` file with the PO layout', async () => { + const appDir = `/projects/${sidemenuOptions.project}/src/app`; + const originalComponent = getFileContent(appTree, `${appDir}/app.component.ts`); + + const tree = await runner.runSchematic('sidemenu', sidemenuOptions, appTree); + + const generatedComponent = getFileContent(tree, `${appDir}/app.component.ts`); + + // The chained `bootstrapModule(AppModule)` import resolves to `./app/app.module` + // (a `.module` suffix), so the classic 2016 style must be detected and the PO layout + // written to the existing `app.component.ts` (suffix `.component`), not to a new + // suffix-less `app.ts`. + expect(generatedComponent).not.toEqual(originalComponent); + expect(generatedComponent).toContain('PoMenuItem'); + expect(generatedComponent).toContain(`templateUrl: './app.component.html'`); + // The class name is read from the module's `bootstrap: [App]`, not from the + // bootstrapped module symbol (`AppModule`), so it stays `App` and keeps matching + // the module's `declarations`/`bootstrap` references. + expect(generatedComponent).toContain('export class App {'); + expect(generatedComponent).not.toContain('export class AppModule'); + }); + }); + + describe('auto-detected class name on an NgModule project bootstrapping `AppComponent`:', () => { + beforeEach(() => { + appTree.overwrite( + '/projects/po/src/main.ts', + `import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\n` + + `import { AppModule } from './app/app.module';\n` + + `platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));\n` + ); + appTree.create( + '/projects/po/src/app/app.component.ts', + `import { Component } from '@angular/core';\n@Component({ selector: 'app-root', template: '' })\nexport class AppComponent {}\n` + ); + appTree.create( + '/projects/po/src/app/app.module.ts', + `import { NgModule } from '@angular/core';\n` + + `import { BrowserModule } from '@angular/platform-browser';\n` + + `import { AppComponent } from './app.component';\n` + + `@NgModule({\n` + + ` declarations: [AppComponent],\n` + + ` imports: [BrowserModule],\n` + + ` bootstrap: [AppComponent]\n` + + `})\n` + + `export class AppModule {}\n` + ); + }); - const tree = await runner.runSchematic('sidemenu', componentOptions, appTree); + it('should preserve the `AppComponent` class name read from the module bootstrap array', async () => { + const tree = await runner.runSchematic('sidemenu', sidemenuOptions, appTree); - const fileContent = getFileContent(tree, htmlComponent); + const content = getFileContent(tree, `/projects/${sidemenuOptions.project}/src/app/app.component.ts`); - expect(fileContent).toContain(poWrapper); - expect(fileContent).toContain(poToolbar); - expect(fileContent).toContain(poMenu); + expect(content).toContain('export class AppComponent {'); }); }); }); diff --git a/projects/ui/schematics/ng-generate/sidemenu/index.ts b/projects/ui/schematics/ng-generate/sidemenu/index.ts index bd90e54b7f..7d31967c87 100644 --- a/projects/ui/schematics/ng-generate/sidemenu/index.ts +++ b/projects/ui/schematics/ng-generate/sidemenu/index.ts @@ -24,7 +24,13 @@ import { getProjectMainFile, getWorkspaceConfigGracefully } from '@po-ui/ng-schematics/project'; -import { supportedCssExtensions } from '@po-ui/ng-schematics/utils'; +import { + detectFileNameStyleGuide, + detectRootComponentClassName, + FileNameStyleGuide, + getFileNameSuffixes, + supportedCssExtensions +} from '@po-ui/ng-schematics/utils'; import { WorkspaceSchema } from '@schematics/angular/utility/workspace-models'; import { Schema as ComponentOptions } from './schema'; @@ -54,12 +60,26 @@ function createAppComponent(options: ComponentOptions): Rule { options.style = 'css'; } + // Use the explicit option when provided, otherwise auto-detect the style already used by the project. + const styleGuide: FileNameStyleGuide = + options.fileNameStyleGuide ?? detectFileNameStyleGuide(tree, browserEntryPoint); + const { componentSuffix } = getFileNameSuffixes(styleGuide); + const appFileName = `app${componentSuffix}`; + + // Preserve the root component class name already used by the project (e.g. `App` or + // `AppComponent`) so the overwritten component keeps matching the existing imports in + // main.ts / app.module.ts. Fall back to the style guide convention when undetectable. + const appClassName = + detectRootComponentClassName(tree, browserEntryPoint) ?? (styleGuide === '2016' ? 'AppComponent' : 'App'); + + const templateOptions = { ...options, appFileName, appClassName }; + const templateSource = applyWithOverwrite(url(urlFile), [ options.skipTests ? filter(path => !path.endsWith('.spec.ts.template')) : noop(), - pathTemplate({ ...options }), + pathTemplate({ ...templateOptions }), applyTemplates({ ...strings, - ...options + ...templateOptions }), move(normalize(sourceDir)) ]); diff --git a/projects/ui/schematics/ng-generate/sidemenu/schema.json b/projects/ui/schematics/ng-generate/sidemenu/schema.json index 82f5466580..997c2eca36 100644 --- a/projects/ui/schematics/ng-generate/sidemenu/schema.json +++ b/projects/ui/schematics/ng-generate/sidemenu/schema.json @@ -26,6 +26,11 @@ "description": "When true, does not create \"spec.ts\" test files for the app.", "type": "boolean", "default": false + }, + "fileNameStyleGuide": { + "type": "string", + "description": "The file naming convention to use for generated files. `2016` uses classic suffixes such as `.component.ts`. `2025` omits type suffixes. When omitted, the convention already used by the project is auto-detected.", + "enum": ["2016", "2025"] } }, "required": [] diff --git a/projects/ui/schematics/ng-generate/sidemenu/schema.ts b/projects/ui/schematics/ng-generate/sidemenu/schema.ts index a3c1af796c..45ef06e566 100644 --- a/projects/ui/schematics/ng-generate/sidemenu/schema.ts +++ b/projects/ui/schematics/ng-generate/sidemenu/schema.ts @@ -13,4 +13,14 @@ export interface Schema { /** When true, does not create \"spec.ts\" test files for the app. */ skipTests?: boolean; + + /** + * The file naming convention to use for generated files. + * + * - `2016`: classic Angular Style Guide suffixes (e.g. `app.component.ts`). + * - `2025`: current Angular convention without type suffixes (e.g. `app.ts`). + * + * When omitted, the convention already used by the project is auto-detected. + */ + fileNameStyleGuide?: '2016' | '2025'; } diff --git a/projects/ui/schematics/ng-update/v18/index.ts b/projects/ui/schematics/ng-update/v18/index.ts index 7b05608e9b..50aeb8152d 100644 --- a/projects/ui/schematics/ng-update/v18/index.ts +++ b/projects/ui/schematics/ng-update/v18/index.ts @@ -134,7 +134,7 @@ export function addProviderToModuleProvider( ) { const moduleSource = getSourceFile(tree, modulePath); const changes = addProviderToModule( - moduleSource as any, + moduleSource, modulePath, ` ${provider}`, diff --git a/projects/ui/schematics/ng-update/v19/index.ts b/projects/ui/schematics/ng-update/v19/index.ts index fb2e3e82c9..8d5cae970c 100644 --- a/projects/ui/schematics/ng-update/v19/index.ts +++ b/projects/ui/schematics/ng-update/v19/index.ts @@ -136,7 +136,7 @@ export function addProviderToModuleProvider( ) { const moduleSource = getSourceFile(tree, modulePath); const changes = addProviderToModule( - moduleSource as any, + moduleSource, modulePath, ` ${provider}`, diff --git a/projects/ui/schematics/ng-update/v20/index.ts b/projects/ui/schematics/ng-update/v20/index.ts index fb2e3e82c9..8d5cae970c 100644 --- a/projects/ui/schematics/ng-update/v20/index.ts +++ b/projects/ui/schematics/ng-update/v20/index.ts @@ -136,7 +136,7 @@ export function addProviderToModuleProvider( ) { const moduleSource = getSourceFile(tree, modulePath); const changes = addProviderToModule( - moduleSource as any, + moduleSource, modulePath, ` ${provider}`, diff --git a/projects/ui/schematics/ng-update/v22/changes.ts b/projects/ui/schematics/ng-update/v22/changes.ts new file mode 100644 index 0000000000..4eda192a61 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/changes.ts @@ -0,0 +1,59 @@ +import { UpdateDependencies } from '@po-ui/ng-schematics/package-config'; + +export const updateDepedenciesVersion: UpdateDependencies = { + dependencies: [ + '@po-ui/ng-components', + '@po-ui/ng-code-editor', + '@po-ui/ng-templates', + '@po-ui/ng-storage', + '@po-ui/ng-sync', + '@po-ui/style' + ] +}; + +/** Pacote de origem/destino dos símbolos migrados do gauge. */ +export const PO_UI_PACKAGE = '@po-ui/ng-components'; + +/** Símbolos gauge com equivalente direto no po-chart. */ +export const gaugeSymbolMap: Record = { + PoGaugeModule: 'PoChartModule', + PoGaugeComponent: 'PoChartComponent', + PoGaugeRanges: 'PoChartSerie', + PoGaugeOptions: 'PoChartOptions' +}; + +/** Símbolos gauge SEM equivalente -> exigem revisão manual (Req 4.4). */ +export const gaugeSymbolsWithoutEquivalent: ReadonlyArray = ['PoGaugeCoordinates', 'PoGaugeSvgContainer']; + +/** Destino de uma propriedade do po-gauge na configuração do po-chart. */ +export type PropertyTarget = 'p-series' | 'p-options' | 'passthrough' | 'unmapped'; + +/** Regra de mapeamento de uma propriedade do po-gauge para o po-chart. */ +export interface GaugePropertyRule { + /** Nome da propriedade do po-gauge (ex.: 'p-value', 'p-ranges'). */ + gaugeProp: string; + /** Destino da propriedade na configuração do po-chart. */ + target: PropertyTarget; + /** Chave em p-options quando target = 'p-options'. */ + optionsKey?: string; +} + +/** + * Tabela de Mapeamento das propriedades do po-gauge para o po-chart + * (conforme comportamento real do componente po-gauge da v21). + * + * Referência: po-gauge.component.html passa `[p-title]` e `[p-height]` + * diretamente como inputs do po-chart. `p-show-pointer` é consumido via + * `p-options.pointer`. `p-value` com `p-ranges` vai para + * `p-value-gauge-multiple`. + */ +export const gaugePropertyRules: ReadonlyArray = [ + { gaugeProp: 'p-value', target: 'p-series' }, + { gaugeProp: 'p-ranges', target: 'p-series' }, + { gaugeProp: 'p-description', target: 'p-options', optionsKey: 'descriptionChart' }, + { gaugeProp: 'p-title', target: 'passthrough' }, + { gaugeProp: 'p-height', target: 'passthrough' }, + { gaugeProp: 'p-show-from-to-legend', target: 'p-options', optionsKey: 'showFromToLegend' }, + { gaugeProp: 'p-show-pointer', target: 'p-options', optionsKey: 'pointer' }, + { gaugeProp: 'p-options', target: 'p-options' } +]; diff --git a/projects/ui/schematics/ng-update/v22/gauge-html-migration.spec.ts b/projects/ui/schematics/ng-update/v22/gauge-html-migration.spec.ts new file mode 100644 index 0000000000..dfdb7a6a46 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/gauge-html-migration.spec.ts @@ -0,0 +1,759 @@ +import * as fc from 'fast-check'; + +import { migrateHtmlContent } from './gauge-html-migration'; + +/** Marcador estável dos comentários TODO inseridos pela migração (idempotência). */ +const TODO_MARKER = 'TODO: migração po-gauge'; + +/** Conta ocorrências não sobrepostas de um trecho literal em um texto. */ +function countOccurrences(haystack: string, needle: string): number { + if (needle.length === 0) { + return 0; + } + + let count = 0; + let index = haystack.indexOf(needle); + while (index !== -1) { + count++; + index = haystack.indexOf(needle, index + needle.length); + } + + return count; +} + +/** + * Expressão de binding simples e determinística (sem espaços nas bordas nem + * caracteres que quebrem a varredura textual de atributos). + */ +const bindingExpressionArb = fc.oneof( + fc.integer({ min: 0, max: 1000 }).map(String), + fc.constantFrom('valor', 'ranges', 'options', 'this.total', 'getValor()', 'true', 'false') +); + +/** Texto estático simples para atributos sem binding (ex.: `p-description="..."`). */ +const staticTextArb = fc.stringMatching(/^[a-zA-Z0-9 ]{0,12}$/); + +/** + * Gera um atributo mapeado do po-gauge. Cobre os bindings mais relevantes: + * `[p-value]`, `[p-ranges]`, `[p-show-from-to-legend]`, `[p-show-pointer]`, + * `[p-options]`, o atributo estático `p-description`, e os passthrough + * `p-title` e `p-height` (que são reconhecidos pela migração). + */ +const mappedAttrArb: fc.Arbitrary = fc.oneof( + bindingExpressionArb.map(expr => `[p-value]="${expr}"`), + bindingExpressionArb.map(expr => `[p-ranges]="${expr}"`), + fc.constantFrom('true', 'false', 'showLegend').map(expr => `[p-show-from-to-legend]="${expr}"`), + fc.constantFrom('true', 'false').map(expr => `[p-show-pointer]="${expr}"`), + staticTextArb.map(text => `p-description="${text}"`), + staticTextArb.map(text => `p-title="${text}"`), + bindingExpressionArb.map(expr => `[p-height]="${expr}"`), + fc.constantFrom('{ showFromToLegend: true }', 'options', '{ pointer: false }').map(expr => `[p-options]="${expr}"`) +); + +/** + * Atributos "passthrough" (fora do Mapeamento_Propriedades) que devem ser + * preservados: classe, id, eventos e template refs. + */ +const passthroughAttrArb: fc.Arbitrary = fc.oneof( + staticTextArb.map(cls => `class="${cls}"`), + fc.stringMatching(/^[a-z][a-z0-9-]{0,8}$/).map(id => `id="${id}"`), + fc.constantFrom('onClick()', 'handle($event)', 'doThing()').map(handler => `(click)="${handler}"`), + fc.stringMatching(/^[a-z][a-z0-9]{0,6}$/).map(name => `#${name}`) +); + +/** + * Propriedade `p-*` sem equivalente na Tabela de Mapeamento: dispara o caminho + * de preservação + comentário TODO (Caso_Nao_Migravel). + */ +const unmappedAttrArb: fc.Arbitrary = fc + .constantFrom('p-foo', 'p-bar', 'p-unknown', 'p-custom') + .chain(name => staticTextArb.map(value => `${name}="${value}"`)); + +/** Um atributo qualquer, com maior peso para os mapeados/passthrough. */ +const anyAttrArb: fc.Arbitrary = fc.oneof( + { weight: 5, arbitrary: mappedAttrArb }, + { weight: 3, arbitrary: passthroughAttrArb }, + { weight: 1, arbitrary: unmappedAttrArb } +); + +/** Whitespace de separação entre atributos (espaço, múltiplos espaços ou quebra). */ +const separatorArb = fc.constantFrom(' ', ' ', '\n ', '\n ', '\t'); + +/** Gera um elemento `` completo (auto-fechado ou com fechamento). */ +const poGaugeElementArb: fc.Arbitrary = fc + .tuple(fc.array(anyAttrArb, { minLength: 0, maxLength: 5 }), separatorArb, fc.boolean()) + .map(([attrs, sep, selfClosing]) => { + const attrsText = attrs.map(attr => `${sep}${attr}`).join(''); + return selfClosing ? `` : ``; + }); + +/** Trecho de marcação arbitrária ao redor dos elementos po-gauge. */ +const surroundingMarkupArb: fc.Arbitrary = fc.oneof( + fc.constant(''), + fc.constant('\n'), + fc.constant('
    '), + fc.constant('
    '), + fc.constant('

    texto

    '), + fc.constant(''), + fc.constant(''), + staticTextArb.map(text => `${text}`) +); + +/** + * Documento HTML arbitrário contendo de 1 a 4 elementos po-gauge intercalados + * com marcação arbitrária ao redor. + */ +const htmlWithGaugeArb: fc.Arbitrary = fc + .array(fc.tuple(surroundingMarkupArb, poGaugeElementArb), { minLength: 1, maxLength: 4 }) + .chain(pairs => + surroundingMarkupArb.map(tail => pairs.map(([markup, gauge]) => `${markup}${gauge}`).join('\n') + '\n' + tail) + ); + +/** HTML arbitrário SEM qualquer po-gauge (para confirmar idempotência trivial). */ +const htmlWithoutGaugeArb: fc.Arbitrary = fc + .array(surroundingMarkupArb, { minLength: 0, maxLength: 8 }) + .map(parts => parts.join('\n')); + +describe('v22 gauge-html-migration (property-based):', () => { + /** + * Propriedade 1 — Idempotência (ponto fixo). + * + * Para qualquer HTML de origem (incluindo fontes com `` com combinações + * variadas de atributos/bindings), aplicar `migrateHtmlContent` duas vezes produz + * o mesmo conteúdo que aplicá-la uma vez: + * `migrateHtmlContent(migrateHtmlContent(x).content).content === migrateHtmlContent(x).content` + * Além disso, não há duplicação de comentários TODO na segunda execução. + * + * **Validates: Requirements 7.2, 7.4** + * **Valida: Requisitos 7.2, 7.4** + */ + it('should reach a fixed point on HTML containing po-gauge elements without duplicating TODO markers (Prop 1, Req 7.2, 7.4)', () => { + fc.assert( + fc.property(htmlWithGaugeArb, source => { + const once = migrateHtmlContent(source).content; + const twice = migrateHtmlContent(once).content; + + // Ponto fixo: a segunda aplicação não altera o conteúdo já migrado. + expect(twice).toBe(once); + + // Sem duplicação de marcadores TODO entre a primeira e a segunda execução. + expect(countOccurrences(twice, TODO_MARKER)).toBe(countOccurrences(once, TODO_MARKER)); + }), + { numRuns: 500 } + ); + }); + + it('should be idempotent on arbitrary HTML without any po-gauge element (Prop 1, Req 7.2, 7.4)', () => { + fc.assert( + fc.property(htmlWithoutGaugeArb, source => { + const once = migrateHtmlContent(source).content; + const twice = migrateHtmlContent(once).content; + + expect(twice).toBe(once); + expect(countOccurrences(twice, TODO_MARKER)).toBe(countOccurrences(once, TODO_MARKER)); + }), + { numRuns: 300 } + ); + }); +}); + +/** Seletor de abertura exato reconhecido pela migração (case-sensitive, Req. 2.1). */ +const OPEN_TAG = '`). */ +function isTagBoundary(char: string): boolean { + return ( + char === ' ' || + char === '\t' || + char === '\n' || + char === '\r' || + char === '\f' || + char === '\v' || + char === '/' || + char === '>' + ); +} + +/** + * Replica exatamente a detecção de correspondência da implementação: existe uma + * ocorrência de ``). Near-misses como + * ``, ``). O caractere + * seguinte a ` = fc + .stringMatching(/^[a-z][a-z0-9-]{0,8}$/) + .map(suffix => `conteúdo`); + +/** + * `po-gauge` aparecendo apenas como texto/atributo/comentário/nome de outro + * elemento — nunca como o token de abertura ` = fc.constantFrom( + 'o po-gauge foi descontinuado', + '', + '', + 'legado', + '', + '', + '', + 'class="po-gauge-legacy"' +); + +/** Marcação genérica que comprovadamente não contém o token ` = fc.oneof( + fc.constant(''), + fc.constant('\n'), + fc.constant(' '), + fc.constant('
    '), + fc.constant('
    '), + fc.constant('

    texto

    '), + fc.constant(''), + fc.stringMatching(/^[a-zA-Z0-9 .,;:!?_-]{0,24}$/), + fc.stringMatching(/^<[a-z][a-z0-9]{0,8}>[a-zA-Z0-9 ]{0,10}<\/[a-z][a-z0-9]{0,8}>$/) +); + +/** + * Documento HTML arbitrário que NÃO contém nenhuma ocorrência do seletor de + * abertura ``) e `po-gauge` como texto puro. Uma pré-condição + * (`fc.pre`) descarta qualquer combinação acidental que forme uma correspondência, + * garantindo o espaço de entrada exato de "sem Uso_Template". + */ +const htmlWithoutGaugeOccurrenceArb: fc.Arbitrary = fc + .array( + fc.oneof( + { weight: 4, arbitrary: safeMarkupArb }, + { weight: 2, arbitrary: nearMissTagArb }, + { weight: 2, arbitrary: poGaugeAsTextArb } + ), + { + minLength: 0, + maxLength: 12 + } + ) + .map(parts => parts.join('')); + +describe('v22 gauge-html-migration — no-op sem ocorrência (property-based):', () => { + /** + * Propriedade 2 — No-op sem ocorrência. + * + * Para qualquer HTML de origem que NÃO contenha nenhum Uso_Template (``) e `po-gauge` como texto/comentário/atributo. + * + * **Validates: Requirements 7.1** + * **Valida: Requisito 7.1** + */ + it('should leave HTML byte-for-byte unchanged when there is no po-gauge occurrence (Prop 2, Req 7.1)', () => { + fc.assert( + fc.property(htmlWithoutGaugeOccurrenceArb, source => { + // Garante o espaço de entrada: nenhuma correspondência real de po-gauge. + fc.pre(!hasPoGaugeMatch(source)); + + const result = migrateHtmlContent(source); + + expect(result.content).toBe(source); + expect(result.changed).toBe(false); + expect(result.warnings).toEqual([]); + }), + { numRuns: 500 } + ); + }); +}); + +/** + * Atributo mapeável do po-gauge (garante que o elemento seja migrado para + * po-chart). Restringe-se a propriedades presentes na Tabela de Mapeamento + * que efetivamente geram p-series ou p-options, evitando o caminho de `unmapped`. + */ +const mappableAttrArb: fc.Arbitrary = fc.oneof( + bindingExpressionArb.map(expr => `[p-value]="${expr}"`), + bindingExpressionArb.map(expr => `[p-ranges]="${expr}"`), + staticTextArb.map(text => `p-description="${text}"`), + fc.constantFrom('true', 'false').map(expr => `[p-show-pointer]="${expr}"`) +); + +/** + * Atributos/bindings "passthrough" (fora do Mapeamento_Propriedades) que devem + * ser preservados verbatim no elemento migrado. Nenhum começa com `p-`, de modo + * a não colidir com as propriedades mapeadas nem cair no caminho `unmapped`. + * Cobre `class`, `id`, eventos `(click)`, estruturais `*ngIf`, `[ngClass]` e + * template refs `#x`. + */ +const passthroughAttrProp4Arb: fc.Arbitrary = fc.oneof( + fc.stringMatching(/^[a-z][a-z0-9-]{0,8}$/).map(cls => `class="${cls}"`), + fc.stringMatching(/^[a-z][a-z0-9-]{0,8}$/).map(id => `id="${id}"`), + fc.constantFrom('onClick()', 'handle($event)', 'doThing()').map(handler => `(click)="${handler}"`), + fc.constantFrom('cond', 'isActive', 'show && ready').map(cond => `*ngIf="${cond}"`), + fc.constantFrom('{ active: isActive }', 'classExpr', "{ 'is-open': open }").map(expr => `[ngClass]="${expr}"`), + fc.stringMatching(/^[a-z][a-z0-9]{0,6}$/).map(name => `#${name}`) +); + +/** + * Gera um `` com exatamente um atributo mapeável (para garantir a + * migração) e um conjunto de atributos passthrough, inseridos em ordem + * arbitrária. Também varia a separação entre atributos e o auto-fechamento. + * Retorna o elemento e a lista de atributos passthrough esperados na saída. + */ +const gaugeWithPassthroughArb: fc.Arbitrary<{ element: string; passthrough: Array }> = fc + .tuple( + mappableAttrArb, + fc.array(passthroughAttrProp4Arb, { minLength: 1, maxLength: 5 }), + fc.nat(), + separatorArb, + fc.boolean() + ) + .map(([mappable, passthrough, pos, sep, selfClosing]) => { + const attrs = [...passthrough]; + const insertAt = pos % (attrs.length + 1); + attrs.splice(insertAt, 0, mappable); + const attrsText = attrs.map(attr => `${sep}${attr}`).join(''); + const element = selfClosing ? `` : ``; + return { element, passthrough }; + }); + +describe('v22 gauge-html-migration — preservação de atributos não mapeados (property-based):', () => { + /** + * Propriedade 4 — Preservação de atributos não mapeados (HTML). + * + * Para qualquer `` contendo ao menos uma propriedade mapeável (que o + * faz migrar para `po-chart`) mais um conjunto de atributos/bindings fora do + * Mapeamento_Propriedades (`class`, `id`, `(click)`, `*ngIf`, `[ngClass]`, + * template refs `#x`), após `migrateHtmlContent`: + * - o elemento passa a ser `po-chart` com `[p-type]="'gauge'"`; + * - cada atributo passthrough (nome e valor) é preservado verbatim na saída; + * - não resta nenhum seletor de abertura ` { + fc.assert( + fc.property(gaugeWithPassthroughArb, ({ element, passthrough }) => { + const { content } = migrateHtmlContent(element); + + // O elemento foi migrado para po-chart com [p-type]="$any('gauge')". + expect(content).toContain(' { + expect(content).toContain(attr); + }); + }), + { numRuns: 500 } + ); + }); +}); + +/** + * Divide o conteúdo em linhas (independente do separador \n) para inspecionar a + * posição relativa do comentário TODO em relação ao trecho preservado. + */ +function splitLines(content: string): Array { + return content.split('\n'); +} + +describe('v22 gauge-html-migration — casos malformados, TODO e exemplo canônico (unit):', () => { + describe('trecho malformado preservado + advertência (Req 2.7, 6.1, 6.3):', () => { + it('should preserve a without a closing tag and record a warning (Req 2.7, 6.1)', () => { + const source = ['
    ', ' ', '
    '].join('\n'); + + const result = migrateHtmlContent(source); + + // O trecho original é preservado sem alteração de conteúdo. + expect(result.content).toContain(''); + + // Uma advertência é registrada, com arquivo (preenchido pela orquestração), + // linha e motivo identificando a ausência do fechamento. + expect(result.warnings.length).toBe(1); + expect(result.warnings[0].filePath).toBe(''); + expect(typeof result.warnings[0].line).toBe('number'); + expect(result.warnings[0].line).toBe(2); + expect(result.warnings[0].reason).toContain('sem tag de fechamento'); + + // Um comentário TODO foi inserido (Req 6.3), portanto houve marcação. + expect(result.changed).toBe(true); + expect(result.content).toContain(TODO_MARKER); + }); + + it('should preserve a with a malformed opening tag (unclosed quote) and record a warning (Req 2.7, 6.1)', () => { + // Aspas não fechadas no valor do atributo: a tag de abertura não pode ser + // interpretada com segurança. + const source = ['
    ', ' '); + + expect(result.warnings.length).toBe(1); + expect(result.warnings[0].filePath).toBe(''); + expect(result.warnings[0].line).toBe(2); + expect(result.warnings[0].reason).toContain('malformado'); + + expect(result.content).toContain(TODO_MARKER); + }); + + it('should not migrate the malformed element to po-chart (Req 2.7)', () => { + const source = ''; + + const result = migrateHtmlContent(source); + + // Nenhuma reescrita para po-chart quando o trecho não é migrável. + expect(result.content).not.toContain(''); + expect(result.warnings.length).toBe(1); + }); + }); + + describe('inserção de TODO para propriedade sem equivalente (Req 3.10, 6.1, 6.3):', () => { + it('should preserve the element and insert a TODO on the line immediately before it (Req 6.3)', () => { + const source = ['
    ', ' ', '
    '].join('\n'); + + const result = migrateHtmlContent(source); + + // Trecho original preservado sem alteração (Req 3.10). + expect(result.content).toContain(''); + expect(result.content).not.toContain(' line.includes(' { + const source = ' '; + + const result = migrateHtmlContent(source); + + expect(countOccurrences(result.content, TODO_MARKER)).toBe(1); + expect(result.warnings.length).toBe(1); + expect(result.warnings[0].reason).toContain('p-unknown'); + }); + }); + + describe('exemplo canônico da transformação (design.md):', () => { + it(`should transform the canonical into with p-series, p-value-gauge-multiple and p-options`, () => { + const source = [ + '', + '' + ].join('\n'); + + const result = migrateHtmlContent(source); + + // Elemento migrado para po-chart com [p-type]="$any('gauge')". + expect(result.content).toContain(''); + expect(result.content).not.toContain(' with only p-value (no ranges) into [p-series]="[{ data: }]"', () => { + const source = ''; + + const result = migrateHtmlContent(source); + + expect(result.content).toContain(' { + const source = ''; + + const result = migrateHtmlContent(source); + + expect(result.content).toContain(' { + const source = ''; + + const result = migrateHtmlContent(source); + + expect(result.content).toContain(' { + it('should generate conditional fallback when p-ranges is a variable (case 9b/27b)', () => { + const source = + ''; + + const result = migrateHtmlContent(source); + + expect(result.content).toContain( + '[p-series]="item.ranges && item.ranges.length ? item.ranges : [{ data: item.value }]"' + ); + expect(result.content).toContain( + '[p-value-gauge-multiple]="item.ranges && item.ranges.length ? item.value : undefined"' + ); + expect(result.content).toContain('descriptionChart: item.description'); + expect(result.changed).toBe(true); + expect(result.warnings).toEqual([]); + }); + + it('should generate conditional fallback for empty array variable (case 28)', () => { + const source = ''; + + const result = migrateHtmlContent(source); + + expect(result.content).toContain('[p-series]="emptyRanges && emptyRanges.length ? emptyRanges : [{ data: 50 }]"'); + expect(result.content).toContain('[p-value-gauge-multiple]="emptyRanges && emptyRanges.length ? 50 : undefined"'); + expect(result.content).toContain('p-title="Empty"'); + }); + + it('should NOT generate conditional fallback for non-empty array literal (case 36)', () => { + const source = ``; + + const result = migrateHtmlContent(source); + + // Array literal com conteúdo: direto, sem ternário + expect(result.content).toContain('[p-series]="[{ from: 0, to: 50 }, { from: 50, to: 100 }]"'); + expect(result.content).toContain('[p-value-gauge-multiple]="60"'); + expect(result.content).not.toContain('&& '); + }); + }); + + describe('prioridade de p-description sobre p-options.descriptionChart (cases 16b, 40):', () => { + it('should let p-description win over descriptionChart in p-options literal (case 16b)', () => { + const source = [ + '`, + '
    ' + ].join('\n'); + + const result = migrateHtmlContent(source); + + expect(result.content).toContain("descriptionChart: 'Desc pela propriedade'"); + expect(result.content).not.toContain('Desc pelo options'); + expect(result.changed).toBe(true); + }); + + it('should let p-description win over opaque p-options variable (case 40)', () => { + const source = + ''; + + const result = migrateHtmlContent(source); + + // descriptionChart aparece DEPOIS do spread para prevalecer + expect(result.content).toContain('...fullOptions, descriptionChart: descricao'); + expect(result.changed).toBe(true); + }); + }); + + describe('gauge sem propriedades (case 21):', () => { + it('should migrate an empty with default series and options', () => { + const source = ''; + + const result = migrateHtmlContent(source); + + expect(result.content).toContain(' { + it('should preserve inner content between po-gauge opening and closing tags', () => { + const source = ' '; + + const result = migrateHtmlContent(source); + + expect(result.content).toContain(''); + // Inner whitespace content is preserved + expect(result.content).toMatch(/>[ ]<\/po-chart>/); + expect(result.changed).toBe(true); + }); + }); + + describe('pipes em bindings (cases 19, 19b, 20):', () => { + it('should preserve pipe expressions in p-value bindings (case 19b)', () => { + const source = ''; + + const result = migrateHtmlContent(source); + + expect(result.content).toContain('[p-series]="[{ data: score }]"'); + expect(result.content).toContain('descriptionChart: descricao | uppercase'); + expect(result.changed).toBe(true); + }); + + it('should preserve $any() and async pipe in bindings (case 20)', () => { + const source = + ''; + + const result = migrateHtmlContent(source); + + expect(result.content).toContain(' { + it('should preserve style, [style.x], data-*, [attr.*], [hidden], tabindex, role, [class.x] attributes', () => { + const source = [ + '', + '
    ' + ].join('\n'); + + const result = migrateHtmlContent(source); + + expect(result.content).toContain(' { + it('should migrate po-gauge inside @if block', () => { + const source = '@if (showGauge) {\n \n}'; + + const result = migrateHtmlContent(source); + + expect(result.content).toContain('@if (showGauge)'); + expect(result.content).toContain(' { + const source = [ + '@for (item of gaugeItems; track item.title) {', + ' ', + '}' + ].join('\n'); + + const result = migrateHtmlContent(source); + + expect(result.content).toContain('@for (item of gaugeItems; track item.title)'); + expect(result.content).toContain(' { + it('should spread opaque p-options with individual showFromToLegend and pointer', () => { + const source = + ''; + + const result = migrateHtmlContent(source); + + expect(result.content).toContain('showFromToLegend: true'); + expect(result.content).toContain('pointer: false'); + expect(result.content).toContain('...optionsWithHeader'); + expect(result.changed).toBe(true); + }); + }); +}); diff --git a/projects/ui/schematics/ng-update/v22/gauge-html-migration.ts b/projects/ui/schematics/ng-update/v22/gauge-html-migration.ts new file mode 100644 index 0000000000..bfa614f1e0 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/gauge-html-migration.ts @@ -0,0 +1,402 @@ +import { GaugeAttribute, mapGaugeProperties, MappedChartAttributes } from './gauge-property-map'; +import { MigrationWarning } from './migration-report'; + +/** + * Resultado da transformação de um arquivo de template HTML pela + * Schematic_Migracao. + * + * A função `migrateHtmlContent` é pura (string → string): recebe o conteúdo + * original e devolve o conteúdo transformado, um indicador de alteração e a + * lista de Casos_Nao_Migravel encontrados. O `filePath` das advertências é + * preenchido pela camada de orquestração da schematic (que conhece o caminho). + */ +export interface HtmlMigrationResult { + /** Conteúdo do template após a transformação (idêntico ao original se nada mudou). */ + content: string; + /** `true` somente quando alguma transformação/marcação foi efetivamente aplicada. */ + changed: boolean; + /** Casos_Nao_Migravel identificados (trecho malformado ou propriedade sem equivalente). */ + warnings: Array; +} + +/** Seletor de abertura do po-gauge (correspondência exata e case-sensitive, Req. 2.1). */ +const OPEN_TAG = '`. */ +interface OpeningTag { + attrs: Array; + /** Whitespace entre o último atributo e o `>`/`/>`. */ + trailingWs: string; + /** `true` quando a tag é auto-fechada (`/>`). */ + selfClosing: boolean; + /** Índice do caractere imediatamente após `>` ou `/>`. */ + tagEndIndex: number; +} + +/** Descreve um Caso_Nao_Migravel a preservar, com o trecho original e o motivo. */ +interface PreservedSnippet { + snippet: string; + reason: string; + line: number; +} + +/** + * Transforma usos de `` em `` em um template + * HTML, mapeando as propriedades públicas conforme a Tabela de Mapeamento. + * + * Comportamento (Req. 2.1–2.3, 2.5–2.7, 3.10, 6.1, 6.3): + * - Localiza cada elemento `po-gauge` (abertura/fechamento exatos e sensíveis a + * maiúsculas) e o reescreve para `po-chart`, injetando `p-type="gauge"` e os + * atributos gerados (`[p-series]`/`[p-options]`), preservando os atributos não + * mapeados e sua ordem original. + * - Elementos já migrados (`po-chart`) nunca são correspondidos, garantindo + * idempotência (Req. 2.6, 7.4). + * - Trechos malformados ou com propriedade sem equivalente são preservados sem + * alteração; um comentário `TODO` é inserido na linha anterior e um + * `MigrationWarning` é registrado (Req. 2.7, 3.10, 6.1, 6.3). O `TODO` não é + * duplicado quando já existe imediatamente antes do trecho (Req. 7.4). + */ +export function migrateHtmlContent(source: string): HtmlMigrationResult { + const warnings: Array = []; + let result = ''; + let index = 0; + let changed = false; + + while (index <= source.length) { + const openIdx = source.indexOf(OPEN_TAG, index); + if (openIdx === -1) { + result += source.slice(index); + break; + } + + const charAfter = source[openIdx + OPEN_TAG.length]; + // Garante correspondência exata do seletor: o caractere seguinte deve ser + // whitespace, `/` ou `>` (evita casar ``, aspas não fechadas, etc.). + if (!openingTag) { + const preserved: PreservedSnippet = { + snippet: OPEN_TAG, + reason: 'Elemento po-gauge malformado (tag de abertura não pôde ser interpretada).', + line + }; + const outcome = appendPreserved(result, preserved, warnings); + result = outcome.result; + changed = outcome.changed || changed; + index = openIdx + OPEN_TAG.length; + continue; + } + + // Caso 2: elemento não auto-fechado sem `` correspondente. + let innerContent = ''; + let elementEnd = openingTag.tagEndIndex; + if (!openingTag.selfClosing) { + const closeIdx = source.indexOf(CLOSE_TAG, openingTag.tagEndIndex); + if (closeIdx === -1) { + const preserved: PreservedSnippet = { + snippet: source.slice(openIdx, openingTag.tagEndIndex), + reason: 'Elemento po-gauge sem tag de fechamento () correspondente.', + line + }; + const outcome = appendPreserved(result, preserved, warnings); + result = outcome.result; + changed = outcome.changed || changed; + index = openingTag.tagEndIndex; + continue; + } + innerContent = source.slice(openingTag.tagEndIndex, closeIdx); + elementEnd = closeIdx + CLOSE_TAG.length; + } + + const gaugeAttrs = toGaugeAttributes(openingTag.attrs); + const mapped = mapGaugeProperties(gaugeAttrs); + + // Caso 3: propriedade sem equivalente na Tabela de Mapeamento (Req. 3.10). + if (mapped.unmapped.length > 0) { + const props = mapped.unmapped.map(attr => attr.name).join(', '); + const preserved: PreservedSnippet = { + snippet: source.slice(openIdx, elementEnd), + reason: `Propriedade(s) do po-gauge sem equivalente no po-chart: ${props}. Migração manual necessária.`, + line + }; + const outcome = appendPreserved(result, preserved, warnings); + result = outcome.result; + changed = outcome.changed || changed; + index = elementEnd; + continue; + } + + // Caso de sucesso: reescreve o elemento para po-chart. + result += buildChartElement(openingTag, mapped, innerContent); + changed = true; + index = elementEnd; + + // Conflito de p-options resolvido em favor de p-options (Req. 3.11): migra e + // apenas registra a advertência, sem preservar/TODO. + if (mapped.conflicts.length > 0) { + warnings.push({ + filePath: '', + line, + reason: + `Conflito de configuração em p-options para: ${mapped.conflicts.join(', ')}. ` + + `Prevaleceu o valor definido em p-options; revise o resultado.` + }); + } + } + + return { content: result, changed, warnings }; +} + +/** + * Anexa ao `result` acumulado um trecho preservado (Caso_Nao_Migravel), + * inserindo um comentário `TODO` na linha imediatamente anterior (sem duplicar) + * e registrando a advertência correspondente. + */ +function appendPreserved( + result: string, + preserved: PreservedSnippet, + warnings: Array +): { result: string; changed: boolean } { + warnings.push({ filePath: '', line: preserved.line, reason: preserved.reason }); + + if (hasTodoImmediatelyBefore(result)) { + // TODO já presente (execução idempotente): apenas preserva o trecho. + return { result: result + preserved.snippet, changed: false }; + } + + const lineStart = result.lastIndexOf('\n') + 1; + const linePrefix = result.slice(lineStart); + const todo = ``; + + if (/^\s*$/.test(linePrefix)) { + // O trecho inicia a linha (após a indentação): TODO na linha anterior com a + // mesma indentação. + const withTodo = result.slice(0, lineStart) + linePrefix + todo + '\n' + linePrefix; + return { result: withTodo + preserved.snippet, changed: true }; + } + + // Há conteúdo antes do trecho na mesma linha: insere o TODO imediatamente + // antes, em nova linha. + return { result: result + todo + '\n' + preserved.snippet, changed: true }; +} + +/** + * Reescreve a tag `po-gauge` para `po-chart`, injetando `p-type="gauge"`, os + * atributos gerados (`[p-series]`/`[p-options]`/`[p-value-gauge-multiple]`) e + * preservando os atributos não mapeados na ordem original. + */ +function buildChartElement(openingTag: OpeningTag, mapped: MappedChartAttributes, innerContent: string): string { + const separator = openingTag.attrs.length > 0 ? openingTag.attrs[0].leadingWs || ' ' : ' '; + const parts: Array = [`${separator}[p-type]="$any('gauge')"`]; + + // Atributos não mapeados preservados na ordem original, com a whitespace + // original de cada um. + mapped.passthrough.forEach(attr => { + const source = (attr as ParsedAttr).source; + parts.push(`${source.leadingWs || ' '}${source.raw}`); + }); + + if (mapped.pSeries !== undefined) { + parts.push(`${separator}[p-series]="${mapped.pSeries}"`); + } + if (mapped.pValueGaugeMultiple !== undefined) { + parts.push(`${separator}[p-value-gauge-multiple]="${mapped.pValueGaugeMultiple}"`); + } + if (mapped.pOptions !== undefined) { + parts.push(`${separator}[p-options]="${mapped.pOptions}"`); + } + + const openTag = `' : '>'}`; + + return openingTag.selfClosing ? openTag : `${openTag}${innerContent}`; +} + +/** + * Varre a tag de abertura `` a partir de `openIdx`, extraindo os + * atributos com a whitespace que os precede e determinando o fim da tag. + * Retorna `null` quando a tag está malformada (sem `>` ou com aspas não + * fechadas), sinalizando um Caso_Nao_Migravel. + */ +function scanOpeningTag(source: string, openIdx: number): OpeningTag | null { + const len = source.length; + const attrs: Array = []; + let i = openIdx + OPEN_TAG.length; + + while (i < len) { + const wsStart = i; + while (i < len && isWhitespace(source[i])) { + i++; + } + const leadingWs = source.slice(wsStart, i); + + if (i >= len) { + return null; + } + + const ch = source[i]; + + if (ch === '>') { + return { attrs, trailingWs: leadingWs, selfClosing: false, tagEndIndex: i + 1 }; + } + if (ch === '/' && source[i + 1] === '>') { + return { attrs, trailingWs: leadingWs, selfClosing: true, tagEndIndex: i + 2 }; + } + if (ch === '/') { + // `/` isolado não seguido de `>`: estrutura não reconhecida. + return null; + } + + const nameStart = i; + while (i < len && !isNameTerminator(source[i])) { + i++; + } + const name = source.slice(nameStart, i); + if (name.length === 0) { + return null; + } + + // Whitespace opcional antes de um eventual `=`. + let j = i; + while (j < len && isWhitespace(source[j])) { + j++; + } + + if (source[j] === '=') { + j++; + while (j < len && isWhitespace(source[j])) { + j++; + } + const quote = source[j]; + if (quote === '"' || quote === "'") { + const valueEnd = source.indexOf(quote, j + 1); + if (valueEnd === -1) { + return null; + } + attrs.push({ leadingWs, name, raw: source.slice(nameStart, valueEnd + 1) }); + i = valueEnd + 1; + } else { + // Valor sem aspas: consome até whitespace ou `>`. + let k = j; + while (k < len && !isWhitespace(source[k]) && source[k] !== '>') { + k++; + } + attrs.push({ leadingWs, name, raw: source.slice(nameStart, k) }); + i = k; + } + } else { + // Atributo booleano (sem valor). + attrs.push({ leadingWs, name, raw: source.slice(nameStart, i) }); + } + } + + return null; +} + +/** + * Converte os atributos brutos em `GaugeAttribute` (enriquecidos com o atributo + * de origem) para consumo por `mapGaugeProperties`. A expressão original é + * preservada textualmente (Req. 3.1–3.7). + */ +function toGaugeAttributes(attrs: Array): Array { + return attrs.map(source => { + const binding = source.name.startsWith('['); + return { + name: source.name, + binding, + rawExpression: extractRawExpression(source), + source + }; + }); +} + +/** Extrai a expressão/valor original do atributo (conteúdo entre aspas, se houver). */ +function extractRawExpression(source: RawAttr): string { + const eqIndex = source.raw.indexOf('='); + if (eqIndex === -1) { + // Atributo booleano sem valor. + return ''; + } + + const afterEq = source.raw.slice(eqIndex + 1).trim(); + const first = afterEq[0]; + if (first === '"' || first === "'") { + return afterEq.slice(1, afterEq.lastIndexOf(first)); + } + return afterEq; +} + +/** + * Indica se já existe um comentário `TODO` da migração imediatamente antes do + * trecho (última linha não vazia do conteúdo já acumulado), evitando duplicatas + * em reexecuções (idempotência, Req. 7.4). + */ +function hasTodoImmediatelyBefore(result: string): boolean { + const trimmed = result.replace(/\s+$/, ''); + if (!trimmed.endsWith('-->')) { + return false; + } + const open = trimmed.lastIndexOf(' +

    Caso 1: Apenas p-value

    + + + +

    Caso 1b: p-value literal

    + + + +

    Caso 1c: p-value string numérica com binding

    + + + +

    Caso 1d: p-value zero

    + + + +

    Caso 1e: p-value overflow (>100)

    + + + +

    Caso 1f: p-value negativo

    + + + +

    Caso 2: Todas as propriedades

    + + + + +

    Caso 2b: Booleans explicitamente false

    + + + + +

    Caso 3: Com ranges e description

    + + + +

    Caso 3b: Ranges sem label

    + + + +

    Caso 3c: Ranges com cores hex

    + + + +

    Caso 3d: Ranges com cores RGB

    + + + +

    Caso 3e: Ranges com cores do tema

    + + + +

    Caso 4: Com p-options variável

    + + + +

    Caso 4b: p-options inline

    + + + + +

    Caso 4c: p-options completo

    + + + +

    Caso 4d: p-options com header

    + + + +

    Caso 4e: p-options com subtitleGauge

    + + + +

    Caso 4f: p-options com descriptionChart

    + + + + +

    Caso 4g: p-options sem container

    + + + +

    Caso 4h: p-options pointer false

    + + + +

    Caso 4i: p-options inline completo

    + + + + +

    Caso 5: Estático

    + + + +

    Caso 5b: Mix binding + estático

    + + + + +

    Caso 5c: Apenas título estático

    + + + +

    Caso 5d: Value e title estáticos

    + + + +

    Caso 6: Múltiplos gauges

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + + +

    Caso 6b: Gauges variados lado a lado

    +
    +
    + +
    +
    + +
    +
    + +
    +
    + + +

    Caso 7: Conteúdo projetado

    + + + +

    Caso 7b: Ranges + descrição

    + + + +

    Caso 8: Atributos genéricos

    + + + + +

    Caso 8b: Com style inline

    + + + +

    Caso 8c: Com data attributes

    + + + + +

    Caso 9: Dentro de *ngIf

    +
    + +
    + + +

    Caso 9b: Dentro de *ngFor

    +
    + + +
    + + +

    Caso 9c: Com ngSwitch

    + + + + + + + +

    Caso 9d: Com ng-template

    + + + + + + +

    Caso 10: showFromToLegend isolado

    + + + +

    Caso 10b: showPointer false

    + + + +

    Caso 10c: showPointer dinâmico

    + + + + +

    Caso 10d: showFromToLegend dinâmico

    + + + + +

    Caso 10e: Flags com expressão

    + + + + +

    Caso 11: Gauge ao lado de po-chart

    +
    +
    + +
    +
    + +
    +
    + + +

    Caso 11b: Pendente de migração

    + + + +

    Caso 12: Multiline

    + + + + +

    Caso 12b: Inline

    + + + +

    Caso 12c: Tag fechada imediata

    + + + +

    Caso 13: Height mínimo (300)

    + + + +

    Caso 13b: Height abaixo do mínimo

    + + + +

    Caso 13c: Height grande

    + + + +

    Caso 13d: Height dinâmico

    + + + +

    Caso 13e: Height literal

    + + + +

    Caso 14: Description com ranges (acima do gauge)

    + + + + +

    Caso 14b: Description sem ranges (dentro do arco)

    + + + +

    Caso 14c: Description dinâmico

    + + + +

    Caso 14d: Description longo

    + + + + +

    Caso 15: Title com binding

    + + + +

    Caso 15b: Title com expressão ternária

    + + + +

    Caso 16: p-options + p-show-from-to-legend (conflito)

    + + + + +

    Caso 16b: Conflito description

    + + + + +

    Caso 17: Ranges com valor abaixo do from mínimo

    + + + +

    Caso 17b: Value acima do max to

    + + + +

    Caso 17c: Ranges negativos

    + + + +

    Caso 17d: Um único range

    + + + +

    Caso 17e: Muitos ranges (12)

    + + + +

    Caso 18: Dentro de po-container

    + +
    Sales Performance
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +

    Caso 19: Value com expressão concatenada

    + + + +

    Caso 19b: Description com pipe

    + + + +

    Caso 20: Value com async pipe

    + + + + +

    Caso 21: Gauge vazio (sem props)

    + + + +

    Caso 22: Header options completo

    + + + +

    Caso 23: Com template reference

    + + + +

    Caso 24: Dentro de po-widget

    + + + + + +

    Caso 24b: Dentro de po-accordion

    + + + + + + + +

    Caso 25: Value com expressão aritmética

    + + + +

    Caso 25b: Value com ternário

    + + + +

    Caso 25c: Value com método

    + + + +

    Caso 25d: Value de objeto

    + + + +

    Caso 25e: Value com non-null assertion

    + + + +

    Caso 26: Indentação com 2 espaços

    +
    + +
    + + +

    Caso 26b: Indentação com 4 espaços

    +
    + +
    + + +

    Caso 27: Com @if (Angular 17+)

    +@if (showGauge) { + +} + + +

    Caso 27b: Com @for

    +@for (item of gaugeItems; track item.title) { + +} + + +

    Caso 27c: Com @switch

    +@switch (gaugeType) { + @case ('simple') { + + } + @case ('ranged') { + + } + @default { + + } +} + + +

    Caso 28: Ranges vazio

    + + + +

    Caso 28b: Ranges null

    + + + +

    Caso 29: Options apenas showContainerGauge true

    + + + +

    Caso 30: Atributos extras preservados

    + + + + +

    Caso 31: Gauge entre comentários HTML

    + + + + + +

    Caso 32: Labs-style (tudo dinâmico)

    + + + + +

    Caso 33: Minimal — só valor decimal

    + + + +

    Caso 33b: Valor decimal longo

    + + + +

    Caso 34: Com múltiplos event handlers

    + + + + +

    Caso 35: Dentro de form

    +
    + + +
    + + +

    Caso 36: Ranges inline literal

    + + + + +

    Caso 37: Atributos não-standard

    + + + +

    Caso 38: Múltiplas classes

    + + + + +

    Caso 39: Propriedades de @Input do pai

    + + + + +

    Caso 40: Tudo junto — máximo de propriedades

    + + diff --git a/projects/ui/schematics/ng-update/v22/gauge-manual-test/all-cases.component.ts b/projects/ui/schematics/ng-update/v22/gauge-manual-test/all-cases.component.ts new file mode 100644 index 0000000000..1406ab4623 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/gauge-manual-test/all-cases.component.ts @@ -0,0 +1,376 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Observable, of } from 'rxjs'; + +import { PoGaugeRanges, PoGaugeOptions } from '@po-ui/ng-components'; + +@Component({ + selector: 'app-all-gauge-cases', + templateUrl: './all-cases.component.html' +}) +export class AllGaugeCasesComponent implements OnInit { + // ═══════════════════════════════════════════════════════════════ + // CASO 1: p-value variações + // ═══════════════════════════════════════════════════════════════ + percentual = 65; + negativeValue = -10; + + // ═══════════════════════════════════════════════════════════════ + // CASO 2: Todas as propriedades + // ═══════════════════════════════════════════════════════════════ + currentValue = 85; + gaugeRanges: Array = [ + { from: 0, to: 40, label: 'Baixo', color: 'red' }, + { from: 40, to: 70, label: 'Médio', color: 'yellow' }, + { from: 70, to: 100, label: 'Alto', color: 'green' } + ]; + descricao = 'Desempenho do sistema'; + + // ═══════════════════════════════════════════════════════════════ + // CASO 3: Ranges variações + // ═══════════════════════════════════════════════════════════════ + score = 72; + scoreRanges: Array = [ + { from: 0, to: 50, label: 'Ruim', color: '#c64840' }, + { from: 50, to: 75, label: 'Regular', color: '#f5a623' }, + { from: 75, to: 100, label: 'Bom', color: '#0c9abe' } + ]; + + // Ranges sem label (legenda oculta) + rangesWithoutLabel: Array = [ + { from: 0, to: 33, color: '#c64840' }, + { from: 33, to: 66, color: '#f5a623' }, + { from: 66, to: 100, color: '#0c9abe' } + ]; + + // Ranges com cores hexadecimais + rangesHexColor: Array = [ + { from: 0, to: 25, label: 'Q1', color: '#FF5733' }, + { from: 25, to: 50, label: 'Q2', color: '#33FF57' }, + { from: 50, to: 75, label: 'Q3', color: '#3357FF' }, + { from: 75, to: 100, label: 'Q4', color: '#FF33F5' } + ]; + + // Ranges com cores RGB + rangesRgbColor: Array = [ + { from: 0, to: 33, label: 'Low', color: 'rgb(198, 72, 64)' }, + { from: 33, to: 66, label: 'Mid', color: 'rgb(245, 166, 35)' }, + { from: 66, to: 100, label: 'High', color: 'rgb(12, 154, 190)' } + ]; + + // Ranges com cores do tema PO + rangesThemeColor: Array = [ + { from: 0, to: 25, label: 'Color 01', color: 'color-01' }, + { from: 25, to: 50, label: 'Color 02', color: 'color-02' }, + { from: 50, to: 75, label: 'Color 03', color: 'color-03' }, + { from: 75, to: 100, label: 'Color 04', color: 'color-04' } + ]; + + // ═══════════════════════════════════════════════════════════════ + // CASO 4: p-options variações + // ═══════════════════════════════════════════════════════════════ + valor = 55; + gaugeOptions: PoGaugeOptions = { showFromToLegend: true }; + temperatura = 78; + + fullOptions: PoGaugeOptions = { + showFromToLegend: true, + pointer: true, + showContainerGauge: true, + subtitleGauge: 'Subtítulo completo', + descriptionChart: 'Descrição via options', + header: { + hideExpand: false, + hideTableDetails: false, + hideExportCsv: false, + hideExportImage: false + } + }; + + optionsWithHeader: PoGaugeOptions = { + header: { + hideExpand: true, + hideTableDetails: true, + hideExportCsv: true, + hideExportImage: true + } + }; + + optionsWithSubtitle: PoGaugeOptions = { + subtitleGauge: 'Este é o subtítulo', + showContainerGauge: true + }; + + optionsWithDescriptionChart: PoGaugeOptions = { + descriptionChart: 'Descrição vinda do options', + showContainerGauge: true + }; + + // ═══════════════════════════════════════════════════════════════ + // CASO 5: Atributos estáticos + // ═══════════════════════════════════════════════════════════════ + dynamicValue = 88; + myRanges: Array = [ + { from: 0, to: 30, label: 'Frio', color: 'blue' }, + { from: 30, to: 70, label: 'Morno', color: 'orange' }, + { from: 70, to: 100, label: 'Quente', color: 'red' } + ]; + + // ═══════════════════════════════════════════════════════════════ + // CASO 6: Múltiplos gauges + // ═══════════════════════════════════════════════════════════════ + cpu = 45; + cpuRanges: Array = [ + { from: 0, to: 60, label: 'Normal', color: 'green' }, + { from: 60, to: 85, label: 'Alto', color: 'yellow' }, + { from: 85, to: 100, label: 'Crítico', color: 'red' } + ]; + memory = 72; + memRanges: Array = [ + { from: 0, to: 50, label: 'OK', color: 'green' }, + { from: 50, to: 80, label: 'Atenção', color: 'yellow' }, + { from: 80, to: 100, label: 'Crítico', color: 'red' } + ]; + disk = 33; + + // ═══════════════════════════════════════════════════════════════ + // CASO 7: Conteúdo projetado + // ═══════════════════════════════════════════════════════════════ + progress = 60; + ranges: Array = [ + { from: 0, to: 50, label: 'Baixo', color: '#c64840' }, + { from: 50, to: 80, label: 'Médio', color: '#f5a623' }, + { from: 80, to: 100, label: 'Alto', color: '#0c9abe' } + ]; + + // ═══════════════════════════════════════════════════════════════ + // CASO 8: Atributos genéricos + // ═══════════════════════════════════════════════════════════════ + val = 90; + isActive = true; + showGauge = true; + + // ═══════════════════════════════════════════════════════════════ + // CASO 9: Estruturas condicionais + // ═══════════════════════════════════════════════════════════════ + gaugeItems = [ + { value: 30, title: 'Item 1', ranges: [], description: 'Primeiro' }, + { + value: 60, + title: 'Item 2', + ranges: [ + { from: 0, to: 50, color: 'red' }, + { from: 50, to: 100, color: 'green' } + ], + description: 'Segundo' + }, + { value: 90, title: 'Item 3', ranges: [], description: 'Terceiro' } + ]; + gaugeType = 'simple'; + + // ═══════════════════════════════════════════════════════════════ + // CASO 10: showFromToLegend e showPointer + // ═══════════════════════════════════════════════════════════════ + showPointerFlag = true; + showLegendFlag = false; + properties: Array = ['showFromToLegend', 'showPointer']; + + // ═══════════════════════════════════════════════════════════════ + // CASO 11: Convivência com po-chart + // ═══════════════════════════════════════════════════════════════ + b = 42; + chartSeries = [{ label: 'Series A', data: [10, 20, 30, 40, 50] }]; + + // ═══════════════════════════════════════════════════════════════ + // CASO 12: Indentação e formatação + // ═══════════════════════════════════════════════════════════════ + longVariableName = 67; + rangesArray: Array = [ + { from: 0, to: 33, label: 'Baixo', color: 'red' }, + { from: 33, to: 66, label: 'Médio', color: 'yellow' }, + { from: 66, to: 100, label: 'Alto', color: 'green' } + ]; + x = 55; + r: Array = [ + { from: 0, to: 50, color: '#c64840' }, + { from: 50, to: 100, color: '#0c9abe' } + ]; + + // ═══════════════════════════════════════════════════════════════ + // CASO 13: p-height variações + // ═══════════════════════════════════════════════════════════════ + dynamicHeight = 450; + + // ═══════════════════════════════════════════════════════════════ + // CASO 14: p-description variações + // ═══════════════════════════════════════════════════════════════ + dynamicDescription = 'Descrição dinâmica via variável'; + + // ═══════════════════════════════════════════════════════════════ + // CASO 15: p-title variações + // ═══════════════════════════════════════════════════════════════ + dynamicTitle = 'Título Dinâmico'; + + // ═══════════════════════════════════════════════════════════════ + // CASO 17: Ranges com valores extremos + // ═══════════════════════════════════════════════════════════════ + rangesStartAt20: Array = [ + { from: 20, to: 50, label: 'Baixo', color: 'blue' }, + { from: 50, to: 80, label: 'Alto', color: 'red' } + ]; + + rangesEndAt80: Array = [ + { from: 0, to: 40, label: 'Baixo', color: 'blue' }, + { from: 40, to: 80, label: 'Alto', color: 'red' } + ]; + + negativeRanges: Array = [ + { from: -50, to: -20, label: 'Muito Baixo', color: 'blue' }, + { from: -20, to: 0, label: 'Baixo', color: 'cyan' }, + { from: 0, to: 50, label: 'Normal', color: 'green' } + ]; + + singleRange: Array = [{ from: 0, to: 100, label: 'Total', color: 'green' }]; + + manyRanges: Array = [ + { from: 0, to: 8, label: 'R1', color: 'color-01' }, + { from: 8, to: 16, label: 'R2', color: 'color-02' }, + { from: 16, to: 24, label: 'R3', color: 'color-03' }, + { from: 24, to: 32, label: 'R4', color: 'color-04' }, + { from: 32, to: 40, label: 'R5', color: 'color-05' }, + { from: 40, to: 48, label: 'R6', color: 'color-06' }, + { from: 48, to: 56, label: 'R7', color: 'color-07' }, + { from: 56, to: 64, label: 'R8', color: 'color-08' }, + { from: 64, to: 72, label: 'R9', color: 'color-09' }, + { from: 72, to: 80, label: 'R10', color: 'color-10' }, + { from: 80, to: 90, label: 'R11', color: 'color-11' }, + { from: 90, to: 100, label: 'R12', color: 'color-12' } + ]; + + // ═══════════════════════════════════════════════════════════════ + // CASO 18: Uso dentro de po-container (sample-summary) + // ═══════════════════════════════════════════════════════════════ + turnoverRanges: Array = [ + { from: 0, to: 50, label: 'Low rate', color: '#00b28e' }, + { from: 50, to: 75, label: 'Average rate', color: '#ea9b3e' }, + { from: 75, to: 100, label: 'High rate', color: '#c64840' } + ]; + + salesRanges: Array = [ + { from: 0, to: 50, label: 'Sales reduction', color: '#c64840' }, + { from: 50, to: 75, label: 'Average sales', color: '#ea9b3e' }, + { from: 75, to: 100, label: 'Sales soared', color: '#00b28e' } + ]; + + // ═══════════════════════════════════════════════════════════════ + // CASO 19: Uso com pipe + // ═══════════════════════════════════════════════════════════════ + rawValue = 77.777; + + // ═══════════════════════════════════════════════════════════════ + // CASO 20: Uso com async pipe (Observable) + // ═══════════════════════════════════════════════════════════════ + gaugeValue$: Observable = of(68); + gaugeTitle$: Observable = of('Async Gauge'); + gaugeRanges$: Observable> = of([ + { from: 0, to: 50, label: 'Low', color: 'red' }, + { from: 50, to: 100, label: 'High', color: 'green' } + ]); + + // ═══════════════════════════════════════════════════════════════ + // CASO 22: Header options completo + // ═══════════════════════════════════════════════════════════════ + fullHeaderOptions: PoGaugeOptions = { + showFromToLegend: true, + pointer: true, + showContainerGauge: true, + subtitleGauge: 'Full Header Sub', + descriptionChart: 'Full Header Desc', + header: { + hideExpand: true, + hideTableDetails: true, + hideExportCsv: true, + hideExportImage: true + } + }; + + // ═══════════════════════════════════════════════════════════════ + // CASO 25: Expressões complexas + // ═══════════════════════════════════════════════════════════════ + gaugeData: { value: number; title: string; ranges: Array } = { + value: 78, + title: 'Object Gauge', + ranges: [ + { from: 0, to: 50, label: 'Low', color: 'red' }, + { from: 50, to: 100, label: 'High', color: 'green' } + ] + }; + + // ═══════════════════════════════════════════════════════════════ + // CASO 28: Ranges vazios e null + // ═══════════════════════════════════════════════════════════════ + emptyRanges: Array = []; + // @ts-ignore + nullRanges: Array = undefined; + + // ═══════════════════════════════════════════════════════════════ + // CASO 32: Labs-style (tudo dinâmico) + // ═══════════════════════════════════════════════════════════════ + labsDescription = 'Labs Description'; + labsHeight = 350; + labsRanges: Array = [ + { from: 0, to: 30, label: 'Baixo', color: '#c64840' }, + { from: 30, to: 60, label: 'Médio', color: '#f5a623' }, + { from: 60, to: 100, label: 'Alto', color: '#0c9abe' } + ]; + labsTitle = 'Labs Gauge'; + labsValue = 55; + labsOptions: PoGaugeOptions = { + showFromToLegend: true, + pointer: true, + showContainerGauge: true, + subtitleGauge: 'Labs Sub' + }; + labsShowFromToLegend = true; + labsShowPointer = true; + + // ═══════════════════════════════════════════════════════════════ + // CASO 35: Dentro de form + // ═══════════════════════════════════════════════════════════════ + formValue = 42; + + // ═══════════════════════════════════════════════════════════════ + // CASO 39: @Input properties do componente pai + // ═══════════════════════════════════════════════════════════════ + @Input() inputValue = 50; + @Input() inputTitle = 'Input Title'; + @Input() inputDescription = 'Input Desc'; + @Input() inputRanges: Array = [ + { from: 0, to: 50, color: 'blue' }, + { from: 50, to: 100, color: 'green' } + ]; + @Input() inputHeight = 300; + @Input() inputShowLegend = false; + @Input() inputShowPointer = true; + @Input() inputOptions: PoGaugeOptions = {}; + + ngOnInit(): void {} + + // ═══════════════════════════════════════════════════════════════ + // Métodos + // ═══════════════════════════════════════════════════════════════ + onGaugeClick(): void { + console.log('Gauge clicked!'); + } + + onMouseEnter(): void { + console.log('Mouse enter'); + } + + onMouseLeave(): void { + console.log('Mouse leave'); + } + + getGaugeValue(): number { + return 73; + } +} diff --git a/projects/ui/schematics/ng-update/v22/gauge-manual-test/all-cases.module.ts b/projects/ui/schematics/ng-update/v22/gauge-manual-test/all-cases.module.ts new file mode 100644 index 0000000000..0155cd10e6 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/gauge-manual-test/all-cases.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { PoGaugeModule } from '@po-ui/ng-components'; + +import { AllGaugeCasesComponent } from './all-cases.component'; + +@NgModule({ + declarations: [AllGaugeCasesComponent], + imports: [CommonModule, PoGaugeModule], + exports: [AllGaugeCasesComponent] +}) +export class AllGaugeCasesModule {} diff --git a/projects/ui/schematics/ng-update/v22/gauge-manual-test/run-migration.ts b/projects/ui/schematics/ng-update/v22/gauge-manual-test/run-migration.ts new file mode 100644 index 0000000000..411bf8d15f --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/gauge-manual-test/run-migration.ts @@ -0,0 +1,161 @@ +/** + * Script utilitário para testar manualmente a migração do po-gauge. + * + * Uso: + * npx ts-node --project tsconfig.json run-migration.ts + * + * Ou via tsx (mais rápido, sem compilar): + * npx tsx run-migration.ts + * + * O script lê todos os arquivos .html e .ts desta pasta (exceto ele mesmo), + * aplica a migração correspondente e grava o resultado na pasta "output/". + */ +import * as fs from 'fs'; +import * as path from 'path'; + +import { migrateHtmlContent } from '../gauge-html-migration'; +import { migrateTypeScriptContent } from '../gauge-ts-migration'; +import { MigrationWarning } from '../migration-report'; + +const DIR = __dirname; +const OUTPUT_DIR = path.join(DIR, 'output'); + +function ensureOutputDir(): void { + if (!fs.existsSync(OUTPUT_DIR)) { + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + } +} + +function run(): void { + ensureOutputDir(); + + const files = fs.readdirSync(DIR).filter(f => { + // Ignora este próprio script e a pasta de output + if (f === 'run-migration.ts' || f === 'output') return false; + return f.endsWith('.html') || f.endsWith('.ts'); + }); + + if (files.length === 0) { + console.log('Nenhum arquivo .html ou .ts encontrado para migrar.'); + return; + } + + let totalChanged = 0; + let totalWarnings = 0; + + for (const file of files) { + const filePath = path.join(DIR, file); + const source = fs.readFileSync(filePath, 'utf-8'); + const ext = path.extname(file); + + console.log(`\n${'─'.repeat(60)}`); + console.log(`📄 ${file}`); + + if (ext === '.html') { + const result = migrateHtmlContent(source); + fs.writeFileSync(path.join(OUTPUT_DIR, file), result.content, 'utf-8'); + + if (result.changed) { + totalChanged++; + console.log(' ✅ Migrado com sucesso'); + } else { + console.log(' ⏭️ Sem alterações'); + } + + if (result.warnings.length > 0) { + totalWarnings += result.warnings.length; + result.warnings.forEach(w => { + console.log(` ⚠️ Linha ${w.line}: ${w.reason}`); + }); + } + } else if (ext === '.ts') { + // Primeiro aplica a migração TypeScript (imports/referências). + const tsResult = migrateTypeScriptContent(source, true); + // Depois aplica a migração HTML em templates inline (template: `...`). + const withInlineTemplates = migrateInlineTemplates(tsResult.content); + + const finalContent = withInlineTemplates.content; + const changed = tsResult.changed || withInlineTemplates.changed; + + fs.writeFileSync(path.join(OUTPUT_DIR, file), finalContent, 'utf-8'); + + if (changed) { + totalChanged++; + console.log(' ✅ Migrado com sucesso'); + } else { + console.log(' ⏭️ Sem alterações'); + } + + const allWarnings = [...tsResult.warnings, ...withInlineTemplates.warnings]; + if (allWarnings.length > 0) { + totalWarnings += allWarnings.length; + allWarnings.forEach(w => { + console.log(` ⚠️ Linha ${w.line}: ${w.reason}`); + }); + } + } + } + + console.log(`\n${'─'.repeat(60)}`); + console.log(`\n📊 Resumo:`); + console.log(` Arquivos processados: ${files.length}`); + console.log(` Arquivos alterados: ${totalChanged}`); + console.log(` Warnings: ${totalWarnings}`); + console.log(`\n📁 Resultados gravados em: ${OUTPUT_DIR}`); +} + +/** + * Procura templates inline (template: `...` ou template: '...' ou template: "...") + * dentro de um arquivo .ts e aplica migrateHtmlContent em cada um encontrado. + */ +function migrateInlineTemplates(source: string): { + content: string; + changed: boolean; + warnings: Array; +} { + const warnings: Array = []; + let changed = false; + + // Regex para encontrar template: `...` (backtick — mais comum para multiline) + const templateRegex = /template\s*:\s*`([^`]*)`/g; + let result = source; + + // Processa templates com backticks + result = result.replace(templateRegex, (match, templateContent: string) => { + const migrated = migrateHtmlContent(templateContent); + if (migrated.changed) { + changed = true; + warnings.push(...migrated.warnings); + return match.replace(templateContent, migrated.content); + } + return match; + }); + + // Processa templates com aspas simples (single-line) + const singleQuoteRegex = /template\s*:\s*'([^']*)'/g; + result = result.replace(singleQuoteRegex, (match, templateContent: string) => { + const migrated = migrateHtmlContent(templateContent); + if (migrated.changed) { + changed = true; + warnings.push(...migrated.warnings); + return match.replace(templateContent, migrated.content); + } + return match; + }); + + // Processa templates com aspas duplas (single-line) + const doubleQuoteRegex = /template\s*:\s*"([^"]*)"/g; + result = result.replace(doubleQuoteRegex, (match, templateContent: string) => { + const migrated = migrateHtmlContent(templateContent); + if (migrated.changed) { + changed = true; + warnings.push(...migrated.warnings); + return match.replace(templateContent, migrated.content); + } + return match; + }); + + return { content: result, changed, warnings }; +} + +run(); diff --git a/projects/ui/schematics/ng-update/v22/gauge-property-map.spec.ts b/projects/ui/schematics/ng-update/v22/gauge-property-map.spec.ts new file mode 100644 index 0000000000..531283b546 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/gauge-property-map.spec.ts @@ -0,0 +1,621 @@ +import * as fc from 'fast-check'; + +import { GaugeAttribute, mapGaugeProperties } from './gauge-property-map'; + +/** + * Gera fragmentos de expressão "atômicos" e plausíveis de aparecer em um + * binding `[p-value]="..."` de template Angular: literais numéricos, + * identificadores, acessos a propriedades, chamadas de método e literais de + * string. As expressões são combinadas para exercitar o mapeamento sem + * introduzir espaços nas bordas (a implementação preserva a expressão via + * `trim()`). + */ +const identifierArb = fc + .tuple( + fc.constantFrom(...'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$'.split('')), + fc.stringMatching(/^[a-zA-Z0-9_$]*$/) + ) + .map(([head, tail]) => `${head}${tail}`); + +const numberArb = fc.oneof( + fc.integer({ min: 0, max: 1_000_000 }).map(String), + fc.float({ min: 0, max: 1000, noNaN: true }).map(value => String(value)) +); + +const memberAccessArb = fc.array(identifierArb, { minLength: 2, maxLength: 4 }).map(parts => parts.join('.')); + +const methodCallArb = fc.tuple(identifierArb, identifierArb).map(([obj, method]) => `${obj}.${method}()`); + +const ternaryArb = fc.tuple(identifierArb, numberArb, numberArb).map(([cond, a, b]) => `${cond} ? ${a} : ${b}`); + +/** Expressão de binding arbitrária, sem espaços nas bordas. */ +const valueExpressionArb = fc.oneof(numberArb, identifierArb, memberAccessArb, methodCallArb, ternaryArb); + +describe('v22 gauge-property-map (property-based):', () => { + /** + * Propriedade 5 — Mapeamento de `p-value` (sem `p-ranges`). + * + * Para qualquer expressão de valor, `mapGaugeProperties` com um atributo + * `p-value` (binding) deve produzir um `pSeries` na forma + * `[{ data: }]`, preservando a expressão original textualmente. + */ + it('should map a `p-value` binding to `[{ data: }]` preserving the original expression (Prop 5)', () => { + fc.assert( + fc.property(valueExpressionArb, expression => { + const attr: GaugeAttribute = { + name: 'p-value', + binding: true, + rawExpression: expression + }; + + const result = mapGaugeProperties([attr]); + + // A expressão original é preservada dentro da estrutura { data: ... }. + expect(result.pSeries).toBe(`[{ data: ${expression.trim()} }]`); + // Reforço: a expressão original aparece textualmente no resultado. + expect(result.pSeries).toContain(expression.trim()); + // p-value sozinho não deve gerar pValueGaugeMultiple. + expect(result.pValueGaugeMultiple).toBeUndefined(); + // p-value não deve gerar casos não migráveis. + expect(result.unmapped).toEqual([]); + expect(result.conflicts).toEqual([]); + }), + { numRuns: 500 } + ); + }); + + it('should preserve the expression even when the binding has surrounding whitespace (Prop 5)', () => { + fc.assert( + fc.property( + valueExpressionArb, + fc.stringMatching(/^ *$/), + fc.stringMatching(/^ *$/), + (expression, pad1, pad2) => { + const attr: GaugeAttribute = { + name: 'p-value', + binding: true, + rawExpression: `${pad1}${expression}${pad2}` + }; + + const result = mapGaugeProperties([attr]); + + expect(result.pSeries).toBe(`[{ data: ${expression.trim()} }]`); + } + ), + { numRuns: 300 } + ); + }); +}); + +/** + * Gera um objeto de faixa (`range`) plausível de aparecer em `p-ranges`, como + * `{ from: 0, to: 50, color: 'green' }`. Os objetos possuem vírgulas internas, + * o que torna a contagem de faixas de nível superior um teste real de + * preservação da quantidade. + */ +const rangeObjectArb = fc + .record( + { + from: numberArb, + to: numberArb, + color: identifierArb.map(id => `'${id}'`), + label: identifierArb.map(id => `'${id}'`) + }, + { requiredKeys: ['from', 'to'] } + ) + .map( + range => + `{ ${Object.entries(range) + .map(([key, value]) => `${key}: ${value}`) + .join(', ')} }` + ); + +/** Lista de 1..6 objetos de faixa (a quantidade N que deve ser preservada). */ +const rangesListArb = fc.array(rangeObjectArb, { minLength: 1, maxLength: 6 }); + +/** + * Conta os elementos de nível superior de um array literal preservado + * textualmente, respeitando aninhamento de `{}`/`[]`/`()` e literais de string. + * Usado para verificar que a quantidade de faixas foi mantida no resultado. + */ +function countTopLevelElements(arrayLiteral: string): number { + const trimmed = arrayLiteral.trim(); + const inner = trimmed.slice(1, -1); + if (inner.trim().length === 0) { + return 0; + } + + let depth = 0; + let count = 1; + let quote = ''; + + for (let i = 0; i < inner.length; i++) { + const char = inner[i]; + + if (quote) { + if (char === quote && inner[i - 1] !== '\\') { + quote = ''; + } + continue; + } + + if (char === '"' || char === "'" || char === '`') { + quote = char; + continue; + } + + if (char === '{' || char === '[' || char === '(') { + depth++; + } else if (char === '}' || char === ']' || char === ')') { + depth--; + } else if (char === ',' && depth === 0) { + count++; + } + } + + return count; +} + +describe('v22 gauge-property-map ranges preservation (property-based):', () => { + /** + * Propriedade 6 — Preservação da quantidade de faixas. + * + * Para qualquer binding `p-ranges` cuja expressão seja um array literal com N + * objetos de faixa, após `mapGaugeProperties` o `pSeries` resultante deve + * preservar a mesma quantidade de faixas (N) e a expressão original das + * faixas textualmente. + */ + it('should preserve the number of ranges and the original expression when only `p-ranges` is present (Prop 6)', () => { + fc.assert( + fc.property(rangesListArb, ranges => { + const arrayLiteral = `[${ranges.join(', ')}]`; + const attr: GaugeAttribute = { + name: 'p-ranges', + binding: true, + rawExpression: arrayLiteral + }; + + const result = mapGaugeProperties([attr]); + + // Apenas p-ranges: a expressão é preservada verbatim em p-series. + expect(result.pSeries).toBe(arrayLiteral); + // A quantidade de faixas (N) é mantida. O `!` e exigido pelo build + // strict (tsconfig.schematics-spec.json); a regra no-unnecessary-type- + // assertion gera falso positivo por nao propagar o narrowing do expect. + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + expect(countTopLevelElements(result.pSeries!)).toBe(ranges.length); + // Cada faixa original aparece textualmente no resultado. + ranges.forEach(range => expect(result.pSeries).toContain(range)); + // Sem p-value, pValueGaugeMultiple não é gerado. + expect(result.pValueGaugeMultiple).toBeUndefined(); + // Somente faixas não geram casos não migráveis. + expect(result.unmapped).toEqual([]); + expect(result.conflicts).toEqual([]); + }), + { numRuns: 500 } + ); + }); + + /** + * Propriedade 6 (combinada com `p-value`) — quando ambos estão presentes, + * p-ranges vai direto para p-series e p-value vai para pValueGaugeMultiple + * (como no ngOnChanges do po-gauge original). + */ + it('should put ranges in p-series and value in p-value-gauge-multiple when both present (Prop 6)', () => { + fc.assert( + fc.property(valueExpressionArb, rangesListArb, (value, ranges) => { + const arrayLiteral = `[${ranges.join(', ')}]`; + const attrs: Array = [ + { name: 'p-value', binding: true, rawExpression: value }, + { name: 'p-ranges', binding: true, rawExpression: arrayLiteral } + ]; + + const result = mapGaugeProperties(attrs); + + // p-series recebe ranges diretamente (como this.series = [...this.ranges]). + expect(result.pSeries).toBe(arrayLiteral); + // p-value vai para pValueGaugeMultiple (como this.valuesMultiple = this.value). + expect(result.pValueGaugeMultiple).toBe(value.trim()); + // A quantidade de faixas (N) é mantida. O `!` e exigido pelo build + // strict (tsconfig.schematics-spec.json); a regra no-unnecessary-type- + // assertion gera falso positivo por nao propagar o narrowing do expect. + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + expect(countTopLevelElements(result.pSeries!)).toBe(ranges.length); + // Cada faixa original aparece textualmente no resultado. + ranges.forEach(range => expect(result.pSeries).toContain(range)); + }), + { numRuns: 500 } + ); + }); +}); + +/** + * Definições das propriedades individuais do `po-gauge` que são mapeadas para + * chaves de `p-options` do `po-chart` (conforme o comportamento real do + * po-gauge). `p-title` e `p-height` agora são passthrough direto. + */ +const optionPropDefs: ReadonlyArray<{ gaugeProp: string; optionsKey: string }> = [ + { gaugeProp: 'p-description', optionsKey: 'descriptionChart' }, + { gaugeProp: 'p-show-from-to-legend', optionsKey: 'showFromToLegend' }, + { gaugeProp: 'p-show-pointer', optionsKey: 'pointer' } +]; + +/** Todas as `optionsKey` mapeáveis para `p-options`. */ +const allOptionKeys = optionPropDefs.map(def => def.optionsKey); + +/** Subconjunto não vazio (preservando ordem) das propriedades de `p-options`. */ +const nonEmptyOptionSubsetArb = fc.subarray([...optionPropDefs], { minLength: 1 }); + +describe('v22 gauge-property-map option-keys omission (property-based):', () => { + /** + * Propriedade 7 — Omissão de chaves não definidas. + * + * Para qualquer subconjunto de propriedades do `po-gauge` fornecido, + * `mapGaugeProperties` deve gerar em `p-options` apenas as chaves das + * propriedades presentes (mais `showContainerGauge: true` como default), + * omitindo (sem valor padrão) as chaves das propriedades ausentes. + */ + it('should only emit keys for provided properties (plus showContainerGauge default) and omit the missing ones (Prop 7)', () => { + fc.assert( + fc.property(nonEmptyOptionSubsetArb, subset => { + const attrs: Array = subset.map(def => ({ + name: def.gaugeProp, + binding: true, + // Valor identificador único e distinto por chave, sem `:` embutido. + rawExpression: `val_${def.optionsKey}` + })); + + const result = mapGaugeProperties(attrs); + + const providedKeys = subset.map(def => def.optionsKey); + const missingKeys = allOptionKeys.filter(key => !providedKeys.includes(key)); + + // p-options deve existir (showContainerGauge é sempre injetado). + expect(result.pOptions).toBeDefined(); + + // showContainerGauge: true é sempre presente. + expect(result.pOptions).toContain('showContainerGauge: true'); + + // Cada chave fornecida aparece com sua expressão original preservada. + providedKeys.forEach(key => { + expect(result.pOptions).toContain(`${key}: val_${key}`); + }); + + // Nenhuma chave ausente é injetada (sem valor padrão). + missingKeys.forEach(key => { + expect(result.pOptions).not.toContain(`${key}:`); + }); + + // Sem propriedades de série, pSeries é [] (default do po-gauge); sem conflitos/unmapped. + expect(result.pSeries).toBe('[]'); + expect(result.conflicts).toEqual([]); + expect(result.unmapped).toEqual([]); + }), + { numRuns: 500 } + ); + }); +}); + +describe('v22 gauge-property-map p-options conflict priority (property-based):', () => { + /** + * Gera um cenário de conflito: um subconjunto não vazio de propriedades + * individuais (`individual`) e um subconjunto não vazio dessas + * (`conflicting`) que também são definidas dentro do objeto literal + * `p-options`. Os valores individuais e os de `p-options` são distintos, o que + * permite verificar qual valor prevalece. + */ + const conflictScenarioArb = nonEmptyOptionSubsetArb.chain(individual => + fc.subarray([...individual], { minLength: 1 }).map(conflicting => ({ individual, conflicting })) + ); + + /** + * Propriedade 8 — Prioridade em conflito de `p-options`. + * + * Quando uma mesma chave de destino em `p-options` é definida tanto por uma + * propriedade individual do `po-gauge` quanto por uma chave dentro do objeto + * `p-options`, o valor de `p-options` deve prevalecer e a chave em conflito + * deve ser registrada em `result.conflicts`. + */ + it('should let the `p-options` value win on conflict and record the conflicting key (Prop 8)', () => { + fc.assert( + fc.property(conflictScenarioArb, ({ individual, conflicting }) => { + const conflictKeys = conflicting.map(def => def.optionsKey); + + // Bindings das propriedades individuais (valor prefixado `indiv_`). + const individualAttrs: Array = individual.map(def => ({ + name: def.gaugeProp, + binding: true, + rawExpression: `indiv_${def.optionsKey}` + })); + + // Objeto literal p-options com as chaves conflitantes (valor `po_`) + + // showContainerGauge para absorver o default sem gerar conflito extra. + const optionsLiteral = `{ ${conflictKeys.map(key => `${key}: po_${key}`).join(', ')}, showContainerGauge: true }`; + const optionsAttr: GaugeAttribute = { + name: 'p-options', + binding: true, + rawExpression: optionsLiteral + }; + + const result = mapGaugeProperties([...individualAttrs, optionsAttr]); + + // Todas (e somente) as chaves em conflito são registradas. + expect([...result.conflicts].sort()).toEqual([...conflictKeys].sort()); + + // p-options deve existir e o valor prevalecente depende da chave. + expect(result.pOptions).toBeDefined(); + conflictKeys.forEach(key => { + if (key === 'descriptionChart') { + // descriptionChart de p-description PREVALECE sobre p-options + // (this.description || options.descriptionChart no po-gauge original). + expect(result.pOptions).toContain(`descriptionChart: indiv_descriptionChart`); + expect(result.pOptions).not.toContain('po_descriptionChart'); + } else { + // Demais chaves: o valor de p-options prevalece; o individual é descartado. + expect(result.pOptions).toContain(`${key}: po_${key}`); + expect(result.pOptions).not.toContain(`indiv_${key}`); + } + }); + + // Propriedades individuais SEM conflito são preservadas com seu valor. + individual + .filter(def => !conflictKeys.includes(def.optionsKey)) + .forEach(def => { + expect(result.pOptions).toContain(`${def.optionsKey}: indiv_${def.optionsKey}`); + }); + + // Conflito de p-options não afeta série nem gera propriedades não mapeadas. + expect(result.pSeries).toBe('[]'); + expect(result.unmapped).toEqual([]); + }), + { numRuns: 500 } + ); + }); +}); + +describe('v22 gauge-property-map (unit):', () => { + /** + * Propriedade `p-*` sem equivalente na Tabela de Mapeamento deve ser coletada + * em `result.unmapped` (Caso_Nao_Migravel), preservada verbatim, e não deve + * contaminar `pSeries`/`pOptions`. + */ + it('should collect a `p-*` attribute without equivalent in `unmapped`', () => { + const fooBinding: GaugeAttribute = { name: '[p-foo]', binding: true, rawExpression: 'someExpr' }; + const barStatic: GaugeAttribute = { name: 'p-bar', binding: false, rawExpression: 'baz' }; + + const result = mapGaugeProperties([fooBinding, barStatic]); + + // Ambas as propriedades `p-*` desconhecidas vão para `unmapped`, preservadas. + expect(result.unmapped).toEqual([fooBinding, barStatic]); + // Não devem aparecer em passthrough nem série. + expect(result.passthrough).toEqual([]); + expect(result.pSeries).toBe('[]'); + // showContainerGauge default é sempre injetado em p-options. + expect(result.pOptions).toBe('{ showContainerGauge: true }'); + expect(result.conflicts).toEqual([]); + }); + + /** + * Atributos que não começam com `p-` (ex.: `class`, eventos `(click)`, + * bindings estruturais) são atributos genéricos do elemento e devem ser + * preservados em `result.passthrough`, jamais mapeados. + */ + it('should collect non `p-*` attributes (class, events) in `passthrough`', () => { + const classAttr: GaugeAttribute = { name: 'class', binding: false, rawExpression: 'x' }; + const clickAttr: GaugeAttribute = { name: '(click)', binding: false, rawExpression: 'f()' }; + const idBinding: GaugeAttribute = { name: '[id]', binding: true, rawExpression: 'gaugeId' }; + + const result = mapGaugeProperties([classAttr, clickAttr, idBinding]); + + // Todos os atributos genéricos são preservados, na ordem original. + expect(result.passthrough).toEqual([classAttr, clickAttr, idBinding]); + // Nada é mapeado nem sinalizado como sem equivalente. + expect(result.unmapped).toEqual([]); + expect(result.pSeries).toBe('[]'); + // showContainerGauge default é injetado em p-options. + expect(result.pOptions).toBe('{ showContainerGauge: true }'); + expect(result.conflicts).toEqual([]); + }); + + /** + * Caso canônico: `[p-value]="72"`, `p-description="Faturamento"` e + * `[p-show-from-to-legend]="true"` produzem: + * - `pSeries = [{ data: 72 }]` + * - `pOptions = { showContainerGauge: true, descriptionChart: 'Faturamento', showFromToLegend: true }` + */ + it('should map the canonical `p-value` + `p-description` + `p-show-from-to-legend` case', () => { + const attrs: Array = [ + { name: 'p-value', binding: true, rawExpression: '72' }, + { name: 'p-description', binding: false, rawExpression: 'Faturamento' }, + { name: 'p-show-from-to-legend', binding: true, rawExpression: 'true' } + ]; + + const result = mapGaugeProperties(attrs); + + expect(result.pSeries).toBe('[{ data: 72 }]'); + expect(result.pOptions).toBe( + "{ showContainerGauge: true, descriptionChart: 'Faturamento', showFromToLegend: true }" + ); + expect(result.passthrough).toEqual([]); + expect(result.unmapped).toEqual([]); + expect(result.conflicts).toEqual([]); + }); + + /** + * `p-title` e `p-height` devem ir para passthrough (como no template real do + * po-gauge que passa `[p-title]` e `[p-height]` diretamente para o po-chart). + */ + it('should treat `p-title` and `p-height` as passthrough attributes', () => { + const titleAttr: GaugeAttribute = { name: 'p-title', binding: false, rawExpression: 'Velocidade' }; + const heightAttr: GaugeAttribute = { name: '[p-height]', binding: true, rawExpression: '300' }; + + const result = mapGaugeProperties([titleAttr, heightAttr]); + + expect(result.passthrough).toEqual([titleAttr, heightAttr]); + expect(result.pSeries).toBe('[]'); + // p-options ainda tem showContainerGauge default. + expect(result.pOptions).toBe('{ showContainerGauge: true }'); + expect(result.unmapped).toEqual([]); + }); + + /** + * `p-show-pointer` deve ir para `p-options.pointer`. + */ + it('should map `p-show-pointer` to `p-options.pointer`', () => { + const pointerAttr: GaugeAttribute = { name: '[p-show-pointer]', binding: true, rawExpression: 'true' }; + + const result = mapGaugeProperties([pointerAttr]); + + expect(result.pOptions).toBe('{ showContainerGauge: true, pointer: true }'); + expect(result.pSeries).toBe('[]'); + expect(result.unmapped).toEqual([]); + }); + + /** + * Formatação de atributo estático vs. binding: um atributo estático é + * convertido em literal de string (`'Faturamento'`), enquanto um binding + * preserva a expressão original textualmente (`descVar`). + */ + it('should format a static attribute as a string literal in `p-options`', () => { + const result = mapGaugeProperties([{ name: 'p-description', binding: false, rawExpression: 'Faturamento' }]); + + expect(result.pOptions).toBe("{ showContainerGauge: true, descriptionChart: 'Faturamento' }"); + expect(result.pSeries).toBe('[]'); + }); + + it('should preserve the original expression for a `p-description` binding in `p-options`', () => { + const result = mapGaugeProperties([{ name: '[p-description]', binding: true, rawExpression: 'descVar' }]); + + expect(result.pOptions).toBe('{ showContainerGauge: true, descriptionChart: descVar }'); + expect(result.pSeries).toBe('[]'); + }); + + /** + * Formatação de atributo estático: aspas simples dentro do valor são + * escapadas ao gerar o literal de string. + */ + it('should escape single quotes when formatting a static attribute value', () => { + const result = mapGaugeProperties([{ name: 'p-description', binding: false, rawExpression: "Vendas d'agosto" }]); + + expect(result.pOptions).toBe("{ showContainerGauge: true, descriptionChart: 'Vendas d\\'agosto' }"); + }); + + /** + * showContainerGauge: true é injetado por padrão mesmo sem nenhuma propriedade + * de options fornecida. + */ + it('should always inject showContainerGauge: true in p-options', () => { + const result = mapGaugeProperties([{ name: 'p-value', binding: true, rawExpression: '50' }]); + + expect(result.pOptions).toBe('{ showContainerGauge: true }'); + expect(result.pSeries).toBe('[{ data: 50 }]'); + }); + + /** + * Quando p-options já tem showContainerGauge definido, não há conflito + * registrado (é apenas um default). + */ + it('should not register conflict for showContainerGauge when already in p-options', () => { + const attrs: Array = [ + { name: 'p-options', binding: true, rawExpression: '{ showContainerGauge: false }' } + ]; + + const result = mapGaugeProperties(attrs); + + // O valor de p-options prevalece, sem conflito registrado. + expect(result.pOptions).toContain('showContainerGauge: false'); + expect(result.conflicts).toEqual([]); + }); + + /** + * Fallback condicional para ranges dinâmico: quando p-value + p-ranges (variável) + * estão presentes, p-series deve usar expressão ternária `expr && expr.length ? expr : [{ data: value }]`. + */ + it('should generate conditional fallback for dynamic ranges with p-value (cases 9b, 28, 28b)', () => { + const attrs: Array = [ + { name: 'p-value', binding: true, rawExpression: 'item.value' }, + { name: 'p-ranges', binding: true, rawExpression: 'item.ranges' } + ]; + + const result = mapGaugeProperties(attrs); + + expect(result.pSeries).toBe('item.ranges && item.ranges.length ? item.ranges : [{ data: item.value }]'); + expect(result.pValueGaugeMultiple).toBe('item.ranges && item.ranges.length ? item.value : undefined'); + }); + + /** + * Ranges como array literal não vazio: não gera fallback condicional, usa direto. + */ + it('should use direct series (no fallback) when p-ranges is a non-empty array literal (case 36)', () => { + const attrs: Array = [ + { name: 'p-value', binding: true, rawExpression: '60' }, + { name: 'p-ranges', binding: true, rawExpression: '[{ from: 0, to: 50 }, { from: 50, to: 100 }]' } + ]; + + const result = mapGaugeProperties(attrs); + + expect(result.pSeries).toBe('[{ from: 0, to: 50 }, { from: 50, to: 100 }]'); + expect(result.pValueGaugeMultiple).toBe('60'); + }); + + /** + * p-description prevalece sobre descriptionChart em p-options literal (case 16b). + */ + it('should let p-description win over descriptionChart in p-options literal (case 16b)', () => { + const attrs: Array = [ + { name: 'p-description', binding: false, rawExpression: 'Desc pela propriedade' }, + { name: 'p-options', binding: true, rawExpression: "{ descriptionChart: 'Desc pelo options' }" } + ]; + + const result = mapGaugeProperties(attrs); + + expect(result.pOptions).toContain("descriptionChart: 'Desc pela propriedade'"); + expect(result.pOptions).not.toContain('Desc pelo options'); + expect(result.conflicts).toContain('descriptionChart'); + }); + + /** + * p-description prevalece sobre p-options opaco via spread (case 40). + * descriptionChart deve vir DEPOIS do spread para prevalecer. + */ + it('should let p-description win over p-options opaque variable via spread (case 40)', () => { + const attrs: Array = [ + { name: '[p-description]', binding: true, rawExpression: 'descricao' }, + { name: 'p-options', binding: true, rawExpression: 'fullOptions' } + ]; + + const result = mapGaugeProperties(attrs); + + // descriptionChart vem após o spread para garantir prioridade + expect(result.pOptions).toContain('...fullOptions, descriptionChart: descricao'); + }); + + /** + * Gauge sem nenhuma propriedade (case 21): gera series vazio e options default. + */ + it('should handle gauge with no properties at all (case 21)', () => { + const result = mapGaugeProperties([]); + + expect(result.pSeries).toBe('[]'); + expect(result.pOptions).toBe('{ showContainerGauge: true }'); + expect(result.pValueGaugeMultiple).toBeUndefined(); + expect(result.passthrough).toEqual([]); + expect(result.unmapped).toEqual([]); + expect(result.conflicts).toEqual([]); + }); + + /** + * p-options opaco (variável) sem p-description: spread no final, sem descriptionChart extra. + */ + it('should spread opaque p-options at the end without extra descriptionChart when no p-description (case 4)', () => { + const attrs: Array = [ + { name: 'p-value', binding: true, rawExpression: 'valor' }, + { name: 'p-options', binding: true, rawExpression: 'gaugeOptions' } + ]; + + const result = mapGaugeProperties(attrs); + + expect(result.pOptions).toBe('{ showContainerGauge: true, ...gaugeOptions }'); + expect(result.pOptions).not.toContain('descriptionChart'); + }); +}); diff --git a/projects/ui/schematics/ng-update/v22/gauge-property-map.ts b/projects/ui/schematics/ng-update/v22/gauge-property-map.ts new file mode 100644 index 0000000000..fa97eb0d55 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/gauge-property-map.ts @@ -0,0 +1,366 @@ +import { gaugePropertyRules, GaugePropertyRule } from './changes'; + +/** + * Representa um único atributo/binding de um elemento `po-gauge` extraído do + * template. A expressão original é preservada textualmente (`rawExpression`), + * sem qualquer avaliação, garantindo que a migração seja fiel ao código-fonte. + */ +export interface GaugeAttribute { + /** Nome da propriedade do po-gauge (ex.: `p-value`, `p-ranges`). */ + name: string; + /** `true` quando o atributo é um property binding (`[p-value]="..."`). */ + binding: boolean; + /** Expressão/valor original preservado textualmente. */ + rawExpression: string; +} + +/** + * Resultado do mapeamento das propriedades do `po-gauge` para os atributos do + * `po-chart`, conforme o comportamento real do componente po-gauge da v21. + */ +export interface MappedChartAttributes { + /** Expressão gerada para `[p-series]` do po-chart. */ + pSeries?: string; + /** Expressão gerada para `[p-options]` do po-chart (omitida se não aplicável). */ + pOptions?: string; + /** Expressão gerada para `[p-value-gauge-multiple]` (quando p-value + p-ranges). */ + pValueGaugeMultiple?: string; + /** Atributos fora do Mapeamento_Propriedades preservados no elemento (Req. 2.5). */ + passthrough: Array; + /** Propriedades `po-gauge` sem equivalente na tabela (Req. 3.10). */ + unmapped: Array; + /** Chaves de `p-options` em conflito entre propriedade individual e `p-options` (Req. 3.11). */ + conflicts: Array; +} + +/** Índice das regras de mapeamento por nome da propriedade do po-gauge. */ +const ruleByProp: Map = (() => { + const map = new Map(); + gaugePropertyRules.forEach(rule => map.set(rule.gaugeProp, rule)); + return map; +})(); + +/** + * Mapeia os atributos/bindings de um `po-gauge` para a configuração equivalente + * do `po-chart`, seguindo o comportamento real do componente po-gauge da v21. + * + * Regras aplicadas (baseadas no template e ngOnChanges do po-gauge): + * - `p-value` sem `p-ranges` → `[p-series]="[{ data: }]"` + * - `p-value` com `p-ranges` → `[p-value-gauge-multiple]=""` + * - `p-ranges` → `[p-series]=""` (direto, sem wrap) + * - `p-title` → `[p-title]` passthrough direto no po-chart + * - `p-height` → `[p-height]` passthrough direto no po-chart + * - `p-description` → `p-options.descriptionChart` + * - `p-show-from-to-legend` → `p-options.showFromToLegend` + * - `p-show-pointer` → `p-options.pointer` + * - `p-options` → mescla para `[p-options]` do po-chart + * - `showContainerGauge: true` é injetado por padrão em `p-options` + * (comportamento do ngOnInit do po-gauge) + * - Propriedade `p-*` sem equivalente: coletada em `unmapped` + * - Demais atributos (não `po-gauge`): coletados em `passthrough` + * - Conflito entre propriedade individual e chave de `p-options`: prevalece o + * valor de `p-options` e o conflito é registrado + */ +export function mapGaugeProperties(attrs: Array): MappedChartAttributes { + const result: MappedChartAttributes = { + passthrough: [], + unmapped: [], + conflicts: [] + }; + + let valueAttr: GaugeAttribute | undefined; + let rangesAttr: GaugeAttribute | undefined; + let optionsAttr: GaugeAttribute | undefined; + + // Entradas individuais destinadas a p-options, na ordem de ocorrência. + const optionEntries: Array<{ key: string; value: string }> = []; + + attrs.forEach(attr => { + const base = normalizeName(attr.name); + const rule = ruleByProp.get(base); + + if (!rule) { + // Propriedade `p-*` do po-gauge sem equivalente vs. atributo genérico + // preservado. + if (base.toLowerCase().startsWith('p-')) { + result.unmapped.push(attr); + } else { + result.passthrough.push(attr); + } + return; + } + + switch (rule.target) { + case 'p-series': + if (base === 'p-value') { + valueAttr = attr; + } else if (base === 'p-ranges') { + rangesAttr = attr; + } + break; + case 'p-options': + if (base === 'p-options') { + optionsAttr = attr; + } else if (rule.optionsKey) { + optionEntries.push({ key: rule.optionsKey, value: formatValue(attr) }); + } + break; + case 'passthrough': + // p-title e p-height vão direto como inputs do po-chart. + result.passthrough.push(attr); + break; + } + }); + + const pSeries = buildSeries(valueAttr, rangesAttr); + if (pSeries !== undefined) { + result.pSeries = pSeries; + } + + // Quando p-value + p-ranges estão presentes, o valor vai para + // p-value-gauge-multiple (como no ngOnChanges do po-gauge original). + if (valueAttr && rangesAttr) { + const rangesExpr = formatValue(rangesAttr); + if (isNonEmptyArrayLiteral(rangesExpr)) { + result.pValueGaugeMultiple = formatValue(valueAttr); + } else { + // Ranges dinâmico: quando vazio em runtime, o po-gauge colocava o valor na + // série (`[{ data: value }]`) e não usava valuesMultiple. Replica esse + // fallback condicional para preservar o comportamento original. + // Usa `expr && expr.length` para evitar warning NG8107. + result.pValueGaugeMultiple = `${rangesExpr} && ${rangesExpr}.length ? ${formatValue(valueAttr)} : undefined`; + } + } + + const pOptions = buildOptions(optionEntries, optionsAttr, result.conflicts); + if (pOptions !== undefined) { + result.pOptions = pOptions; + } + + return result; +} + +/** + * Constrói a expressão de `p-series` seguindo o comportamento real do + * ngOnChanges do po-gauge: + * - Com ranges: `this.series = [...this.ranges]` → p-series recebe ranges diretamente + * - Sem ranges, com value: `this.series = [{ data: this.value }]` + * - Nem value nem ranges: gera `[]` (comportamento padrão do po-gauge que + * inicializava `series: Array = []`) + * + * Quando ambos existem, o value é tratado separadamente via + * `p-value-gauge-multiple` (pelo chamador). + */ +function buildSeries(valueAttr: GaugeAttribute | undefined, rangesAttr: GaugeAttribute | undefined): string { + if (rangesAttr) { + const rangesExpr = formatValue(rangesAttr); + + // Array literal não vazio: o conteúdo é garantido em tempo de build, então + // usa os ranges diretamente (equivale a `this.series = [...this.ranges]`). + if (isNonEmptyArrayLiteral(rangesExpr)) { + return rangesExpr; + } + + // Ranges dinâmico (variável/expressão) ou array literal vazio: pode não ter + // itens em runtime. O po-gauge decidia isso em tempo de execução no + // ngOnChanges: + // this.ranges?.length ? [...this.ranges] + // : (value ? [{ data: value }] : []) + // Replica esse fallback condicional para preservar o comportamento original. + // Usa `expr && expr.length` em vez de `expr?.length` para evitar o warning + // NG8107 do Angular (optional chain desnecessário em tipos não-nullable). + const fallback = valueAttr ? `[{ data: ${formatValue(valueAttr)} }]` : '[]'; + return `${rangesExpr} && ${rangesExpr}.length ? ${rangesExpr} : ${fallback}`; + } + + if (valueAttr) { + // Sem ranges: series é [{ data: value }]. + return `[{ data: ${formatValue(valueAttr)} }]`; + } + + // Sem value nem ranges: o po-gauge inicializava series como [] por padrão. + // É necessário passar explicitamente para evitar que o po-chart receba + // undefined (o que causaria erro em runtime no template). + return '[]'; +} + +/** + * Indica se a expressão é um array literal com pelo menos um elemento (ex.: + * `[{ from: 0, to: 50 }]`). Nesses casos o conteúdo é garantido em build-time e + * dispensa o fallback condicional aplicado a ranges dinâmicos. + */ +function isNonEmptyArrayLiteral(expr: string): boolean { + const trimmed = expr.trim(); + return trimmed.startsWith('[') && trimmed.endsWith(']') && trimmed.slice(1, -1).trim().length > 0; +} + +/** + * Constrói a expressão de `p-options` mesclando as propriedades individuais com + * o objeto `p-options` de origem, e injetando `showContainerGauge: true` por + * padrão (comportamento do ngOnInit do po-gauge original). + * + * Quando uma mesma chave é definida pela propriedade individual e por + * `p-options`, prevalece o valor de `p-options` e o conflito é registrado. + */ +function buildOptions( + individualEntries: Array<{ key: string; value: string }>, + optionsAttr: GaugeAttribute | undefined, + conflicts: Array +): string | undefined { + // showContainerGauge: true é o default do ngOnInit do po-gauge. + const defaultEntries: Array<{ key: string; value: string }> = [{ key: 'showContainerGauge', value: 'true' }]; + + const allIndividualEntries = [...defaultEntries, ...individualEntries]; + + if (!optionsAttr) { + return `{ ${allIndividualEntries.map(entry => `${entry.key}: ${entry.value}`).join(', ')} }`; + } + + const optionsExpr = optionsAttr.binding ? optionsAttr.rawExpression.trim() : formatValue(optionsAttr); + const isLiteralObject = optionsAttr.binding && optionsExpr.startsWith('{') && optionsExpr.endsWith('}'); + + if (isLiteralObject) { + const topLevelKeys = parseTopLevelKeys(optionsExpr); + const keptEntries: Array<{ key: string; value: string }> = []; + + allIndividualEntries.forEach(entry => { + if (topLevelKeys.includes(entry.key)) { + if (entry.key === 'descriptionChart') { + // descriptionChart de p-description PREVALECE sobre p-options + // (comportamento do po-gauge: this.description || options.descriptionChart). + keptEntries.push(entry); + conflicts.push(entry.key); + } else if (entry.key !== 'showContainerGauge') { + // Demais chaves: prevalece o valor definido em p-options. + // Não registra conflito para showContainerGauge (é apenas um default). + conflicts.push(entry.key); + } + } else { + keptEntries.push(entry); + } + }); + + // Monta o corpo do p-options literal, removendo a chave descriptionChart + // quando p-description prevalece (para não duplicar a chave). + let inner = optionsExpr.slice(1, -1).trim(); + const descriptionOverrides = + allIndividualEntries.some(entry => entry.key === 'descriptionChart') && topLevelKeys.includes('descriptionChart'); + + if (descriptionOverrides) { + inner = splitTopLevel(inner, ',') + .map(part => part.trim()) + .filter(part => part.length > 0) + .filter(part => { + const key = (splitTopLevel(part, ':')[0] ?? '').trim().replace(/^['"`]|['"`]$/g, ''); + return key !== 'descriptionChart'; + }) + .join(', '); + } + + const parts = keptEntries.map(entry => `${entry.key}: ${entry.value}`); + if (inner.length > 0) { + parts.push(inner); + } + + return parts.length > 0 ? `{ ${parts.join(', ')} }` : '{}'; + } + + // p-options é uma expressão opaca (variável/chamada): mescla via spread. + // As chaves individuais vêm antes do spread (p-options vence), EXCETO + // descriptionChart, que vem depois do spread para prevalecer, replicando + // `this.description || options.descriptionChart` do po-gauge original. + const descriptionEntry = allIndividualEntries.find(entry => entry.key === 'descriptionChart'); + const otherEntries = allIndividualEntries.filter(entry => entry.key !== 'descriptionChart'); + + const otherParts = otherEntries.map(entry => `${entry.key}: ${entry.value}`).join(', '); + const prefix = otherParts.length > 0 ? `${otherParts}, ` : ''; + + if (descriptionEntry) { + return `{ ${prefix}...${optionsExpr}, ${descriptionEntry.key}: ${descriptionEntry.value} }`; + } + return `{ ${prefix}...${optionsExpr} }`; +} + +/** + * Formata o valor de um atributo para uso em uma expressão de binding do + * po-chart. Bindings preservam a expressão original; atributos estáticos são + * convertidos em literais de string (Req. 3.1, 3.3). + */ +function formatValue(attr: GaugeAttribute): string { + if (attr.binding) { + return attr.rawExpression.trim(); + } + return `'${attr.rawExpression.replace(/'/g, "\\'")}'`; +} + +/** Remove colchetes/parênteses de binding e espaços do nome de um atributo. */ +function normalizeName(name: string): string { + return name + .replace(/^[[(]/, '') + .replace(/[\])]$/, '') + .trim(); +} + +/** + * Extrai as chaves de primeiro nível de um objeto literal preservado + * textualmente, respeitando aninhamento de `{}`/`[]`/`()` e literais de string. + */ +function parseTopLevelKeys(objectLiteral: string): Array { + const inner = objectLiteral.trim().slice(1, -1); + + return splitTopLevel(inner, ',') + .map(entry => { + const key = splitTopLevel(entry, ':')[0]?.trim() ?? ''; + return key.replace(/^['"`]|['"`]$/g, ''); + }) + .filter(key => key.length > 0); +} + +/** + * Divide uma string por um separador considerando apenas o nível superior, + * ignorando separadores dentro de `{}`/`[]`/`()` ou de literais de string. + */ +function splitTopLevel(source: string, separator: string): Array { + const parts: Array = []; + let current = ''; + let depth = 0; + let quote = ''; + + for (let i = 0; i < source.length; i++) { + const char = source[i]; + + if (quote) { + current += char; + if (char === quote && source[i - 1] !== '\\') { + quote = ''; + } + continue; + } + + if (char === '"' || char === "'" || char === '`') { + quote = char; + current += char; + continue; + } + + if (char === '{' || char === '[' || char === '(') { + depth++; + } else if (char === '}' || char === ']' || char === ')') { + depth--; + } + + if (char === separator && depth === 0) { + parts.push(current); + current = ''; + continue; + } + + current += char; + } + + if (current.trim().length > 0) { + parts.push(current); + } + + return parts; +} diff --git a/projects/ui/schematics/ng-update/v22/gauge-ts-migration.spec.ts b/projects/ui/schematics/ng-update/v22/gauge-ts-migration.spec.ts new file mode 100644 index 0000000000..4a3d6c6541 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/gauge-ts-migration.spec.ts @@ -0,0 +1,497 @@ +import fc from 'fast-check'; + +import { gaugeSymbolMap, gaugeSymbolsWithoutEquivalent } from './changes'; +import { migrateTypeScriptContent } from './gauge-ts-migration'; + +/** + * Testes de propriedade para a transformação de referências TypeScript + * (`migrateTypeScriptContent`). + */ +describe('v22 gauge-ts-migration (property-based):', () => { + // Símbolos gauge que possuem equivalente direto no po-chart. + const gaugeSymbols = Object.keys(gaugeSymbolMap); + + // Conjunto de símbolos não-gauge, reais do @po-ui/ng-components, garantidamente + // distintos dos símbolos gauge e de seus equivalentes (evita colisões de dedup). + const nonGaugeSymbols = [ + 'PoButtonModule', + 'PoTableModule', + 'PoFieldModule', + 'PoModalModule', + 'PoNotificationModule', + 'PoPageModule', + 'PoLoadingModule', + 'PoWidgetModule', + 'PoInfoModule', + 'PoTabsModule' + ]; + + /** Verifica a presença de um identificador com fronteira de palavra. */ + function hasSymbol(content: string, symbol: string): boolean { + return new RegExp(`\\b${symbol}\\b`).test(content); + } + + /** Gera um subconjunto não-vazio, sem repetição. */ + function nonEmptySubset(pool: Array): fc.Arbitrary> { + return fc.subarray(pool, { minLength: 1, maxLength: pool.length }); + } + + function subset(pool: Array): fc.Arbitrary> { + return fc.subarray(pool, { minLength: 0, maxLength: pool.length }); + } + + /** + * Extrai os símbolos nomeados do import de `@po-ui/ng-components` presente no + * conteúdo, retornando a lista de nomes (na forma textual, ex.: `PoChartModule` + * ou `PoGaugeModule as Foo`). Retorna `[]` quando não há import do pacote. + */ + function poUiImportSymbols(content: string): Array { + const match = content.match(/import\s*\{([^}]*)\}\s*from\s*['"]@po-ui\/ng-components['"]/); + if (!match) { + return []; + } + return match[1] + .split(',') + .map(symbol => symbol.trim()) + .filter(symbol => symbol.length > 0); + } + + /** Indica se há símbolos duplicados na lista de imports informada. */ + function hasDuplicateSymbols(symbols: Array): boolean { + return new Set(symbols).size !== symbols.length; + } + + /** + * Propriedade 9: Preservação dos demais imports (TS) + * + * Para qualquer declaração de importação de `@po-ui/ng-components` que misture + * símbolos gauge (com equivalente) e símbolos não-gauge arbitrários, após + * `migrateTypeScriptContent`: + * - cada símbolo gauge é substituído pelo equivalente de `gaugeSymbolMap`; + * - todos os símbolos não-gauge do mesmo import são preservados. + * + * **Validates: Requisitos 4.1, 4.2** + */ + it('should replace gauge symbols by their equivalents while preserving every non-gauge import (Prop 9)', () => { + fc.assert( + fc.property( + nonEmptySubset(gaugeSymbols), + subset(nonGaugeSymbols), + fc.boolean(), + fc.boolean(), + (chosenGauge, chosenNonGauge, gaugeFirst, isStandalone) => { + // Compõe a lista de símbolos do import, variando a ordem relativa. + const symbols = gaugeFirst ? [...chosenGauge, ...chosenNonGauge] : [...chosenNonGauge, ...chosenGauge]; + + const source = `import { ${symbols.join(', ')} } from '@po-ui/ng-components';\n`; + + const result = migrateTypeScriptContent(source, isStandalone); + + // 1. Todos os símbolos não-gauge devem permanecer presentes. + for (const symbol of chosenNonGauge) { + expect(hasSymbol(result.content, symbol)).toBe(true); + } + + // 2. Cada símbolo gauge deve ter sido substituído pelo equivalente. + for (const gauge of chosenGauge) { + const equivalent = gaugeSymbolMap[gauge]; + + expect(hasSymbol(result.content, equivalent)).toBe(true); + expect(hasSymbol(result.content, gauge)).toBe(false); + } + + // 3. Como há ao menos um símbolo gauge com equivalente, houve alteração. + expect(result.changed).toBe(true); + + // 4. Nenhuma advertência para símbolos que possuem equivalente. + expect(result.warnings.length).toBe(0); + } + ) + ); + }); + + /** + * Propriedade 10: Símbolo sem equivalente inalterado (TS) + * + * Para qualquer fonte TypeScript que importe ao menos um símbolo gauge SEM + * equivalente (`PoGaugeCoordinates`/`PoGaugeSvgContainer`, de + * `gaugeSymbolsWithoutEquivalent`) de `@po-ui/ng-components` — possivelmente + * misturado a outros símbolos —, após `migrateTypeScriptContent`: + * - o conteúdo é retornado INALTERADO (idêntico byte a byte ao original); + * - `changed === false`; + * - ao menos um `MigrationWarning` é registrado para o símbolo sem equivalente. + * + * **Validates: Requisito 4.4** + */ + it('should keep content unchanged and register a warning when a no-equivalent gauge symbol is imported (Prop 10)', () => { + // Pool de "outros símbolos" arbitrários: não-gauge + gauge com equivalente. + // Independentemente da mistura, a presença de um símbolo sem equivalente + // deve manter o arquivo inalterado (Req. 4.4). + const otherSymbols = [...nonGaugeSymbols, ...gaugeSymbols]; + + fc.assert( + fc.property( + nonEmptySubset([...gaugeSymbolsWithoutEquivalent]), + subset(otherSymbols), + fc.boolean(), + fc.boolean(), + (chosenWithout, chosenOthers, withoutFirst, isStandalone) => { + // Compõe a lista de símbolos do import, variando a ordem relativa. + const symbols = withoutFirst ? [...chosenWithout, ...chosenOthers] : [...chosenOthers, ...chosenWithout]; + + const source = `import { ${symbols.join(', ')} } from '@po-ui/ng-components';\n`; + + const result = migrateTypeScriptContent(source, isStandalone); + + // 1. Conteúdo idêntico byte a byte ao original. + expect(result.content).toBe(source); + + // 2. Nenhuma alteração aplicada. + expect(result.changed).toBe(false); + + // 3. Ao menos uma advertência registrada. + expect(result.warnings.length).toBeGreaterThanOrEqual(1); + + // 4. Ao menos uma advertência referencia um símbolo sem equivalente. + const mentionsWithout = result.warnings.some(warning => + chosenWithout.some(symbol => warning.reason.includes(symbol)) + ); + expect(mentionsWithout).toBe(true); + } + ) + ); + }); + + /** + * Propriedade 1: Idempotência (ponto fixo) — TS + * + * Para qualquer fonte TypeScript variada (import de `@po-ui/ng-components` + * misturando símbolos gauge com equivalente, símbolos não-gauge, opcionalmente + * símbolos sem equivalente, e opcionalmente uma estrutura `@NgModule` + * declarando/importando/exportando ou um componente standalone importando os + * símbolos gauge), aplicar `migrateTypeScriptContent` duas vezes produz o mesmo + * conteúdo que aplicá-la uma única vez (a transformação é um ponto fixo): + * + * migrate(migrate(x, s).content, s).content === migrate(x, s).content + * + * Além disso, após a segunda execução, não há símbolos de import duplicados. + * + * **Validates: Requisitos 7.2, 7.4** + */ + it('should be idempotent (fixed point) and not duplicate import symbols on the second run (Prop 1)', () => { + // Símbolos gauge que podem aparecer em arrays de módulo/standalone. + const referenceableGauge = gaugeSymbols; + + /** + * Constrói uma fonte TypeScript variada a partir dos parâmetros gerados. + */ + function buildSource(params: { + chosenGauge: Array; + chosenNonGauge: Array; + chosenWithout: Array; + gaugeFirst: boolean; + structure: 'none' | 'ngmodule' | 'standalone'; + }): string { + const { chosenGauge, chosenNonGauge, chosenWithout, gaugeFirst, structure } = params; + + const gaugePart = [...chosenGauge, ...chosenWithout]; + const symbols = gaugeFirst ? [...gaugePart, ...chosenNonGauge] : [...chosenNonGauge, ...gaugePart]; + + // Sempre há ao menos um símbolo no import (garantido pelos geradores). + let source = `import { ${symbols.join(', ')} } from '@po-ui/ng-components';\n\n`; + + // Referências usadas nas estruturas: apenas símbolos gauge com equivalente + // efetivamente importados (identificadores válidos no corpo do arquivo). + const refs = chosenGauge; + + if (structure === 'ngmodule') { + const decls = ['AppComponent', ...refs].join(', '); + const imps = ['CommonModule', ...refs].join(', '); + const exps = refs.join(', '); + source += + `@NgModule({\n` + + ` declarations: [${decls}],\n` + + ` imports: [${imps}],\n` + + ` exports: [${exps}]\n` + + `})\n` + + `export class AppModule {}\n`; + } else if (structure === 'standalone') { + const imps = ['CommonModule', ...refs].join(', '); + source += + `@Component({\n` + + ` selector: 'app-demo',\n` + + ` imports: [${imps}],\n` + + ` template: ''\n` + + `})\n` + + `export class DemoComponent {}\n`; + } + + return source; + } + + fc.assert( + fc.property( + subset(referenceableGauge), + subset(nonGaugeSymbols), + subset([...gaugeSymbolsWithoutEquivalent]), + fc.boolean(), + fc.constantFrom('none', 'ngmodule', 'standalone'), + fc.boolean(), + (chosenGauge, chosenNonGauge, chosenWithout, gaugeFirst, structure, isStandalone) => { + // Garante ao menos um símbolo no import para uma fonte válida. + if (chosenGauge.length + chosenNonGauge.length + chosenWithout.length === 0) { + return true; + } + + const source = buildSource({ + chosenGauge, + chosenNonGauge, + chosenWithout, + gaugeFirst, + structure + }); + + const once = migrateTypeScriptContent(source, isStandalone).content; + const twice = migrateTypeScriptContent(once, isStandalone).content; + + // 1. Ponto fixo: aplicar duas vezes é igual a aplicar uma vez. + expect(twice).toBe(once); + + // 2. Nenhum símbolo de import duplicado após a segunda execução. + expect(hasDuplicateSymbols(poUiImportSymbols(twice))).toBe(false); + + return true; + } + ) + ); + }); +}); + +/** + * Testes unitários (baseados em exemplos) para a transformação de referências + * TypeScript em projetos NgModule e standalone. + * + * Cobrem os cenários da migração po-gauge → po-chart em que os símbolos gauge + * aparecem nas listas `declarations`/`imports`/`exports` de um `@NgModule`, nos + * `imports` de um componente standalone e na configuração da aplicação + * standalone, verificando que: + * - as referências gauge são atualizadas para os equivalentes do po-chart; + * - a declaração de importação é atualizada de forma correspondente; + * - todos os demais itens já existentes são preservados. + * + * Validates: Requisitos 5.1, 5.2, 5.3 + */ +describe('v22 gauge-ts-migration (NgModule e standalone):', () => { + /** Extrai os símbolos importados de `@po-ui/ng-components`, se houver. */ + function poUiImportSymbols(content: string): Array { + const match = content.match(/import\s*\{([^}]*)\}\s*from\s*['"]@po-ui\/ng-components['"]/); + if (!match) { + return []; + } + return match[1] + .split(',') + .map(symbol => symbol.trim()) + .filter(symbol => symbol.length > 0); + } + + /** + * Extrai o conteúdo textual de uma lista nomeada de um decorator + * (`declarations: [...]`, `imports: [...]`, `exports: [...]`, `providers: [...]`). + */ + function arrayContentOf(content: string, key: string): string { + const match = content.match(new RegExp(`${key}\\s*:\\s*\\[([^\\]]*)\\]`)); + return match ? match[1] : ''; + } + + describe('NgModule (Req 5.1):', () => { + const source = + `import { NgModule } from '@angular/core';\n` + + `import { CommonModule } from '@angular/common';\n` + + `import { PoButtonModule, PoGaugeModule, PoGaugeComponent, PoFieldModule } from '@po-ui/ng-components';\n` + + `\n` + + `import { AppComponent } from './app.component';\n` + + `\n` + + `@NgModule({\n` + + ` declarations: [AppComponent, PoGaugeComponent],\n` + + ` imports: [CommonModule, PoButtonModule, PoGaugeModule, PoFieldModule],\n` + + ` bootstrap: [AppComponent]\n` + + `})\n` + + `export class AppModule {}\n`; + + const result = migrateTypeScriptContent(source, false); + + it('should mark the file as changed without warnings', () => { + expect(result.changed).toBe(true); + expect(result.warnings.length).toBe(0); + }); + + it('should update gauge references in declarations to the po-chart equivalent', () => { + const declarations = arrayContentOf(result.content, 'declarations'); + + expect(declarations).toContain('PoChartComponent'); + expect(declarations).not.toContain('PoGaugeComponent'); + // Item já existente preservado. + expect(declarations).toContain('AppComponent'); + }); + + it('should update gauge references in imports to the po-chart equivalent', () => { + const imports = arrayContentOf(result.content, 'imports'); + + expect(imports).toContain('PoChartModule'); + expect(imports).not.toContain('PoGaugeModule'); + // Itens já existentes preservados, na mesma ordem. + expect(imports).toContain('CommonModule'); + expect(imports).toContain('PoButtonModule'); + expect(imports).toContain('PoFieldModule'); + }); + + it('should update the po-ui import declaration replacing gauge symbols by equivalents', () => { + const symbols = poUiImportSymbols(result.content); + + expect(symbols).toContain('PoChartModule'); + expect(symbols).toContain('PoChartComponent'); + expect(symbols).toContain('PoButtonModule'); + expect(symbols).toContain('PoFieldModule'); + expect(symbols).not.toContain('PoGaugeModule'); + expect(symbols).not.toContain('PoGaugeComponent'); + }); + + it('should preserve unrelated imports and the bootstrap array untouched', () => { + // Imports de @angular preservados. + expect(result.content).toContain(`import { NgModule } from '@angular/core';`); + expect(result.content).toContain(`import { CommonModule } from '@angular/common';`); + // Array bootstrap preservado. + expect(arrayContentOf(result.content, 'bootstrap')).toContain('AppComponent'); + }); + }); + + describe('NgModule com exports (Req 5.1):', () => { + const source = + `import { NgModule } from '@angular/core';\n` + + `import { PoGaugeModule } from '@po-ui/ng-components';\n` + + `\n` + + `@NgModule({\n` + + ` imports: [PoGaugeModule],\n` + + ` exports: [PoGaugeModule]\n` + + `})\n` + + `export class SharedModule {}\n`; + + const result = migrateTypeScriptContent(source, false); + + it('should update gauge references in both imports and exports arrays', () => { + expect(result.changed).toBe(true); + expect(arrayContentOf(result.content, 'imports')).toContain('PoChartModule'); + expect(arrayContentOf(result.content, 'exports')).toContain('PoChartModule'); + expect(result.content).not.toContain('PoGaugeModule'); + }); + }); + + describe('Componente standalone (Req 5.2):', () => { + const source = + `import { Component } from '@angular/core';\n` + + `import { CommonModule } from '@angular/common';\n` + + `import { PoTableModule, PoGaugeModule } from '@po-ui/ng-components';\n` + + `\n` + + `@Component({\n` + + ` selector: 'app-dashboard',\n` + + ` standalone: true,\n` + + ` imports: [CommonModule, PoGaugeModule, PoTableModule],\n` + + ` template: ''\n` + + `})\n` + + `export class DashboardComponent {}\n`; + + const result = migrateTypeScriptContent(source, true); + + it('should mark the file as changed without warnings', () => { + expect(result.changed).toBe(true); + expect(result.warnings.length).toBe(0); + }); + + it('should update gauge references in the standalone imports to the po-chart equivalent', () => { + const imports = arrayContentOf(result.content, 'imports'); + + expect(imports).toContain('PoChartModule'); + expect(imports).not.toContain('PoGaugeModule'); + // Itens já existentes preservados. + expect(imports).toContain('CommonModule'); + expect(imports).toContain('PoTableModule'); + }); + + it('should update the po-ui import declaration preserving the non-gauge symbol', () => { + const symbols = poUiImportSymbols(result.content); + + expect(symbols).toContain('PoChartModule'); + expect(symbols).toContain('PoTableModule'); + expect(symbols).not.toContain('PoGaugeModule'); + }); + }); + + describe('Configuração de aplicação standalone (Req 5.3):', () => { + const source = + `import { ApplicationConfig, importProvidersFrom } from '@angular/core';\n` + + `import { provideRouter } from '@angular/router';\n` + + `import { PoGaugeModule, PoI18nModule } from '@po-ui/ng-components';\n` + + `\n` + + `import { routes } from './app.routes';\n` + + `\n` + + `export const appConfig: ApplicationConfig = {\n` + + ` providers: [provideRouter(routes), importProvidersFrom(PoGaugeModule, PoI18nModule)]\n` + + `};\n`; + + const result = migrateTypeScriptContent(source, true); + + it('should mark the file as changed without warnings', () => { + expect(result.changed).toBe(true); + expect(result.warnings.length).toBe(0); + }); + + it('should update the gauge reference in the application config providers', () => { + expect(result.content).toContain('importProvidersFrom(PoChartModule, PoI18nModule)'); + expect(result.content).not.toContain('PoGaugeModule'); + }); + + it('should preserve the remaining providers and po-ui symbols', () => { + // Provedor não relacionado preservado. + expect(result.content).toContain('provideRouter(routes)'); + // Símbolo po-ui não-gauge preservado no import. + const symbols = poUiImportSymbols(result.content); + expect(symbols).toContain('PoChartModule'); + expect(symbols).toContain('PoI18nModule'); + expect(symbols).not.toContain('PoGaugeModule'); + }); + }); + + describe('Interfaces do gauge em NgModule/standalone (Req 5.1, 5.2):', () => { + const source = + `import { Component } from '@angular/core';\n` + + `import { PoGaugeRanges, PoGaugeOptions } from '@po-ui/ng-components';\n` + + `\n` + + `@Component({\n` + + ` selector: 'app-metric',\n` + + ` template: ''\n` + + `})\n` + + `export class MetricComponent {\n` + + ` ranges: Array = [];\n` + + ` options: PoGaugeOptions = {};\n` + + `}\n`; + + const result = migrateTypeScriptContent(source, true); + + it('should replace gauge interface imports and usages by their equivalents', () => { + expect(result.changed).toBe(true); + expect(result.warnings.length).toBe(0); + + const symbols = poUiImportSymbols(result.content); + expect(symbols).toContain('PoChartSerie'); + expect(symbols).toContain('PoChartOptions'); + expect(symbols).not.toContain('PoGaugeRanges'); + expect(symbols).not.toContain('PoGaugeOptions'); + + // Usos no corpo da classe atualizados. + expect(result.content).toContain('Array'); + expect(result.content).toContain('options: PoChartOptions'); + expect(result.content).not.toContain('PoGaugeRanges'); + expect(result.content).not.toContain('PoGaugeOptions'); + }); + }); +}); diff --git a/projects/ui/schematics/ng-update/v22/gauge-ts-migration.ts b/projects/ui/schematics/ng-update/v22/gauge-ts-migration.ts new file mode 100644 index 0000000000..840aaf96c8 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/gauge-ts-migration.ts @@ -0,0 +1,442 @@ +import * as ts from 'typescript'; + +import { gaugeSymbolMap, gaugeSymbolsWithoutEquivalent, PO_UI_PACKAGE } from './changes'; +import { MigrationWarning } from './migration-report'; + +/** + * Resultado da transformação de um arquivo TypeScript pela Schematic_Migracao. + * + * A função `migrateTypeScriptContent` é pura (string → string): recebe o + * conteúdo original e devolve o conteúdo transformado, um indicador de + * alteração e a lista de Casos_Nao_Migravel encontrados. + */ +export interface TsMigrationResult { + /** Conteúdo do arquivo após a transformação (idêntico ao original se nada mudou). */ + content: string; + /** `true` somente quando alguma transformação foi efetivamente aplicada. */ + changed: boolean; + /** Casos_Nao_Migravel identificados (ex.: símbolo gauge sem equivalente). */ + warnings: Array; +} + +/** Edição textual pontual a ser aplicada sobre o conteúdo original. */ +interface TextEdit { + start: number; + end: number; + text: string; +} + +/** Informações de um símbolo gauge encontrado em uma declaração de importação. */ +interface GaugeSpecifierInfo { + specifier: ts.ImportSpecifier; + /** Nome importado (lado esquerdo de `as`, ou o próprio nome). */ + importedName: string; + /** Nome local usado nas referências (lado direito de `as`, ou o próprio nome). */ + localName: string; + /** Indica se o import usa alias (`PoGaugeModule as Foo`). */ + aliased: boolean; + namedImports: ts.NamedImports; + decl: ts.ImportDeclaration; +} + +/** + * Transforma referências ao `po-gauge` em referências equivalentes ao + * `po-chart` em um arquivo TypeScript. + * + * Comportamento (Req. 4.1–4.4, 4.6, 5.1–5.3): + * - Localiza `ImportDeclaration` de `@po-ui/ng-components` que contenham + * símbolos gauge e substitui os símbolos com equivalente conhecido + * (`gaugeSymbolMap`), preservando os demais símbolos do mesmo import. + * - Atualiza as referências desses símbolos no restante do arquivo + * (`declarations`/`imports`/`exports` de `@NgModule` e `imports` de + * componentes standalone / configuração da aplicação). + * - Se um símbolo gauge importado NÃO possui equivalente + * (`gaugeSymbolsWithoutEquivalent`), o arquivo é mantido inalterado e um + * `MigrationWarning` é registrado (Req. 4.4). + * - Deduplica símbolos-alvo já importados, evitando imports/itens duplicados + * (idempotência, Req. 7.4). + * - Preserva indentação, quebras de linha e a ordenação das importações não + * relacionadas ao gauge (Req. 4.6). + * + * @param source Conteúdo original do arquivo `.ts`. + * @param isStandalone Indica se o projeto é standalone (mantido por contrato de + * interface; a transformação de referências é a mesma para ambas as + * arquiteturas). + */ +export function migrateTypeScriptContent(source: string, isStandalone: boolean): TsMigrationResult { + void isStandalone; + + const warnings: Array = []; + const sourceFile = ts.createSourceFile('file.ts', source, ts.ScriptTarget.Latest, /* setParentNodes */ true); + + const poUiImports = collectPoUiImports(sourceFile); + + if (poUiImports.length === 0) { + return { content: source, changed: false, warnings }; + } + + const gaugeSpecifiers: Array = []; + const withoutEquivalent: Array = []; + const allImportedNames = new Set(); + + for (const decl of poUiImports) { + const named = getNamedImports(decl); + if (!named) { + continue; + } + + for (const element of named.elements) { + const importedName = (element.propertyName ?? element.name).text; + const localName = element.name.text; + allImportedNames.add(localName); + + if (Object.prototype.hasOwnProperty.call(gaugeSymbolMap, importedName)) { + gaugeSpecifiers.push({ + specifier: element, + importedName, + localName, + aliased: element.propertyName !== undefined, + namedImports: named, + decl + }); + } else if (gaugeSymbolsWithoutEquivalent.includes(importedName)) { + withoutEquivalent.push(element); + } + } + } + + // Req. 4.4 — símbolo gauge sem equivalente: mantém o arquivo inalterado e + // registra advertência para revisão manual. + if (withoutEquivalent.length > 0) { + for (const element of withoutEquivalent) { + const importedName = (element.propertyName ?? element.name).text; + warnings.push({ + filePath: '', + line: lineOf(sourceFile, element), + reason: + `O símbolo "${importedName}" do po-gauge não possui equivalente no po-chart. ` + + `Revise manualmente este arquivo antes de removê-lo.` + }); + } + + return { content: source, changed: false, warnings }; + } + + if (gaugeSpecifiers.length === 0) { + return { content: source, changed: false, warnings }; + } + + const edits: Array = []; + + // Nomes locais (sem alias) que serão substituídos por seu equivalente nas + // referências ao longo do arquivo. + const referenceRenameMap = new Map(); + + buildImportEdits(sourceFile, gaugeSpecifiers, allImportedNames, referenceRenameMap, edits); + + buildReferenceEdits(sourceFile, poUiImports, referenceRenameMap, edits); + + if (edits.length === 0) { + return { content: source, changed: false, warnings }; + } + + const content = applyEdits(source, edits); + + return { content, changed: content !== source, warnings }; +} + +/** Coleta as `ImportDeclaration` cujo módulo é `@po-ui/ng-components`. */ +function collectPoUiImports(sourceFile: ts.SourceFile): Array { + const imports: Array = []; + + for (const statement of sourceFile.statements) { + if ( + ts.isImportDeclaration(statement) && + ts.isStringLiteral(statement.moduleSpecifier) && + statement.moduleSpecifier.text === PO_UI_PACKAGE + ) { + imports.push(statement); + } + } + + return imports; +} + +/** Retorna os `NamedImports` de uma declaração, quando existirem. */ +function getNamedImports(decl: ts.ImportDeclaration): ts.NamedImports | undefined { + const bindings = decl.importClause?.namedBindings; + return bindings && ts.isNamedImports(bindings) ? bindings : undefined; +} + +/** + * Gera as edições sobre as declarações de importação, renomeando ou removendo + * (deduplicando) os símbolos gauge, e alimenta o mapa de renomeação de + * referências. + */ +function buildImportEdits( + sourceFile: ts.SourceFile, + gaugeSpecifiers: Array, + allImportedNames: Set, + referenceRenameMap: Map, + edits: Array +): void { + // Alvos já presentes como símbolos importados que NÃO são símbolos gauge. + const gaugeLocalNames = new Set(gaugeSpecifiers.map(info => info.localName)); + const presentTargets = new Set(); + allImportedNames.forEach(name => { + if (!gaugeLocalNames.has(name)) { + presentTargets.add(name); + } + }); + + // Índice: declaração -> símbolos gauge que serão removidos (dedup). + const removedByDecl = new Map>(); + const declSpecifierEdits: Array<{ info: GaugeSpecifierInfo; remove: boolean; target: string }> = []; + + for (const info of gaugeSpecifiers) { + const target = gaugeSymbolMap[info.importedName]; + + if (info.aliased) { + // Import com alias: renomeia apenas o nome importado, preservando o alias + // local. As referências (que usam o alias) permanecem inalteradas. + declSpecifierEdits.push({ info, remove: false, target }); + continue; + } + + // Referências ao símbolo gauge passam a apontar para o equivalente. + referenceRenameMap.set(info.localName, target); + + // Dedup: se o alvo já é importado, remove o símbolo gauge em vez de renomear. + const alreadyPresent = presentTargets.has(target); + + if (alreadyPresent) { + declSpecifierEdits.push({ info, remove: true, target }); + const set = removedByDecl.get(info.decl) ?? new Set(); + set.add(info.specifier); + removedByDecl.set(info.decl, set); + } else { + declSpecifierEdits.push({ info, remove: false, target }); + presentTargets.add(target); + } + } + + // Declarações cujos elementos serão TODOS removidos são apagadas por inteiro. + const fullyRemovedDecls = new Set(); + removedByDecl.forEach((removedSet, decl) => { + const named = getNamedImports(decl); + if (named && named.elements.every(element => removedSet.has(element))) { + fullyRemovedDecls.add(decl); + } + }); + + for (const decl of fullyRemovedDecls) { + edits.push(removeDeclarationEdit(sourceFile, decl)); + } + + for (const { info, remove, target } of declSpecifierEdits) { + if (fullyRemovedDecls.has(info.decl)) { + continue; + } + + if (remove) { + edits.push(removeSpecifierEdit(sourceFile, info.namedImports, info.specifier)); + } else if (info.aliased && info.specifier.propertyName) { + edits.push({ + start: info.specifier.propertyName.getStart(sourceFile), + end: info.specifier.propertyName.getEnd(), + text: target + }); + } else { + edits.push({ + start: info.specifier.name.getStart(sourceFile), + end: info.specifier.name.getEnd(), + text: target + }); + } + } +} + +/** + * Gera as edições sobre as referências dos símbolos gauge no corpo do arquivo + * (fora das declarações de importação), com deduplicação dentro de arrays. + */ +function buildReferenceEdits( + sourceFile: ts.SourceFile, + poUiImports: Array, + referenceRenameMap: Map, + edits: Array +): void { + if (referenceRenameMap.size === 0) { + return; + } + + const importRanges = poUiImports.map(decl => ({ start: decl.getStart(sourceFile), end: decl.getEnd() })); + // Rastreia os alvos já presentes/emitidos por array, para evitar duplicatas + // em listas como `declarations`/`imports`/`exports`. + const emittedTargetsByArray = new Map>(); + + const visit = (node: ts.Node): void => { + if (ts.isIdentifier(node) && referenceRenameMap.has(node.text) && !isWithinRanges(node, sourceFile, importRanges)) { + if (isRenameableReference(node)) { + // O `!` é necessário sob strictNullChecks (build de schematics): a + // condição do `if` acima garante que a chave existe no mapa, mas o + // compilador nao relaciona Map.has() com Map.get(), entao get() ainda + // e `string | undefined`. A regra @typescript-eslint/no-unnecessary- + // type-assertion gera um falso positivo aqui. + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + const target = referenceRenameMap.get(node.text)!; + const array = getContainingArrayElement(node); + + if (array) { + const emitted = emittedTargetsByArray.get(array) ?? collectExistingArrayNames(array, referenceRenameMap); + emittedTargetsByArray.set(array, emitted); + + if (emitted.has(target)) { + // Alvo já presente no array: remove o elemento gauge (dedup). + edits.push(removeArrayElementEdit(sourceFile, array, node)); + return; + } + + emitted.add(target); + } + + edits.push({ start: node.getStart(sourceFile), end: node.getEnd(), text: target }); + } + return; + } + + ts.forEachChild(node, visit); + }; + + visit(sourceFile); +} + +/** Verifica se o identificador é uma referência renomeável (não é chave/propriedade). */ +function isRenameableReference(node: ts.Identifier): boolean { + const parent = node.parent; + + if (!parent) { + return true; + } + + // `obj.PoGaugeModule` — não é referência ao símbolo importado. + if (ts.isPropertyAccessExpression(parent) && parent.name === node) { + return false; + } + + // `{ PoGaugeModule: ... }` — chave de objeto, não é referência. + if (ts.isPropertyAssignment(parent) && parent.name === node) { + return false; + } + + // `PoGaugeModule.prop` como qualificador de tipo. + if (ts.isQualifiedName(parent) && parent.right === node) { + return false; + } + + return true; +} + +/** Retorna o `ArrayLiteralExpression` do qual o nó é elemento direto, se houver. */ +function getContainingArrayElement(node: ts.Node): ts.ArrayLiteralExpression | undefined { + const parent = node.parent; + if (parent && ts.isArrayLiteralExpression(parent) && parent.elements.indexOf(node as ts.Expression) !== -1) { + return parent; + } + return undefined; +} + +/** Coleta os nomes já existentes em um array, mapeando símbolos gauge para seus alvos. */ +function collectExistingArrayNames( + array: ts.ArrayLiteralExpression, + referenceRenameMap: Map +): Set { + const names = new Set(); + + for (const element of array.elements) { + // Nomes que não são gauge já contam como presentes com seu próprio nome. + if (ts.isIdentifier(element) && !referenceRenameMap.has(element.text)) { + names.add(element.text); + } + } + + return names; +} + +/** Indica se um nó está contido em alguma das faixas informadas. */ +function isWithinRanges( + node: ts.Node, + sourceFile: ts.SourceFile, + ranges: Array<{ start: number; end: number }> +): boolean { + const start = node.getStart(sourceFile); + return ranges.some(range => start >= range.start && start < range.end); +} + +/** Cria uma edição que remove um `ImportSpecifier`, cuidando das vírgulas. */ +function removeSpecifierEdit(sourceFile: ts.SourceFile, named: ts.NamedImports, element: ts.ImportSpecifier): TextEdit { + const elements = named.elements; + const index = elements.indexOf(element); + + if (index < elements.length - 1) { + // Remove do início do elemento até o início do próximo (inclui a vírgula). + return { start: element.getStart(sourceFile), end: elements[index + 1].getStart(sourceFile), text: '' }; + } + + // Último elemento: remove do fim do elemento anterior (inclui a vírgula). + return { start: elements[index - 1].getEnd(), end: element.getEnd(), text: '' }; +} + +/** Cria uma edição que remove um elemento de array, cuidando das vírgulas. */ +function removeArrayElementEdit( + sourceFile: ts.SourceFile, + array: ts.ArrayLiteralExpression, + element: ts.Node +): TextEdit { + const elements = array.elements; + const index = elements.indexOf(element as ts.Expression); + + if (index < elements.length - 1) { + return { start: element.getStart(sourceFile), end: elements[index + 1].getStart(sourceFile), text: '' }; + } + + if (index > 0) { + return { start: elements[index - 1].getEnd(), end: element.getEnd(), text: '' }; + } + + // Único elemento do array. + return { start: element.getStart(sourceFile), end: element.getEnd(), text: '' }; +} + +/** Cria uma edição que remove uma `ImportDeclaration` inteira, incluindo a quebra de linha. */ +function removeDeclarationEdit(sourceFile: ts.SourceFile, decl: ts.ImportDeclaration): TextEdit { + const start = decl.getStart(sourceFile); + let end = decl.getEnd(); + + const text = sourceFile.getFullText(); + // Consome uma eventual quebra de linha subsequente para não deixar linha vazia. + if (text[end] === '\r' && text[end + 1] === '\n') { + end += 2; + } else if (text[end] === '\n' || text[end] === '\r') { + end += 1; + } + + return { start, end, text: '' }; +} + +/** Número da linha (1-indexado) em que o nó inicia. */ +function lineOf(sourceFile: ts.SourceFile, node: ts.Node): number { + return sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1; +} + +/** Aplica as edições sobre o conteúdo, do fim para o início, preservando offsets. */ +function applyEdits(source: string, edits: Array): string { + const ordered = [...edits].sort((a, b) => b.start - a.start); + + let result = source; + for (const edit of ordered) { + result = result.slice(0, edit.start) + edit.text + result.slice(edit.end); + } + + return result; +} diff --git a/projects/ui/schematics/ng-update/v22/index.spec.ts b/projects/ui/schematics/ng-update/v22/index.spec.ts new file mode 100644 index 0000000000..32d6c09753 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/index.spec.ts @@ -0,0 +1,660 @@ +import * as fc from 'fast-check'; +import * as path from 'path'; + +import { logging } from '@angular-devkit/core'; +import { SchematicContext, Tree } from '@angular-devkit/schematics'; +import { SchematicTestRunner } from '@angular-devkit/schematics/testing'; + +import { migrateHtmlContent } from './gauge-html-migration'; +import { migrateTypeScriptContent } from './gauge-ts-migration'; +import { gaugeMigrationRule, getAngularMajor } from './index'; + +/** + * Testes de propriedade para a **escrita condicional** (`Propriedade 3`) da regra + * de orquestração `gaugeMigrationRule`. + * + * A regra só deve gravar (`tree.overwrite`) um arquivo quando o conteúdo + * transformado difere do original (Req. 2.8, 4.6, 7.3). Consequentemente, quando + * o conteúdo migrado de um arquivo é idêntico ao original — por exemplo, um + * arquivo sem qualquer `Uso_Template`/`Uso_TypeScript` do `po-gauge`, ou um + * arquivo já migrado (`po-chart` com `p-type="gauge"` / símbolos do `po-chart`) — + * o arquivo NÃO deve ser sobrescrito e seu conteúdo deve permanecer idêntico + * byte a byte. + * + * Abordagem: teste em nível de regra. Constrói-se um `Tree` em memória com um + * `angular.json` mínimo (workspace + projeto `application` com `sourceRoot` e + * `browser`/main), um `main.ts` standalone (para `getProjectMainFile` / + * `isStandaloneApp`) e arquivos gerados sob o diretório-fonte do projeto cujo + * conteúdo migrado é idêntico ao original. Após aplicar `gaugeMigrationRule()`, + * verifica-se que: + * - o conteúdo de cada arquivo permanece idêntico byte a byte (invariante + * observável da escrita condicional); + * - `tree.overwrite` não foi chamado para esses arquivos (nenhuma escrita). + * + * O espaço de entrada "sem mudança" é garantido por uma pré-condição + * (`fc.pre`) que usa as próprias transformações puras: um arquivo só participa + * do teste quando `migrate(x).changed === false && migrate(x).content === x` — + * que é exatamente a condição sob a qual `scanDirectory` pula a escrita. + */ + +/** `angular.json` mínimo: um projeto `application` com `sourceRoot` e main file. */ +const ANGULAR_JSON = { + version: 1, + projects: { + demo: { + projectType: 'application', + root: '', + sourceRoot: 'src', + architect: { + build: { + builder: '@angular/build:application', + options: { + browser: 'src/main.ts' + } + } + } + } + } +}; + +/** `main.ts` standalone válido para `getProjectMainFile`/`isStandaloneApp`. */ +const MAIN_TS = [ + `import { bootstrapApplication } from '@angular/platform-browser';`, + `import { AppComponent } from './app/app.component';`, + ``, + `bootstrapApplication(AppComponent).catch(err => console.error(err));`, + `` +].join('\n'); + +/** Constrói um `Tree` em memória com o workspace mínimo e os arquivos gerados. */ +function buildTree(files: Array<{ path: string; content: string }>): Tree { + const tree = Tree.empty(); + tree.create('/angular.json', JSON.stringify(ANGULAR_JSON, null, 2)); + tree.create('/src/main.ts', MAIN_TS); + + for (const file of files) { + tree.create(file.path, file.content); + } + + return tree; +} + +/** Contexto mínimo: a regra só depende de `context.logger`. */ +function createContext(): SchematicContext { + return { logger: new logging.NullLogger() } as unknown as SchematicContext; +} + +/** Executa a regra de forma síncrona sobre o `tree` informado. */ +function runRule(tree: Tree): void { + const rule = gaugeMigrationRule() as (tree: Tree, context: SchematicContext) => Tree; + rule(tree, createContext()); +} + +/** + * Trechos de HTML seguros: marcação genérica e elementos já migrados + * (`po-chart` com `p-type="gauge"`). Nenhum contém o seletor de abertura + * ` = fc.constantFrom( + '
    ', + '

    texto

    ', + '', + 'conteúdo', + '', + '', + '', + '\n', + ' ' +); + +/** Documento HTML cujo conteúdo migrado é idêntico ao original (no-op). */ +const noChangeHtmlArb: fc.Arbitrary = fc + .array(safeHtmlPartArb, { minLength: 0, maxLength: 8 }) + .map(parts => parts.join('')); + +/** + * Trechos de TypeScript seguros: imports de símbolos não-gauge, símbolos já + * migrados (`PoChartModule`) e código comum. Nenhum importa símbolos gauge, + * portanto a migração não altera o conteúdo. + */ +const safeTsPartArb: fc.Arbitrary = fc.constantFrom( + `import { Component } from '@angular/core';\n`, + `import { CommonModule } from '@angular/common';\n`, + `import { PoButtonModule, PoTableModule } from '@po-ui/ng-components';\n`, + `import { PoChartModule } from '@po-ui/ng-components';\n`, + `export class FooComponent {}\n`, + `const total = 42;\n`, + `// comentário existente\n` +); + +/** Arquivo TypeScript cujo conteúdo migrado é idêntico ao original (no-op). */ +const noChangeTsArb: fc.Arbitrary = fc + .array(safeTsPartArb, { minLength: 0, maxLength: 6 }) + .map(parts => parts.join('')); + +/** Especificação de um arquivo gerado: tipo (html/ts) e conteúdo. */ +type FileSpecKind = 'html' | 'ts'; +interface FileSpec { + kind: FileSpecKind; + content: string; +} + +/** Gera a especificação de um arquivo no-change (html ou ts). */ +const fileSpecArb: fc.Arbitrary = fc.oneof( + noChangeHtmlArb.map(content => ({ kind: 'html' as const, content })), + noChangeTsArb.map(content => ({ kind: 'ts' as const, content })) +); + +describe('v22 gaugeMigrationRule — escrita condicional (property-based):', () => { + /** + * Propriedade 3 — Escrita condicional. + * + * Para qualquer conjunto de arquivos `.html`/`.ts` cujo conteúdo migrado é + * idêntico ao original (garantido pela pré-condição via transformações puras), + * após aplicar `gaugeMigrationRule()`: + * - nenhuma operação de escrita (`tree.overwrite`) ocorre para esses arquivos; + * - o conteúdo de cada arquivo permanece idêntico byte a byte ao original. + * + * **Validates: Requirements 2.8, 4.6, 7.3** + * **Valida: Requisitos 2.8, 4.6, 7.3** + */ + it('should not overwrite files whose migrated content equals the original (Prop 3, Req 2.8, 4.6, 7.3)', () => { + fc.assert( + fc.property(fc.array(fileSpecArb, { minLength: 1, maxLength: 5 }), specs => { + const files = specs.map((spec, index) => ({ + path: `/src/app/generated-${index}.${spec.kind === 'html' ? 'html' : 'ts'}`, + content: spec.content, + kind: spec.kind + })); + + // Pré-condição: cada arquivo é um caso genuíno de "sem mudança". + // (mesma condição sob a qual `scanDirectory` pula a escrita). + for (const file of files) { + const result = + file.kind === 'html' ? migrateHtmlContent(file.content) : migrateTypeScriptContent(file.content, true); + fc.pre(result.changed === false && result.content === file.content); + } + + const tree = buildTree(files); + const overwriteSpy = spyOn(tree, 'overwrite').and.callThrough(); + + runRule(tree); + + for (const file of files) { + // Invariante da escrita condicional: conteúdo idêntico byte a byte. + const after = tree.read(file.path); + expect(after).not.toBeNull(); + expect(after!.toString('utf-8')).toBe(file.content); + + // Nenhuma escrita ocorreu para este arquivo (Prop 3). + const overwroteThisFile = overwriteSpy.calls.allArgs().some(args => args[0] === file.path); + expect(overwroteThisFile).toBe(false); + } + }), + { numRuns: 100 } + ); + }); + + /** + * Exemplo determinístico (mesma invariante da Propriedade 3): um arquivo HTML + * sem `po-gauge` combinado com um arquivo já migrado (`po-chart`) e um arquivo + * TypeScript sem símbolos gauge não sofrem escrita e permanecem idênticos. + */ + it('should leave no-op html/ts files byte-for-byte identical and never call overwrite (Prop 3, Req 2.8, 4.6, 7.3)', () => { + const htmlNoGauge = '
    \n

    Sem gauge aqui

    \n
    \n'; + const htmlAlreadyMigrated = '\n'; + const tsNoGauge = + `import { Component } from '@angular/core';\n` + + `import { PoButtonModule } from '@po-ui/ng-components';\n\n` + + `@Component({ selector: 'app-x', imports: [PoButtonModule], template: '' })\n` + + `export class XComponent {}\n`; + + const files = [ + { path: '/src/app/no-gauge.html', content: htmlNoGauge }, + { path: '/src/app/already-migrated.html', content: htmlAlreadyMigrated }, + { path: '/src/app/no-gauge.component.ts', content: tsNoGauge } + ]; + + const tree = buildTree(files); + const overwriteSpy = spyOn(tree, 'overwrite').and.callThrough(); + + runRule(tree); + + for (const file of files) { + expect(tree.read(file.path)!.toString('utf-8')).toBe(file.content); + } + + expect(overwriteSpy).not.toHaveBeenCalled(); + }); +}); + +/** + * Testes de integração da `chain` do `migration-v22` (task 8.2). + * + * Abordagem escolhida: **nível de regra/chain com `SchematicTestRunner.callRule`** + * sobre um `Tree` em memória, em vez de `runner.runSchematic('migration-v22', ...)`. + * + * Justificativa: + * - O factory exportado por `./index` compõe a `chain` real (`updatePackageJson` + * → `gaugeMigrationRule` → `postUpdate`) e é a mesma `Rule` executada pelo + * Angular CLI durante `ng update`. Invocá-lo diretamente e rodá-lo com + * `runner.callRule(...)` exercita exatamente essa cadeia (ordem das regras, + * propagação de falha e agendamento de tarefas), sem depender de artefatos + * compilados/registro de collection resolvíveis em tempo de teste — que são + * frágeis quando o schematic é validado isoladamente. + * - `runner.tasks` reflete as tarefas agendadas via `context.addTask` durante a + * execução da `chain`, permitindo verificar o agendamento de exatamente um + * `NodePackageInstallTask` (nome de tarefa `node-package`). + * - O `Tree` em memória (mesmo `angular.json`/`main.ts` já usados nos testes de + * propriedade acima) permite montar um `package.json` com versão antiga e + * arquivos de projeto com `po-gauge`, verificando as transformações aplicadas. + */ +describe('v22 migration-v22 chain — integração (SchematicTestRunner.callRule):', () => { + /** Caminho do `migrations.json` (relativo ao diretório compilado deste spec). */ + const collectionPath = path.join(__dirname, '../../migrations.json'); + + /** Versão "antiga" do `@po-ui/ng-components` antes da migração de versões. */ + const OLD_PO_VERSION = '19.16.0'; + + /** `package.json` mínimo com a dependência do PO UI em versão antiga (Req 8.1). */ + const PACKAGE_JSON = { + name: 'consumer-app', + version: '0.0.0', + dependencies: { + '@angular/core': '^22.0.0', + '@po-ui/ng-components': OLD_PO_VERSION + }, + devDependencies: { + typescript: '~5.9.0' + } + }; + + /** Componente standalone com uso de `po-gauge` em TypeScript (Req 8.2). */ + const APP_COMPONENT_TS = [ + `import { Component } from '@angular/core';`, + `import { PoGaugeModule } from '@po-ui/ng-components';`, + ``, + `@Component({`, + ` selector: 'app-root',`, + ` standalone: true,`, + ` imports: [PoGaugeModule],`, + ` template: ''`, + `})`, + `export class AppComponent {}`, + `` + ].join('\n'); + + /** Template com uso de `` (Req 8.2). */ + const APP_COMPONENT_HTML = `\n`; + + /** Monta um `Tree` completo: workspace, main, package.json e arquivos do projeto. */ + function buildIntegrationTree(pkgJsonContent?: string): Tree { + const tree = Tree.empty(); + tree.create('/angular.json', JSON.stringify(ANGULAR_JSON, null, 2)); + tree.create('/src/main.ts', MAIN_TS); + tree.create('/package.json', pkgJsonContent ?? JSON.stringify(PACKAGE_JSON, null, 2)); + tree.create('/src/app/app.component.ts', APP_COMPONENT_TS); + tree.create('/src/app/app.component.html', APP_COMPONENT_HTML); + + return tree; + } + + /** Executa a `chain` real do factory sobre o `tree` e devolve o runner (para `tasks`). */ + async function runChain(tree: Tree): Promise { + const runner = new SchematicTestRunner('schematics', collectionPath); + await runner.runSchematic('migration-v22', {}, tree); + return runner; + } + + /** Conta as tarefas `NodePackageInstallTask` agendadas (nome `node-package`). */ + function countInstallTasks(runner: SchematicTestRunner): number { + return runner.tasks.filter(task => task.name === 'node-package').length; + } + + /** + * Ordem e efeitos da `chain` no caminho de sucesso (Req 8.1, 8.2, 8.3). + * + * Após executar a migração confirmada: + * - as versões de dependências do `package.json` são atualizadas (Req 8.1); + * - a transformação `po-gauge` → `po-chart` é aplicada em HTML e TS (Req 8.2); + * - exatamente um `NodePackageInstallTask` é agendado (Req 8.3). + * + * **Validates: Requirements 8.1, 8.2, 8.3** + */ + it('should update package.json versions, transform gauge usages and schedule exactly one install task (Req 8.1, 8.2, 8.3)', async () => { + const tree = buildIntegrationTree(); + + const runner = await runChain(tree); + + // Req 8.1 — versão da dependência do PO UI atualizada (deixou de ser a antiga). + const pkg = JSON.parse(tree.read('/package.json')!.toString('utf-8')); + expect(pkg.dependencies['@po-ui/ng-components']).toBeDefined(); + expect(pkg.dependencies['@po-ui/ng-components']).not.toBe(OLD_PO_VERSION); + + // Req 8.2 — transformação aplicada no template HTML. + const html = tree.read('/src/app/app.component.html')!.toString('utf-8'); + expect(html).toContain(' { + const tree = buildIntegrationTree(); + + const runner = await runChain(tree); + + const pkg = JSON.parse(tree.read('/package.json')!.toString('utf-8')); + const html = tree.read('/src/app/app.component.html')!.toString('utf-8'); + const ts = tree.read('/src/app/app.component.ts')!.toString('utf-8'); + + const versionsUpdated = pkg.dependencies['@po-ui/ng-components'] !== OLD_PO_VERSION; + const codeMigrated = html.includes(' { + const tree = buildIntegrationTree('{ this is not valid json'); + + const runner = new SchematicTestRunner('schematics', collectionPath); + + // A falha da regra propaga-se pela chain (runSchematic rejeita). + let rejected = false; + try { + await runner.runSchematic('migration-v22', {}, tree); + } catch { + rejected = true; + } + expect(rejected).toBe(true); + + // Req 8.4 — nenhuma tarefa de instalação foi agendada. + expect(countInstallTasks(runner)).toBe(0); + }); + + /** + * Pré-requisito de versão do Angular: quando o `package.json` do projeto + * declara um Angular anterior ao mínimo exigido (major < 22), a migração + * aborta de forma determinística — sem transformar arquivos, sem alterar + * versões e sem agendar tarefa de instalação. + * + * Substitui a antiga confirmação interativa (prompt via readline) por uma + * checagem baseada no `@angular/core` declarado no `package.json`. + */ + it('should abort without changes when the declared Angular is older than the required major', async () => { + const outdatedPackageJson = JSON.stringify( + { + name: 'consumer-app', + version: '0.0.0', + dependencies: { + '@angular/core': '^21.0.0', + '@po-ui/ng-components': OLD_PO_VERSION + }, + devDependencies: { typescript: '~5.9.0' } + }, + null, + 2 + ); + + const tree = buildIntegrationTree(outdatedPackageJson); + + const runner = await runChain(tree); + + // Nenhuma transformação: arquivos idênticos ao original. + expect(tree.read('/src/app/app.component.html')!.toString('utf-8')).toBe(APP_COMPONENT_HTML); + expect(tree.read('/src/app/app.component.ts')!.toString('utf-8')).toBe(APP_COMPONENT_TS); + + // package.json inalterado (versão antiga do PO UI preservada). + const pkg = JSON.parse(tree.read('/package.json')!.toString('utf-8')); + expect(pkg.dependencies['@po-ui/ng-components']).toBe(OLD_PO_VERSION); + + // Nenhuma tarefa de instalação agendada. + expect(countInstallTasks(runner)).toBe(0); + }); +}); + +/** + * Testes de integração de **idempotência multi-execução** (task 8.3). + * + * Verifica que o resultado da migração é um ponto fixo: a partir da segunda + * execução sobre o mesmo `Tree`, o conteúdo de todos os arquivos permanece + * idêntico byte a byte ao resultado da primeira execução e a migração reporta + * "nenhuma ocorrência" (Req. 9.4). + * + * Usa `fast-check` com `fc.integer({min: 2, max: 10})` para variar o número + * de re-execuções, exercitando a propriedade de ponto fixo para diferentes + * quantidades de iterações. + * + * **Validates: Requirements 7.1, 7.2, 9.4** + */ +describe('v22 migration-v22 chain — idempotência multi-execução (property-based):', () => { + const collectionPath = path.join(__dirname, '../../migrations.json'); + + const OLD_PO_VERSION = '19.16.0'; + + const PACKAGE_JSON = { + name: 'consumer-app', + version: '0.0.0', + dependencies: { + '@angular/core': '^22.0.0', + '@po-ui/ng-components': OLD_PO_VERSION + }, + devDependencies: { + typescript: '~5.9.0' + } + }; + + /** Componente standalone com uso de `po-gauge` em TypeScript. */ + const APP_COMPONENT_TS = [ + `import { Component } from '@angular/core';`, + `import { PoGaugeModule } from '@po-ui/ng-components';`, + ``, + `@Component({`, + ` selector: 'app-root',`, + ` standalone: true,`, + ` imports: [PoGaugeModule],`, + ` template: ''`, + `})`, + `export class AppComponent {}`, + `` + ].join('\n'); + + /** Template com uso de ``. */ + const APP_COMPONENT_HTML = `\n`; + + /** Monta um `Tree` completo com usos de `po-gauge`. */ + function buildIdempotencyTree(): Tree { + const tree = Tree.empty(); + tree.create('/angular.json', JSON.stringify(ANGULAR_JSON, null, 2)); + tree.create('/src/main.ts', MAIN_TS); + tree.create('/package.json', JSON.stringify(PACKAGE_JSON, null, 2)); + tree.create('/src/app/app.component.ts', APP_COMPONENT_TS); + tree.create('/src/app/app.component.html', APP_COMPONENT_HTML); + return tree; + } + + /** Executa a `chain` real do factory sobre o `tree`. */ + async function runMigration(tree: Tree): Promise { + const runner = new SchematicTestRunner('schematics', collectionPath); + await runner.runSchematic('migration-v22', {}, tree); + } + + /** Captura o conteúdo de todos os arquivos do `Tree` como mapa `path → content`. */ + function captureTreeContents(tree: Tree): Map { + const contents = new Map(); + tree.visit(filePath => { + const buffer = tree.read(filePath); + if (buffer) { + contents.set(filePath, buffer.toString('utf-8')); + } + }); + return contents; + } + + let originalIsTTY: boolean | undefined; + + beforeEach(() => { + originalIsTTY = process.stdin.isTTY; + (process.stdin as unknown as { isTTY?: boolean }).isTTY = false; + }); + + afterEach(() => { + (process.stdin as unknown as { isTTY?: boolean }).isTTY = originalIsTTY; + }); + + /** + * Propriedade: idempotência (ponto fixo) — multi-execução da chain completa. + * + * Dado um `Tree` com usos de `po-gauge`, após a primeira execução da migração + * o resultado é um ponto fixo: N execuções adicionais (2 ≤ N ≤ 10) produzem + * conteúdo idêntico byte a byte ao resultado da primeira execução. + * + * **Validates: Requirements 7.1, 7.2** + */ + it('should produce byte-for-byte identical content from the second execution onwards (Prop 1, Req 7.1, 7.2)', async () => { + await fc.assert( + fc.asyncProperty(fc.integer({ min: 2, max: 10 }), async (n: number) => { + const tree = buildIdempotencyTree(); + + // Primeira execução: transforma gauge → chart. + await runMigration(tree); + + // Captura o estado após a primeira execução (ponto fixo esperado). + const firstRunContents = captureTreeContents(tree); + + // Re-execuções adicionais (N vezes): conteúdo deve permanecer idêntico. + for (let i = 2; i <= n; i++) { + await runMigration(tree); + + const currentContents = captureTreeContents(tree); + + // Verificar que o conjunto de arquivos não mudou. + expect(currentContents.size).toBe(firstRunContents.size); + + // Verificar conteúdo idêntico byte a byte para cada arquivo. + for (const [filePath, expectedContent] of firstRunContents) { + const actualContent = currentContents.get(filePath); + expect(actualContent).toBe(expectedContent); + } + } + }), + { numRuns: 5 } + ); + }); + + /** + * Verificação do log "nenhuma ocorrência" em re-execuções (Req. 9.4). + * + * Após a primeira execução ter transformado todos os usos, execuções + * subsequentes devem detectar que não há mais `po-gauge` e registrar + * a mensagem "Nenhuma ocorrência do po-gauge foi encontrada no workspace". + * + * **Validates: Requirement 9.4** + */ + it('should log "nenhuma ocorrência" on subsequent executions when no gauge usages remain (Req 9.4)', async () => { + const tree = buildIdempotencyTree(); + + // Primeira execução: transforma gauge → chart. + await runMigration(tree); + + // Segunda execução capturando os logs do runner. + const runner = new SchematicTestRunner('schematics', collectionPath); + const infoMessages: Array = []; + runner.logger.subscribe(entry => { + if (entry.level === 'info') { + infoMessages.push(entry.message); + } + }); + + await runner.runSchematic('migration-v22', {}, tree); + + // Req. 9.4 — a mensagem "nenhuma ocorrência" deve ter sido registrada. + const noOccurrenceMessage = infoMessages.find(msg => + msg.includes('Nenhuma ocorrência do po-gauge foi encontrada no workspace') + ); + expect(noOccurrenceMessage).toBeDefined(); + }); +}); + +/** + * Testes unitários de `getAngularMajor`. + * + * A função extrai o `major` do range declarado para `@angular/core` no + * `package.json`, priorizando `dependencies` sobre `devDependencies`, e devolve + * `null` em todos os cenários que impedem inferir o major com segurança + * (arquivo ausente, JSON inválido, dependência ausente ou range sem número). + */ +describe('v22 getAngularMajor:', () => { + /** Monta um `Tree` com um `package.json` de conteúdo arbitrário. */ + function treeWithPackageJson(content: string): Tree { + const tree = Tree.empty(); + tree.create('/package.json', content); + return tree; + } + + it('should extract the major from a caret range in dependencies', () => { + const tree = treeWithPackageJson(JSON.stringify({ dependencies: { '@angular/core': '^22.1.3' } })); + expect(getAngularMajor(tree)).toBe(22); + }); + + it('should extract the major from a tilde range', () => { + const tree = treeWithPackageJson(JSON.stringify({ dependencies: { '@angular/core': '~21.0.0' } })); + expect(getAngularMajor(tree)).toBe(21); + }); + + it('should extract the major from an exact version', () => { + const tree = treeWithPackageJson(JSON.stringify({ dependencies: { '@angular/core': '20.2.0' } })); + expect(getAngularMajor(tree)).toBe(20); + }); + + it('should fall back to devDependencies when not present in dependencies', () => { + const tree = treeWithPackageJson(JSON.stringify({ devDependencies: { '@angular/core': '^22.0.0' } })); + expect(getAngularMajor(tree)).toBe(22); + }); + + it('should return null when package.json does not exist', () => { + expect(getAngularMajor(Tree.empty())).toBeNull(); + }); + + it('should return null when the JSON is invalid', () => { + const tree = treeWithPackageJson('{ not valid json'); + expect(getAngularMajor(tree)).toBeNull(); + }); + + it('should return null when @angular/core is not declared', () => { + const tree = treeWithPackageJson(JSON.stringify({ dependencies: { '@po-ui/ng-components': '^22.0.0' } })); + expect(getAngularMajor(tree)).toBeNull(); + }); + + it('should return null when the range has no inferable major (e.g. "latest")', () => { + const tree = treeWithPackageJson(JSON.stringify({ dependencies: { '@angular/core': 'latest' } })); + expect(getAngularMajor(tree)).toBeNull(); + }); +}); diff --git a/projects/ui/schematics/ng-update/v22/index.ts b/projects/ui/schematics/ng-update/v22/index.ts new file mode 100644 index 0000000000..d47a92a4da --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/index.ts @@ -0,0 +1,328 @@ +import { chain, Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; +import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; + +import { logging } from '@angular-devkit/core'; + +import { updatePackageJson } from '@po-ui/ng-schematics/package-config'; +import { + getProjectFromWorkspace, + getProjectMainFile, + getWorkspaceConfigGracefully +} from '@po-ui/ng-schematics/project'; + +import { isStandaloneApp } from '@schematics/angular/utility/ng-ast-utils'; +import { WorkspaceSchema } from '@schematics/angular/utility/workspace-models'; + +import { updateDepedenciesVersion } from './changes'; +import { migrateHtmlContent } from './gauge-html-migration'; +import { migrateTypeScriptContent } from './gauge-ts-migration'; +import { createMigrationReport, MigrationReport, MigrationWarning, printMigrationSummary } from './migration-report'; + +/** Versão mínima do Angular exigida pela v22 do `@po-ui/ng-components`. */ +const MINIMUM_ANGULAR_MAJOR = 22; + +/** + * Extrai o `major` declarado para o `@angular/core` no `package.json` do + * `Projeto_Consumidor`. + * + * Retorna `null` quando o `package.json` não existe, não é um JSON válido, a + * dependência não está declarada ou o range não permite inferir um `major` + * (por exemplo `*`, `latest` ou um caminho `file:`). Nesses casos a migração + * prossegue, para não bloquear cenários legítimos como monorepos que resolvem + * o Angular por outro meio. + */ +export function getAngularMajor(tree: Tree): number | null { + const buffer = tree.read('package.json'); + + if (!buffer) { + return null; + } + + try { + const json = JSON.parse(buffer.toString('utf-8')); + const range: string | undefined = json?.dependencies?.['@angular/core'] ?? json?.devDependencies?.['@angular/core']; + + if (!range) { + return null; + } + + const match = /(\d+)\./.exec(range); + + return match ? Number(match[1]) : null; + } catch { + return null; + } +} + +/** + * Ponto de entrada da `migration-v22`. + * + * Não realiza perguntas interativas: `readline` dentro do `ng update` provoca + * deadlock quando o `stdin` é um TTY. Em vez de perguntar, a checagem do + * pré-requisito do Angular é feita de forma determinística a partir do + * `package.json` do `Projeto_Consumidor`. + */ +export default function (): Rule { + return (tree: Tree, context: SchematicContext) => { + const logger = context.logger; + const angularMajor = getAngularMajor(tree); + + if (angularMajor !== null && angularMajor < MINIMUM_ANGULAR_MAJOR) { + logger.error( + `A v22 do @po-ui/ng-components exige o Angular ${MINIMUM_ANGULAR_MAJOR}, mas o projeto declara ` + + `o Angular ${angularMajor}. Nenhum arquivo foi alterado.\n` + + `Atualize o Angular primeiro:\n` + + ` ng update @angular/core@${MINIMUM_ANGULAR_MAJOR} @angular/cli@${MINIMUM_ANGULAR_MAJOR}\n` + + `Consulte o guia oficial: https://angular.dev/update-guide` + ); + + return tree; + } + + return chain([ + updatePackageJson('0.0.0-PLACEHOLDER', updateDepedenciesVersion), // Req 8.1 + gaugeMigrationRule(), // Req 8.2 (após versões, antes da instalação) + postUpdate() // Req 8.3 (NodePackageInstallTask) + ]); + }; +} + +/** + * Regra adicionada à `chain` do `migration-v22` responsável por localizar e + * transformar os usos do componente removido `po-gauge` para `po-chart` com + * `p-type="gauge"`. + * + * Comportamento (Req. 1.1, 1.2, 1.3, 1.4): + * - Obtém a configuração do workspace via `getWorkspaceConfigGracefully`. + * - Se a configuração não pôde ser obtida, registra erro e encerra sem alterar + * nenhum arquivo. + * - Se não há nenhum projeto definido, registra aviso e encerra sem alterar + * nenhum arquivo. + * - Caso contrário, itera por todos os `Projeto_Consumidor`, delegando a + * migração de cada projeto para `migrateProject`, e ao final apresenta o + * `Resumo_Migracao` (Req. 6.4, 9.1). + * + * Observação: a composição desta regra na `chain` é realizada na task 8.1. + */ +export function gaugeMigrationRule(): Rule { + return (tree: Tree, context: SchematicContext) => { + const logger = context.logger; + const workspace = getWorkspaceConfigGracefully(tree); + + if (!workspace) { + // Req. 1.2 — falha ao obter a configuração do workspace + logger.error('Não foi possível obter a configuração do workspace. Nenhum arquivo foi alterado.'); + return tree; + } + + const projectNames = Object.keys(workspace.projects ?? {}); + + if (projectNames.length === 0) { + // Req. 1.3 — nenhum projeto definido no workspace + logger.info('Nenhum projeto encontrado no workspace. Nenhum arquivo foi alterado.'); + return tree; + } + + const report = createMigrationReport(); + + // Req. 1.4 — itera por todos os projetos do workspace + for (const projectName of projectNames) { + migrateProject(tree, workspace, projectName, report, logger); + } + + // Req. 6.4 / 9.1 — apresenta o Resumo_Migracao ao final da execução + printMigrationSummary(report, logger); + + return tree; + }; +} + +/** + * Contexto de um `Projeto_Consumidor` propagado para a varredura de arquivos. + * Reúne os dados de projeto já resolvidos (tipo, diretório-fonte e arquitetura) + * para que `scanDirectory` e as transformações não precisem recalculá-los. + */ +interface ProjectContext { + /** Nome do projeto no workspace. */ + projectName: string; + /** Tipo do projeto conforme o `angular.json`. */ + projectType: 'application' | 'library'; + /** Diretório-fonte base: `${sourceRoot}/${app|lib}`. */ + sourceDir: string; + /** `true` quando o projeto é uma aplicação standalone. */ + isStandalone: boolean; +} + +/** + * Migração por projeto (`Projeto_Consumidor`). + * + * Comportamento (Req. 1.6, 1.7, 1.8, 5.4, 5.5, 5.6): + * - Resolve a pasta de entrada (`lib` para `library`, `app` para `application`) + * e monta `sourceDir = ${sourceRoot}/${entryFolder}`, seguindo o mesmo padrão + * de `v20`/`v21`. + * - Se o diretório-fonte não existe ou está vazio, registra aviso identificando + * o projeto e prossegue para o próximo, sem encerrar a execução (Req. 1.6). + * - Resolve o `mainFile` via `getProjectMainFile` e determina a arquitetura com + * `isStandaloneApp` (Req. 5.4). Se o `mainFile` não pode ser localizado/lido, + * interrompe a migração deste projeto com erro (Req. 5.5). Se a arquitetura + * não pode ser determinada, idem, com mensagem específica (Req. 5.6). Em + * ambos os casos os arquivos do projeto permanecem inalterados. + * - Dispara a varredura recursiva (`scanDirectory`). + */ +function migrateProject( + tree: Tree, + workspace: WorkspaceSchema, + projectName: string, + report: MigrationReport, + logger: logging.LoggerApi +): void { + const project = getProjectFromWorkspace(workspace, projectName); + + if (!project) { + return; + } + + // Req. 1.7 / 1.8 — pasta de entrada conforme o tipo do projeto. + const projectType: 'application' | 'library' = project.projectType === 'library' ? 'library' : 'application'; + const entryFolder = projectType === 'library' ? 'lib' : 'app'; + const sourceDir = `${project.sourceRoot}/${entryFolder}`; + + // Req. 1.6 — diretório-fonte inexistente ou vazio: avisa e segue adiante. + const directory = tree.getDir(sourceDir); + if (directory.subfiles.length === 0 && directory.subdirs.length === 0) { + logger.warn( + `[po-gauge] Projeto "${projectName}": o diretório-fonte "${sourceDir}" não existe ou está vazio. ` + + `Nenhum arquivo foi alterado neste projeto.` + ); + return; + } + + // Req. 5.4 / 5.5 — localizar o arquivo de entrada principal (main). + let mainFile: string; + try { + mainFile = getProjectMainFile(project); + } catch (error) { + logger.error( + `[po-gauge] Projeto "${projectName}": não foi possível localizar o arquivo de entrada principal ` + + `(main) a partir do angular.json. Nenhum arquivo foi alterado neste projeto. ` + + `Detalhe: ${(error as Error)?.message ?? error}` + ); + return; + } + + if (!mainFile || !tree.exists(mainFile)) { + logger.error( + `[po-gauge] Projeto "${projectName}": o arquivo de entrada principal (main) não foi encontrado ou ` + + `não pôde ser lido. Nenhum arquivo foi alterado neste projeto.` + ); + return; + } + + // Req. 5.4 / 5.6 — determinar a arquitetura (NgModule x standalone). + let isStandalone: boolean; + try { + isStandalone = isStandaloneApp(tree, mainFile); + } catch (error) { + logger.error( + `[po-gauge] Projeto "${projectName}": não foi possível determinar a arquitetura do projeto ` + + `(NgModule ou standalone) a partir de "${mainFile}". Nenhum arquivo foi alterado neste projeto. ` + + `Detalhe: ${(error as Error)?.message ?? error}` + ); + return; + } + + const ctx: ProjectContext = { + projectName, + projectType, + sourceDir, + isStandalone + }; + + // Dispara a varredura recursiva dos arquivos `.html`/`.ts` do projeto. + scanDirectory(tree, sourceDir, ctx, report, logger); +} + +/** + * Varredura recursiva do diretório-fonte de um `Projeto_Consumidor`. + * + * Comportamento (Req. 1.4, 1.5, 2.8, 4.6, 7.3, 7.5, 9.1): + * - Percorre recursivamente todos os subdiretórios sem limite de profundidade, + * reaproveitando o padrão de `v20`/`v21` (`tree.getDir(...)` com + * `subfiles`/`subdirs`) (Req. 1.4). + * - Processa apenas arquivos com extensão `.html` ou `.ts` (comparação + * case-insensitive); demais arquivos são ignorados sem alteração (Req. 1.5). + * - Para cada arquivo processado incrementa `report.filesScanned`, lê o + * conteúdo via `tree.read` e delega às transformações puras + * (`migrateHtmlContent` para `.html`, `migrateTypeScriptContent` para `.ts`). + * - Preenche o campo `filePath` das advertências com o caminho relativo do + * arquivo (as funções puras o deixam vazio) e as acumula em `report.warnings` + * (Req. 9.1). + * - Escreve com `tree.overwrite` somente quando o conteúdo transformado difere + * do original (Req. 2.8, 4.6, 7.3), incrementando `report.filesChanged`. + * - Em caso de exceção na escrita, preserva o arquivo original (sem aplicar + * alterações parciais) e registra erro identificando o arquivo, sem + * incrementar `report.filesChanged` (Req. 7.5). + */ +function scanDirectory( + tree: Tree, + dirPath: string, + ctx: ProjectContext, + report: MigrationReport, + logger: logging.LoggerApi +): void { + const directory = tree.getDir(dirPath); + + // Req. 1.5 — processa apenas arquivos `.html`/`.ts` (case-insensitive). + directory.subfiles.forEach((file: string) => { + const lowerName = file.toLowerCase(); + const isHtml = lowerName.endsWith('.html'); + const isTs = lowerName.endsWith('.ts'); + + if (!isHtml && !isTs) { + return; + } + + const filePath = `${directory.path}/${file}`; + const buffer = tree.read(filePath); + if (!buffer) { + return; + } + + const original = buffer.toString('utf-8'); + + // Req. 9.1 — contabiliza cada arquivo `.html`/`.ts` analisado. + report.filesScanned++; + + const result = isHtml ? migrateHtmlContent(original) : migrateTypeScriptContent(original, ctx.isStandalone); + + // Preenche o `filePath` (deixado vazio pelas funções puras) e acumula. + result.warnings.forEach((warning: MigrationWarning) => { + report.warnings.push({ ...warning, filePath }); + }); + + // Req. 2.8 / 4.6 / 7.3 — escreve somente quando o conteúdo efetivamente mudou. + if (result.content !== original) { + try { + tree.overwrite(filePath, result.content); + report.filesChanged++; + } catch (error) { + // Req. 7.5 — falha na escrita: preserva o original e registra o erro. + logger.error( + `[po-gauge] Falha ao gravar o arquivo "${filePath}". O conteúdo original foi preservado ` + + `(nenhuma alteração parcial foi aplicada). Detalhe: ${(error as Error)?.message ?? error}` + ); + } + } + }); + + // Req. 1.4 — varredura recursiva dos subdiretórios, sem limite de profundidade. + directory.subdirs.forEach((subdir: string) => { + scanDirectory(tree, `${directory.path}/${subdir}`, ctx, report, logger); + }); +} + +function postUpdate() { + return (_: Tree, context: SchematicContext) => { + context.addTask(new NodePackageInstallTask()); + }; +} diff --git a/projects/ui/schematics/ng-update/v22/migration-report.spec.ts b/projects/ui/schematics/ng-update/v22/migration-report.spec.ts new file mode 100644 index 0000000000..ec44d6dcc1 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/migration-report.spec.ts @@ -0,0 +1,152 @@ +import { logging } from '@angular-devkit/core'; + +import { createMigrationReport, MigrationReport, printMigrationSummary } from './migration-report'; + +describe('v22 migration-report:', () => { + let logger: jasmine.SpyObj; + + beforeEach(() => { + logger = jasmine.createSpyObj('LoggerApi', ['info', 'warn', 'error', 'debug', 'fatal']); + }); + + describe('createMigrationReport:', () => { + it('should return a report with zeroed counters and an empty warnings list', () => { + const report = createMigrationReport(); + + expect(report.filesScanned).toBe(0); + expect(report.filesChanged).toBe(0); + expect(report.warnings).toEqual([]); + }); + + it('should return a new (independent) instance on each call', () => { + const first = createMigrationReport(); + const second = createMigrationReport(); + + expect(first).not.toBe(second); + expect(first.warnings).not.toBe(second.warnings); + }); + }); + + describe('printMigrationSummary:', () => { + it('should always log an info message with the total scanned/changed files (Req 9.1)', () => { + const report: MigrationReport = { + filesScanned: 5, + filesChanged: 2, + warnings: [] + }; + + printMigrationSummary(report, logger); + + expect(logger.info).toHaveBeenCalledWith( + 'Resumo da migração po-gauge → po-chart: 5 arquivo(s) analisado(s), 2 arquivo(s) alterado(s).' + ); + }); + + describe('when there are Casos_Nao_Migravel (warnings present) (Req 9.2, 6.5):', () => { + const report: MigrationReport = { + filesScanned: 3, + filesChanged: 1, + warnings: [ + { filePath: 'src/app/a.html', line: 10, reason: 'trecho malformado' }, + { filePath: 'src/app/b.ts', line: 4, reason: 'símbolo sem equivalente' } + ] + }; + + it('should log the info totals', () => { + printMigrationSummary(report, logger); + + expect(logger.info).toHaveBeenCalledWith( + 'Resumo da migração po-gauge → po-chart: 3 arquivo(s) analisado(s), 1 arquivo(s) alterado(s).' + ); + }); + + it('should log a warn header with the number of occurrences requiring manual review', () => { + printMigrationSummary(report, logger); + + expect(logger.warn).toHaveBeenCalledWith( + '2 ocorrência(s) exigem revisão manual (não foram migradas automaticamente):' + ); + }); + + it('should log a warn line for each warning with file/line/reason', () => { + printMigrationSummary(report, logger); + + expect(logger.warn).toHaveBeenCalledWith(' - src/app/a.html:10 — trecho malformado'); + expect(logger.warn).toHaveBeenCalledWith(' - src/app/b.ts:4 — símbolo sem equivalente'); + }); + + it('should not log the success message when warnings are present (Req 9.3)', () => { + printMigrationSummary(report, logger); + + expect(logger.info).not.toHaveBeenCalledWith( + 'Todas as ocorrências encontradas do po-gauge foram migradas com sucesso para po-chart.' + ); + }); + + it('should not throw even when Casos_Nao_Migravel exist (Req 6.5)', () => { + expect(() => printMigrationSummary(report, logger)).not.toThrow(); + expect(logger.error).not.toHaveBeenCalled(); + }); + }); + + describe('when there are no warnings but migration occurred (filesChanged > 0) (Req 9.3):', () => { + const report: MigrationReport = { + filesScanned: 4, + filesChanged: 4, + warnings: [] + }; + + it('should log the success info message', () => { + printMigrationSummary(report, logger); + + expect(logger.info).toHaveBeenCalledWith( + 'Todas as ocorrências encontradas do po-gauge foram migradas com sucesso para po-chart.' + ); + }); + + it('should not log any warn message', () => { + printMigrationSummary(report, logger); + + expect(logger.warn).not.toHaveBeenCalled(); + }); + + it('should not log the "nenhuma ocorrência" message (Req 9.4)', () => { + printMigrationSummary(report, logger); + + expect(logger.info).not.toHaveBeenCalledWith( + 'Nenhuma ocorrência do po-gauge foi encontrada no workspace. Nenhum arquivo foi alterado.' + ); + }); + }); + + describe('when no occurrence was found (filesChanged === 0, no warnings) (Req 9.4):', () => { + const report: MigrationReport = { + filesScanned: 7, + filesChanged: 0, + warnings: [] + }; + + it('should log the "nenhuma ocorrência" info message', () => { + printMigrationSummary(report, logger); + + expect(logger.info).toHaveBeenCalledWith( + 'Nenhuma ocorrência do po-gauge foi encontrada no workspace. Nenhum arquivo foi alterado.' + ); + }); + + it('should not log the success message (Req 9.3)', () => { + printMigrationSummary(report, logger); + + expect(logger.info).not.toHaveBeenCalledWith( + 'Todas as ocorrências encontradas do po-gauge foram migradas com sucesso para po-chart.' + ); + }); + + it('should not log any warn message', () => { + printMigrationSummary(report, logger); + + expect(logger.warn).not.toHaveBeenCalled(); + }); + }); + }); +}); diff --git a/projects/ui/schematics/ng-update/v22/migration-report.ts b/projects/ui/schematics/ng-update/v22/migration-report.ts new file mode 100644 index 0000000000..5df0bef811 --- /dev/null +++ b/projects/ui/schematics/ng-update/v22/migration-report.ts @@ -0,0 +1,84 @@ +import { logging } from '@angular-devkit/core'; + +/** + * Representa um Caso_Nao_Migravel identificado durante a execução da + * Schematic_Migracao. Guarda a localização e o motivo pelo qual o trecho não + * pôde ser migrado automaticamente, permitindo a revisão manual pelo + * desenvolvedor. + */ +export interface MigrationWarning { + /** Caminho do arquivo (relativo ao workspace) onde o caso foi encontrado. */ + filePath: string; + /** Número da linha inicial do trecho não migrado. */ + line: number; + /** Motivo pelo qual a transformação automática não foi aplicada. */ + reason: string; +} + +/** + * Relatório consolidado (Resumo_Migracao) acumulado ao longo da execução da + * Schematic_Migracao. Contém a quantidade de arquivos analisados e alterados, + * além da lista de Casos_Nao_Migravel encontrados. + */ +export interface MigrationReport { + /** Quantidade total de arquivos analisados durante a varredura. */ + filesScanned: number; + /** Quantidade total de arquivos efetivamente alterados. */ + filesChanged: number; + /** Lista de Casos_Nao_Migravel que exigem revisão manual. */ + warnings: Array; +} + +/** + * Cria um relatório de migração vazio, com as contagens zeradas e sem + * advertências. + */ +export function createMigrationReport(): MigrationReport { + return { + filesScanned: 0, + filesChanged: 0, + warnings: [] + }; +} + +/** + * Apresenta o Resumo_Migracao no logger da schematic ao final da execução. + * + * Comportamento: + * - Sempre registra, em nível informativo, o total de arquivos analisados e + * alterados (Req. 9.1). + * - Quando existem Casos_Nao_Migravel, registra em nível de alerta a lista de + * arquivos/linhas/motivos que exigem revisão manual, concluindo sem lançar + * erro (Req. 9.2, 6.5). + * - Quando não há Casos_Nao_Migravel mas houve migração, registra mensagem + * informativa de sucesso total (Req. 9.3). + * - Quando nenhuma ocorrência foi encontrada, registra mensagem informativa de + * "nenhuma ocorrência" (Req. 9.4). + */ +export function printMigrationSummary(report: MigrationReport, logger: logging.LoggerApi): void { + // Req. 9.1 — total de arquivos analisados e alterados + logger.info( + `Resumo da migração po-gauge → po-chart: ${report.filesScanned} arquivo(s) analisado(s), ` + + `${report.filesChanged} arquivo(s) alterado(s).` + ); + + if (report.warnings.length > 0) { + // Req. 9.2 / 6.5 — lista de casos não migráveis, concluindo sem lançar erro + logger.warn(`${report.warnings.length} ocorrência(s) exigem revisão manual (não foram migradas automaticamente):`); + + report.warnings.forEach(warning => { + logger.warn(` - ${warning.filePath}:${warning.line} — ${warning.reason}`); + }); + + return; + } + + if (report.filesChanged > 0) { + // Req. 9.3 — sucesso total (todas as ocorrências migradas) + logger.info('Todas as ocorrências encontradas do po-gauge foram migradas com sucesso para po-chart.'); + return; + } + + // Req. 9.4 — nenhuma ocorrência encontrada + logger.info('Nenhuma ocorrência do po-gauge foi encontrada no workspace. Nenhum arquivo foi alterado.'); +} diff --git a/projects/ui/schematics/package.json b/projects/ui/schematics/package.json new file mode 100644 index 0000000000..5bbefffbab --- /dev/null +++ b/projects/ui/schematics/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/projects/ui/src/lib/components/components.module.ts b/projects/ui/src/lib/components/components.module.ts index 959d7f92d4..3ca0e7c0a3 100644 --- a/projects/ui/src/lib/components/components.module.ts +++ b/projects/ui/src/lib/components/components.module.ts @@ -18,7 +18,6 @@ import { PoDynamicModule } from './po-dynamic/po-dynamic.module'; import { PoFieldModule } from './po-field/po-field.module'; import { PoFilterChipModule } from './po-filter-chip/po-filter-chip.module'; import { PoSwitchModule } from './po-field/po-switch/po-switch.module'; -import { PoGaugeModule } from './po-gauge/po-gauge.module'; import { PoGridModule } from './po-grid/po-grid.module'; import { PoIconModule } from './po-icon/po-icon.module'; import { PoImageModule } from './po-image/po-image.module'; @@ -72,7 +71,6 @@ const PO_MODULES = [ PoDynamicModule, PoFieldModule, PoFilterChipModule, - PoGaugeModule, PoGridModule, PoIconModule, PoInfoModule, diff --git a/projects/ui/src/lib/components/index.ts b/projects/ui/src/lib/components/index.ts index ca21a7e2c9..c52323578c 100644 --- a/projects/ui/src/lib/components/index.ts +++ b/projects/ui/src/lib/components/index.ts @@ -17,7 +17,6 @@ export * from './po-dropdown/index'; export * from './po-dynamic/index'; export * from './po-field/index'; export * from './po-filter-chip/index'; -export * from './po-gauge/index'; export * from './po-grid/index'; export * from './po-helper/index'; export * from './po-icon/index'; diff --git a/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.html b/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.html index a237407ee4..4c8c3f8ebc 100644 --- a/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.html +++ b/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.html @@ -1,5 +1,5 @@ @if (expanded) { -
    +
    diff --git a/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.spec.ts b/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.spec.ts index 31f07f14c8..646c3c5ea5 100644 --- a/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.spec.ts +++ b/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.spec.ts @@ -1,5 +1,3 @@ -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - import { ComponentFixture, TestBed } from '@angular/core/testing'; import { PoAccordionItemBodyComponent } from './po-accordion-item-body.component'; @@ -12,8 +10,7 @@ describe('PoAccordionItemBodyComponent:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [PoAccordionItemBodyComponent], - imports: [BrowserAnimationsModule] + declarations: [PoAccordionItemBodyComponent] }).compileComponents(); fixture = TestBed.createComponent(PoAccordionItemBodyComponent); @@ -52,4 +49,42 @@ describe('PoAccordionItemBodyComponent:', () => { expect(body).toBeFalsy(); }); }); + + describe('Methods:', () => { + it('animateEnter: should animate height from 0 to scrollHeight and call animationComplete', () => { + const animationComplete = jasmine.createSpy('animationComplete'); + const animation: any = {}; + const element = document.createElement('div'); + Object.defineProperty(element, 'scrollHeight', { value: 120 }); + spyOn(element, 'animate').and.returnValue(animation); + + component.animateEnter({ target: element, animationComplete }); + + expect(element.animate).toHaveBeenCalledWith([{ height: '0px' }, { height: '120px' }], { + duration: 200, + easing: 'linear' + }); + + animation.onfinish(); + expect(animationComplete).toHaveBeenCalled(); + }); + + it('animateLeave: should animate height from scrollHeight to 0 and call animationComplete', () => { + const animationComplete = jasmine.createSpy('animationComplete'); + const animation: any = {}; + const element = document.createElement('div'); + Object.defineProperty(element, 'scrollHeight', { value: 80 }); + spyOn(element, 'animate').and.returnValue(animation); + + component.animateLeave({ target: element, animationComplete }); + + expect(element.animate).toHaveBeenCalledWith([{ height: '80px' }, { height: '0px' }], { + duration: 200, + easing: 'linear' + }); + + animation.onfinish(); + expect(animationComplete).toHaveBeenCalled(); + }); + }); }); diff --git a/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.ts b/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.ts index 2414b2cdfb..9054315342 100644 --- a/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.ts +++ b/projects/ui/src/lib/components/po-accordion/po-accordion-item-body/po-accordion-item-body.component.ts @@ -1,17 +1,35 @@ -import { Component, Input } from '@angular/core'; -import { animate, style, transition, trigger } from '@angular/animations'; +import { AnimationCallbackEvent, Component, Input, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'po-accordion-item-body', templateUrl: 'po-accordion-item-body.component.html', - animations: [ - trigger('toggleBody', [ - transition('* => void', [style({ height: '*' }), animate(200, style({ height: 0 }))]), - transition('void => *', [style({ height: '0' }), animate(200, style({ height: '*' }))]) - ]) - ], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoAccordionItemBodyComponent { @Input('p-expanded') expanded: boolean = false; + + animateEnter(event: AnimationCallbackEvent): void { + this.animateHeight(event, '0px', `${(event.target as HTMLElement).scrollHeight}px`); + } + + animateLeave(event: AnimationCallbackEvent): void { + this.animateHeight(event, `${(event.target as HTMLElement).scrollHeight}px`, '0px'); + } + + private animateHeight(event: AnimationCallbackEvent, from: string, to: string): void { + const element = event.target as HTMLElement; + const previousOverflow = element.style.overflow; + element.style.overflow = 'hidden'; + + const animation = element.animate([{ height: from }, { height: to }], { + duration: 200, + easing: 'linear' + }); + + animation.onfinish = () => { + element.style.overflow = previousOverflow; + event.animationComplete(); + }; + } } diff --git a/projects/ui/src/lib/components/po-accordion/po-accordion-item/po-accordion-item.component.ts b/projects/ui/src/lib/components/po-accordion/po-accordion-item/po-accordion-item.component.ts index ebe0bb0772..8f938f0ae2 100644 --- a/projects/ui/src/lib/components/po-accordion/po-accordion-item/po-accordion-item.component.ts +++ b/projects/ui/src/lib/components/po-accordion/po-accordion-item/po-accordion-item.component.ts @@ -1,4 +1,14 @@ -import { Component, EventEmitter, Input, OnDestroy, Output, TemplateRef, ViewChild, inject } from '@angular/core'; +import { + Component, + EventEmitter, + Input, + OnDestroy, + Output, + TemplateRef, + ViewChild, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { Subscription, filter } from 'rxjs'; import { convertToBoolean } from '../../../utils/util'; @@ -39,6 +49,7 @@ import { PoAccordionService } from '../services/po-accordion.service'; @Component({ selector: 'po-accordion-item', templateUrl: 'po-accordion-item.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoAccordionItemComponent implements OnDestroy { diff --git a/projects/ui/src/lib/components/po-accordion/po-accordion-manager/po-accordion-manager.component.spec.ts b/projects/ui/src/lib/components/po-accordion/po-accordion-manager/po-accordion-manager.component.spec.ts index 285826399b..24e9d7ea63 100644 --- a/projects/ui/src/lib/components/po-accordion/po-accordion-manager/po-accordion-manager.component.spec.ts +++ b/projects/ui/src/lib/components/po-accordion/po-accordion-manager/po-accordion-manager.component.spec.ts @@ -1,5 +1,4 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { PoAccordionManagerComponent } from './po-accordion-manager.component'; @@ -12,7 +11,7 @@ describe('PoAccordionManagerComponent:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [PoAccordionManagerComponent], - imports: [BrowserAnimationsModule] + imports: [] }).compileComponents(); fixture = TestBed.createComponent(PoAccordionManagerComponent); diff --git a/projects/ui/src/lib/components/po-accordion/po-accordion-manager/po-accordion-manager.component.ts b/projects/ui/src/lib/components/po-accordion/po-accordion-manager/po-accordion-manager.component.ts index 8e5a997262..f810bb701b 100644 --- a/projects/ui/src/lib/components/po-accordion/po-accordion-manager/po-accordion-manager.component.ts +++ b/projects/ui/src/lib/components/po-accordion/po-accordion-manager/po-accordion-manager.component.ts @@ -8,13 +8,15 @@ import { OnChanges, Output, SimpleChanges, - ViewChild + ViewChild, + ChangeDetectionStrategy } from '@angular/core'; import { PoAccordionLiterals } from '../interfaces/po-accordion-literals.interface'; @Component({ selector: 'po-accordion-manager', templateUrl: 'po-accordion-manager.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoAccordionManagerComponent implements OnChanges { diff --git a/projects/ui/src/lib/components/po-accordion/po-accordion.component.spec.ts b/projects/ui/src/lib/components/po-accordion/po-accordion.component.spec.ts index aeca031853..619c3e684b 100644 --- a/projects/ui/src/lib/components/po-accordion/po-accordion.component.spec.ts +++ b/projects/ui/src/lib/components/po-accordion/po-accordion.component.spec.ts @@ -1,5 +1,4 @@ -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { Component, QueryList } from '@angular/core'; +import { Component, QueryList, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { PoAccordionComponent } from './po-accordion.component'; @@ -13,6 +12,7 @@ import { PoAccordionService } from './services/po-accordion.service'; Item 2 `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class PoAccordionMockComponent {} @@ -29,7 +29,7 @@ describe('PoAccordionComponent:', () => { await TestBed.configureTestingModule({ declarations: [PoAccordionMockComponent], providers: [PoAccordionService], - imports: [PoAccordionModule, BrowserAnimationsModule] + imports: [PoAccordionModule] }).compileComponents(); fixture = TestBed.createComponent(PoAccordionComponent); diff --git a/projects/ui/src/lib/components/po-accordion/po-accordion.component.ts b/projects/ui/src/lib/components/po-accordion/po-accordion.component.ts index 088284cccb..4adb6d1527 100644 --- a/projects/ui/src/lib/components/po-accordion/po-accordion.component.ts +++ b/projects/ui/src/lib/components/po-accordion/po-accordion.component.ts @@ -1,4 +1,12 @@ -import { Component, ContentChildren, OnDestroy, QueryList, ViewChildren, inject } from '@angular/core'; +import { + Component, + ContentChildren, + OnDestroy, + QueryList, + ViewChildren, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { Subscription } from 'rxjs'; @@ -32,6 +40,7 @@ import { PoAccordionService } from './services/po-accordion.service'; selector: 'po-accordion', templateUrl: 'po-accordion.component.html', providers: [PoAccordionService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoAccordionComponent extends PoAccordionBaseComponent implements OnDestroy { diff --git a/projects/ui/src/lib/components/po-accordion/po-accordion.module.ts b/projects/ui/src/lib/components/po-accordion/po-accordion.module.ts index 8c57dcb8ee..98ebcd490a 100644 --- a/projects/ui/src/lib/components/po-accordion/po-accordion.module.ts +++ b/projects/ui/src/lib/components/po-accordion/po-accordion.module.ts @@ -16,44 +16,6 @@ import { PoAccordionComponent } from './po-accordion.component'; * @description * * Módulo do componente `po-accordion`. - * - * > Para o correto funcionamento do componente `po-accordion`, deve ser importado o módulo `BrowserAnimationsModule` no - * > módulo principal da sua aplicação. - * - * Módulo da aplicação: - * ``` - * import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - * import { PoModule } from '@po-ui/ng-components'; - * ... - * - * @NgModule({ - * imports: [ - * BrowserModule, - * BrowserAnimationsModule, - * ... - * PoModule - * ], - * declarations: [ - * AppComponent, - * ... - * ], - * providers: [], - * bootstrap: [AppComponent] - * }) - * export class AppModule { } - * ``` - * - * Em aplicações Standalone, utilize a seguinte configuração para o bootstrap: - * - * ``` - * import { bootstrapApplication } from '@angular/platform-browser'; - * import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - * import { AppComponent } from './app.component'; - * - * bootstrapApplication(AppComponent, { - * providers: [importProvidersFrom(BrowserAnimationsModule)] - * }).catch(err => console.error(err)); - * ``` */ @NgModule({ imports: [CommonModule, PoTagModule, PoIconModule, PoDividerModule, PoTooltipModule], diff --git a/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-basic/sample-po-accordion-basic.component.ts b/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-basic/sample-po-accordion-basic.component.ts index f1763af443..b489715b5e 100644 --- a/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-basic/sample-po-accordion-basic.component.ts +++ b/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-basic/sample-po-accordion-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-accordion-basic', templateUrl: './sample-po-accordion-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoAccordionBasicComponent {} diff --git a/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-faq/sample-po-accordion-faq.component.ts b/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-faq/sample-po-accordion-faq.component.ts index e4686a42f0..4166af2703 100644 --- a/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-faq/sample-po-accordion-faq.component.ts +++ b/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-faq/sample-po-accordion-faq.component.ts @@ -1,10 +1,11 @@ -import { AfterContentInit, Component, ViewChild } from '@angular/core'; +import { AfterContentInit, Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoAccordionItemComponent } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-accordion-faq', templateUrl: './sample-po-accordion-faq.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoAccordionFaqComponent implements AfterContentInit { diff --git a/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-labs/sample-po-accordion-labs.component.ts b/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-labs/sample-po-accordion-labs.component.ts index c99f80a4ca..a04f63716d 100644 --- a/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-labs/sample-po-accordion-labs.component.ts +++ b/projects/ui/src/lib/components/po-accordion/samples/sample-po-accordion-labs/sample-po-accordion-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoAccordionItemComponent, @@ -12,6 +12,7 @@ import { @Component({ selector: 'sample-po-accordion-labs', templateUrl: './sample-po-accordion-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoAccordionLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-basic/sample-po-avatar-basic.component.ts b/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-basic/sample-po-avatar-basic.component.ts index a59f1ae24d..ac92bed292 100644 --- a/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-basic/sample-po-avatar-basic.component.ts +++ b/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-basic/sample-po-avatar-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-avatar-basic', templateUrl: './sample-po-avatar-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoAvatarBasicComponent {} diff --git a/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-business-card/sample-po-avatar-business-card.component.ts b/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-business-card/sample-po-avatar-business-card.component.ts index 784c959304..0f790345bf 100644 --- a/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-business-card/sample-po-avatar-business-card.component.ts +++ b/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-business-card/sample-po-avatar-business-card.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-avatar-business-card', styleUrls: ['./sample-po-avatar-business-card.component.css'], templateUrl: './sample-po-avatar-business-card.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoAvatarBusinessCardComponent { diff --git a/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-labs/sample-po-avatar-labs.component.ts b/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-labs/sample-po-avatar-labs.component.ts index d495c66c5c..5852febf6d 100644 --- a/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-labs/sample-po-avatar-labs.component.ts +++ b/projects/ui/src/lib/components/po-avatar/samples/sample-po-avatar-labs/sample-po-avatar-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-avatar-labs', templateUrl: './sample-po-avatar-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoAvatarLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-badge/po-badge.component.ts b/projects/ui/src/lib/components/po-badge/po-badge.component.ts index 7f13eb52c1..20313b2b90 100644 --- a/projects/ui/src/lib/components/po-badge/po-badge.component.ts +++ b/projects/ui/src/lib/components/po-badge/po-badge.component.ts @@ -1,4 +1,4 @@ -import { Component, OnChanges, OnInit, SimpleChanges, inject } from '@angular/core'; +import { Component, OnChanges, OnInit, SimpleChanges, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoBadgeBaseComponent } from './po-badge-base.component'; import { PoBadgeLiterals } from './interfaces/po-badge-literals.interface'; @@ -32,6 +32,7 @@ const PO_BADGE_MAX_NOTIFICATIONS = 9; selector: 'po-badge', templateUrl: './po-badge.component.html', styles: [], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoBadgeComponent extends PoBadgeBaseComponent implements OnInit, OnChanges { diff --git a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.ts b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.ts index 30e613f2ea..b6144d6828 100644 --- a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.ts +++ b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-badge-basic', templateUrl: './sample-po-badge-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoBadgeBasicComponent {} diff --git a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.ts b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.ts index d71a88ac8b..bb040036a1 100644 --- a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.ts +++ b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.ts @@ -1,9 +1,10 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-badge-labs', templateUrl: './sample-po-badge-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoBadgeLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.ts b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.ts index dd594045cf..ef5dcfc5fd 100644 --- a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.ts +++ b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-badge-message', templateUrl: './sample-po-badge-message.component.html', styleUrls: ['./sample-po-badge-message.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoBadgeMessageComponent { diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.spec.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.spec.ts index 65b81de08a..9abde79c24 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.spec.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.spec.ts @@ -5,7 +5,7 @@ import { Observable } from 'rxjs'; import { PoBreadcrumbFavoriteComponent } from './po-breadcrumb-favorite.component'; import { PoBreadcrumbFavoriteService } from './po-breadcrumb-favorite.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoBreadcrumbFavoriteComponent', () => { let component: PoBreadcrumbFavoriteComponent; @@ -23,7 +23,7 @@ describe('PoBreadcrumbFavoriteComponent', () => { await TestBed.configureTestingModule({ declarations: [PoBreadcrumbFavoriteComponent], imports: [], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting()] }).compileComponents(); fixture = TestBed.createComponent(PoBreadcrumbFavoriteComponent); diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.ts index a792cbecc3..c2406fe137 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnDestroy, OnInit, inject } from '@angular/core'; +import { Component, Input, OnDestroy, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { Subscription } from 'rxjs'; @@ -37,6 +37,7 @@ export const PoBreadcrumbLiterals: object = { selector: 'po-breadcrumb-favorite', templateUrl: './po-breadcrumb-favorite.component.html', providers: [PoBreadcrumbFavoriteService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoBreadcrumbFavoriteComponent implements OnInit, OnDestroy { diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.service.spec.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.service.spec.ts index 522f1cdeae..560d5fd38b 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.service.spec.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb-favorite/po-breadcrumb-favorite.service.spec.ts @@ -1,5 +1,5 @@ import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; -import { HttpRequest, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { HttpRequest, provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { TestBed } from '@angular/core/testing'; import { PoBreadcrumbFavoriteService } from './po-breadcrumb-favorite.service'; @@ -21,7 +21,11 @@ describe('PoBreadcrumbFavoriteService:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoBreadcrumbFavoriteService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoBreadcrumbFavoriteService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); breadcrumbFavoriteService = TestBed.inject(PoBreadcrumbFavoriteService); diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.spec.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.spec.ts index daf6ad4671..0ffd6fccf2 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.spec.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.spec.ts @@ -1,23 +1,25 @@ import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; -import { Component } from '@angular/core'; +import { provideLocationMocks } from '@angular/common/testing'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { HttpClient, HttpHandler } from '@angular/common/http'; -import { Routes } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import { Routes, RouterModule } from '@angular/router'; import { PoBreadcrumbComponent } from './po-breadcrumb.component'; import { PoBreadcrumbFavoriteComponent } from './po-breadcrumb-favorite/po-breadcrumb-favorite.component'; import { PoBreadcrumbItem } from './po-breadcrumb-item.interface'; @Component({ - selector: 'app-breadcrumb-documentation', + selector: 'app-documentation-test', template: 'Documentation', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class DocumentationComponent {} @Component({ - selector: 'app-breadcrumb-guides', + selector: 'app-guides-test', template: 'Guides', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class GuidesComponent {} @@ -51,9 +53,9 @@ describe('PoBreadcrumbComponent:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes(routes)], + imports: [RouterModule.forRoot(routes)], declarations: [PoBreadcrumbComponent, PoBreadcrumbFavoriteComponent, DocumentationComponent, GuidesComponent], - providers: [HttpClient, HttpHandler] + providers: [provideLocationMocks(), HttpClient, HttpHandler] }).compileComponents(); fixture = TestBed.createComponent(PoBreadcrumbComponent); @@ -65,6 +67,19 @@ describe('PoBreadcrumbComponent:', () => { fixture.detectChanges(); }); + afterEach(() => { + // O ambiente roda com `teardown: { destroyAfterEach: false }`, então o + // `ngOnDestroy` não é chamado automaticamente entre os testes. Sem isso, o + // listener de `window:resize` registrado em `ngAfterViewInit` (via + // `initializeResizeListener`) permanece vivo apontando para uma instância + // órfã. Ao acumularem-se entre os testes, qualquer `window.dispatchEvent('resize')` + // de outros specs dispara esses callbacks órfãos (agendando setTimeout que + // acessa `breadcrumbElement` de componentes já descartados), corrompendo a + // execução e a medição de cobertura da suíte completa. + // Destruir o fixture aqui remove o listener e limpa o timer pendente. + fixture?.destroy(); + }); + it('should be created', () => { expect(component).toBeTruthy(); }); @@ -236,8 +251,21 @@ describe('PoBreadcrumbComponent:', () => { it('should called when window resize.', () => { spyOn(component, 'debounceResize'); + + // Captura o callback registrado para 'resize' e o invoca diretamente, em vez + // de disparar um evento global em `window` (que dependeria de listeners de + // outras instâncias). O `removeResizeListener` ao final evita vazamento. + let resizeCallback: (event: Event) => void; + spyOn(component['renderer'], 'listen').and.callFake((target: any, eventName: string, callback: any) => { + if (target === 'window' && eventName === 'resize') { + resizeCallback = callback; + } + return () => {}; + }); + component['initializeResizeListener'](); - window.dispatchEvent(eventResize); + resizeCallback(eventResize); + component['removeResizeListener'](); expect(component[debounceResize]).toHaveBeenCalled(); }); @@ -440,7 +468,7 @@ describe('PoBreadcrumbComponent:', () => { { label: 'Teste nível 4', link: '/test/nivel/4' } ]; - component['_breadcrumbItemsLenght'] = 400; + component['_breadcrumbItemsLenght'] = 500; spyOn(component, 'getBreadcrumbWidth').and.returnValue(300); component['calcBreadcrumb'](); diff --git a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.ts b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.ts index 050581dfeb..0abec05f98 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/po-breadcrumb.component.ts @@ -7,7 +7,8 @@ import { OnDestroy, Renderer2, ViewChild, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { PoBreadcrumbBaseComponent } from './po-breadcrumb-base.component'; @@ -48,6 +49,7 @@ export const poBreadcrumbLiterals: object = { @Component({ selector: 'po-breadcrumb', templateUrl: './po-breadcrumb.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoBreadcrumbComponent extends PoBreadcrumbBaseComponent implements AfterViewInit, DoCheck, OnDestroy { diff --git a/projects/ui/src/lib/components/po-breadcrumb/samples/sample-po-breadcrumb-basic/sample-po-breadcrumb-basic.component.ts b/projects/ui/src/lib/components/po-breadcrumb/samples/sample-po-breadcrumb-basic/sample-po-breadcrumb-basic.component.ts index 4d5bdd93a2..8d557b57fb 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/samples/sample-po-breadcrumb-basic/sample-po-breadcrumb-basic.component.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/samples/sample-po-breadcrumb-basic/sample-po-breadcrumb-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-breadcrumb-basic', templateUrl: './sample-po-breadcrumb-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoBreadcrumbBasicComponent {} diff --git a/projects/ui/src/lib/components/po-breadcrumb/samples/sample-po-breadcrumb-labs/sample-po-breadcrumb-labs.component.ts b/projects/ui/src/lib/components/po-breadcrumb/samples/sample-po-breadcrumb-labs/sample-po-breadcrumb-labs.component.ts index 7575ef3fc2..bcca59251b 100644 --- a/projects/ui/src/lib/components/po-breadcrumb/samples/sample-po-breadcrumb-labs/sample-po-breadcrumb-labs.component.ts +++ b/projects/ui/src/lib/components/po-breadcrumb/samples/sample-po-breadcrumb-labs/sample-po-breadcrumb-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoBreadcrumbItem, PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-breadcrumb-labs', templateUrl: './sample-po-breadcrumb-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoBreadcrumbLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-button-group/po-button-group-base.component.ts b/projects/ui/src/lib/components/po-button-group/po-button-group-base.component.ts index b19b0e17bd..9b78389f20 100644 --- a/projects/ui/src/lib/components/po-button-group/po-button-group-base.component.ts +++ b/projects/ui/src/lib/components/po-button-group/po-button-group-base.component.ts @@ -1,4 +1,4 @@ -import { Component, HostBinding, HostListener, Input, input } from '@angular/core'; +import { Component, HostBinding, HostListener, Input, input, ChangeDetectionStrategy } from '@angular/core'; import { PoFieldSize } from '../../enums/po-field-size.enum'; import { getDefaultSizeFn, validateSizeFn } from '../../utils/util'; @@ -63,6 +63,7 @@ const PO_TOGGLE_TYPE_DEFAULT = 'none'; @Component({ selector: 'po-button-group-base', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoButtonGroupBaseComponent { diff --git a/projects/ui/src/lib/components/po-button-group/po-button-group.component.ts b/projects/ui/src/lib/components/po-button-group/po-button-group.component.ts index b93f2971a9..0c6abc6cc7 100644 --- a/projects/ui/src/lib/components/po-button-group/po-button-group.component.ts +++ b/projects/ui/src/lib/components/po-button-group/po-button-group.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewContainerRef, inject } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoButtonGroupBaseComponent } from './po-button-group-base.component'; @@ -36,6 +36,7 @@ import { PoButtonGroupBaseComponent } from './po-button-group-base.component'; @Component({ selector: 'po-button-group', templateUrl: './po-button-group.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoButtonGroupComponent extends PoButtonGroupBaseComponent {} diff --git a/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-attendance/sample-po-button-group-attendance.component.ts b/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-attendance/sample-po-button-group-attendance.component.ts index 8cb1d4a619..aa0cbd99fd 100644 --- a/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-attendance/sample-po-button-group-attendance.component.ts +++ b/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-attendance/sample-po-button-group-attendance.component.ts @@ -1,10 +1,11 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoButtonGroupItem, PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-button-group-attendance', templateUrl: './sample-po-button-group-attendance.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoButtonGroupAttendanceComponent { diff --git a/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-basic/sample-po-button-group-basic.component.ts b/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-basic/sample-po-button-group-basic.component.ts index 13333fed43..eaed17a0cb 100644 --- a/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-basic/sample-po-button-group-basic.component.ts +++ b/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-basic/sample-po-button-group-basic.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoButtonGroupItem } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-button-group-basic', templateUrl: './sample-po-button-group-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoButtonGroupBasicComponent { diff --git a/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-labs/sample-po-button-group-labs.component.ts b/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-labs/sample-po-button-group-labs.component.ts index 218975157f..78ee72dd58 100644 --- a/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-labs/sample-po-button-group-labs.component.ts +++ b/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-labs/sample-po-button-group-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoButtonGroupItem, @@ -11,6 +11,7 @@ import { @Component({ selector: 'sample-po-button-group-labs', templateUrl: './sample-po-button-group-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoButtonGroupLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-opening-service-ticket/sample-po-button-group-opening-service-ticket.component.ts b/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-opening-service-ticket/sample-po-button-group-opening-service-ticket.component.ts index 85c49564dd..7639dee2c2 100644 --- a/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-opening-service-ticket/sample-po-button-group-opening-service-ticket.component.ts +++ b/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-opening-service-ticket/sample-po-button-group-opening-service-ticket.component.ts @@ -26,10 +26,10 @@ export class SamplePoButtonGroupOpeningServiceTicketComponent { ]; selectWeekDay(button: PoButtonGroupItem): void { - this.selectedWeekDay = button.selected ? button.label! : ''; + this.selectedWeekDay = button.selected ? button.label : ''; } selectPeriod(button: PoButtonGroupItem): void { - this.selectedPeriod = button.selected ? button.label! : ''; + this.selectedPeriod = button.selected ? button.label : ''; } } diff --git a/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-post/sample-po-button-group-post.component.ts b/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-post/sample-po-button-group-post.component.ts index ab1d8bc2c7..12602eb432 100644 --- a/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-post/sample-po-button-group-post.component.ts +++ b/projects/ui/src/lib/components/po-button-group/samples/sample-po-button-group-post/sample-po-button-group-post.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoButtonGroupItem } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-button-group-post', templateUrl: './sample-po-button-group-post.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoButtonGroupPostComponent { diff --git a/projects/ui/src/lib/components/po-button/po-button-base.component.ts b/projects/ui/src/lib/components/po-button/po-button-base.component.ts index 45da6889f7..aee70d858d 100644 --- a/projects/ui/src/lib/components/po-button/po-button-base.component.ts +++ b/projects/ui/src/lib/components/po-button/po-button-base.component.ts @@ -1,4 +1,14 @@ -import { Component, EventEmitter, HostBinding, HostListener, Input, Output, TemplateRef, input } from '@angular/core'; +import { + Component, + EventEmitter, + HostBinding, + HostListener, + Input, + Output, + TemplateRef, + input, + ChangeDetectionStrategy +} from '@angular/core'; import { convertToBoolean, getDefaultSizeFn, validateSizeFn } from '../../utils/util'; @@ -73,6 +83,7 @@ import { PoButtonType } from './enums/po-button-type.enum'; @Component({ selector: 'po-button-base', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoButtonBaseComponent { diff --git a/projects/ui/src/lib/components/po-button/samples/sample-po-button-basic/sample-po-button-basic.component.ts b/projects/ui/src/lib/components/po-button/samples/sample-po-button-basic/sample-po-button-basic.component.ts index 3ee3f001d6..9465223e14 100644 --- a/projects/ui/src/lib/components/po-button/samples/sample-po-button-basic/sample-po-button-basic.component.ts +++ b/projects/ui/src/lib/components/po-button/samples/sample-po-button-basic/sample-po-button-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-button-basic', templateUrl: './sample-po-button-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoButtonBasicComponent { diff --git a/projects/ui/src/lib/components/po-button/samples/sample-po-button-labs/sample-po-button-labs.component.ts b/projects/ui/src/lib/components/po-button/samples/sample-po-button-labs/sample-po-button-labs.component.ts index 8f72f131b7..f8f4ce1d21 100644 --- a/projects/ui/src/lib/components/po-button/samples/sample-po-button-labs/sample-po-button-labs.component.ts +++ b/projects/ui/src/lib/components/po-button/samples/sample-po-button-labs/sample-po-button-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption, PoDialogService, PoButtonType } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-button-labs', templateUrl: './sample-po-button-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoButtonLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-button/samples/sample-po-button-social-network/sample-po-button-social-network.component.ts b/projects/ui/src/lib/components/po-button/samples/sample-po-button-social-network/sample-po-button-social-network.component.ts index 5cb95ebf1e..0a4951349c 100644 --- a/projects/ui/src/lib/components/po-button/samples/sample-po-button-social-network/sample-po-button-social-network.component.ts +++ b/projects/ui/src/lib/components/po-button/samples/sample-po-button-social-network/sample-po-button-social-network.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-button-social-network', templateUrl: './sample-po-button-social-network.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoButtonSocialNetworkComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-calendar/po-calendar-wrapper/po-calendar-wrapper.component.spec.ts b/projects/ui/src/lib/components/po-calendar/po-calendar-wrapper/po-calendar-wrapper.component.spec.ts index 19a097f5fc..b06c47c60c 100644 --- a/projects/ui/src/lib/components/po-calendar/po-calendar-wrapper/po-calendar-wrapper.component.spec.ts +++ b/projects/ui/src/lib/components/po-calendar/po-calendar-wrapper/po-calendar-wrapper.component.spec.ts @@ -599,7 +599,7 @@ describe('PoCalendarWrapperComponent', () => { }); it('getDayBackgroundColor: should return empty string when date is falsy', () => { - expect(component.getDayBackgroundColor(null as any)).toBe(''); + expect(component.getDayBackgroundColor(null)).toBe(''); }); it('getDayForegroundColor: should call `getDayColor` with `date` and `foreground`', () => { @@ -2725,7 +2725,7 @@ describe('PoCalendarWrapperComponent', () => { it('should return "invalid-index" when the date is null', () => { const index = 5; - expect(component.trackByDay(index, null as any)).toBe('invalid-5'); + expect(component.trackByDay(index, null)).toBe('invalid-5'); }); it('should return "invalid-index" when the object is not an instance of Date', () => { @@ -2768,7 +2768,7 @@ describe('PoCalendarWrapperComponent', () => { }); it('trackByDay: deve retornar fallback para data inválida', () => { - expect(component.trackByDay(5, null as any)).toBe('invalid-5'); + expect(component.trackByDay(5, null)).toBe('invalid-5'); }); }); diff --git a/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-basic/sample-po-calendar-basic.component.ts b/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-basic/sample-po-calendar-basic.component.ts index 4709d77cb4..343173903d 100644 --- a/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-basic/sample-po-calendar-basic.component.ts +++ b/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-basic/sample-po-calendar-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-calendar-basic', templateUrl: './sample-po-calendar-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCalendarBasicComponent {} diff --git a/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-labs/sample-po-calendar-labs.component.ts b/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-labs/sample-po-calendar-labs.component.ts index 75678e1330..49b158edfe 100644 --- a/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-labs/sample-po-calendar-labs.component.ts +++ b/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-labs/sample-po-calendar-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoRadioGroupOption, PoCalendarMode, PoCalendarRangePreset } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-calendar-labs', templateUrl: './sample-po-calendar-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCalendarLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-range-presets/sample-po-calendar-range-presets.component.ts b/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-range-presets/sample-po-calendar-range-presets.component.ts index 6214e6f32d..181679a427 100644 --- a/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-range-presets/sample-po-calendar-range-presets.component.ts +++ b/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-range-presets/sample-po-calendar-range-presets.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-calendar-range-presets', templateUrl: './sample-po-calendar-range-presets.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCalendarRangePresetsComponent {} diff --git a/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-ticket-sales/sample-po-calendar-ticket-sales.component.ts b/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-ticket-sales/sample-po-calendar-ticket-sales.component.ts index c9af701e7e..25df994c13 100644 --- a/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-ticket-sales/sample-po-calendar-ticket-sales.component.ts +++ b/projects/ui/src/lib/components/po-calendar/samples/sample-po-calendar-ticket-sales/sample-po-calendar-ticket-sales.component.ts @@ -1,10 +1,11 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService, PoPageAction, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-calendar-ticket-sales', templateUrl: './sample-po-calendar-ticket-sales.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCalendarTicketSalesComponent { diff --git a/projects/ui/src/lib/components/po-chart/po-chart-grid-utils.spec.ts b/projects/ui/src/lib/components/po-chart/po-chart-grid-utils.spec.ts index d4fa878aa0..7e30e0ae4d 100644 --- a/projects/ui/src/lib/components/po-chart/po-chart-grid-utils.spec.ts +++ b/projects/ui/src/lib/components/po-chart/po-chart-grid-utils.spec.ts @@ -85,6 +85,7 @@ describe('PoChartGridUtils', () => { }); it('should set areaStyle.color using computedStyle when serie.color is var(...)', () => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spyGetComputed = spyOn(globalThis, 'getComputedStyle').and.returnValue({ getPropertyValue: () => '#445566' } as unknown as CSSStyleDeclaration); diff --git a/projects/ui/src/lib/components/po-chart/po-chart-modal-table/po-chart-modal-table.component.spec.ts b/projects/ui/src/lib/components/po-chart/po-chart-modal-table/po-chart-modal-table.component.spec.ts index ae1e27274d..78d833539e 100644 --- a/projects/ui/src/lib/components/po-chart/po-chart-modal-table/po-chart-modal-table.component.spec.ts +++ b/projects/ui/src/lib/components/po-chart/po-chart-modal-table/po-chart-modal-table.component.spec.ts @@ -1,9 +1,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { PoChartModalTableComponent } from './po-chart-modal-table.component'; import { PoModalModule } from '../../po-modal'; import { PoTableModule } from '../../po-table'; -import { provideHttpClient } from '@angular/common/http'; +import { provideHttpClient, withXhr } from '@angular/common/http'; describe('PoChartModalTableComponent', () => { let component: PoChartModalTableComponent; @@ -11,8 +10,8 @@ describe('PoChartModalTableComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [NoopAnimationsModule, PoChartModalTableComponent, PoModalModule, PoTableModule], - providers: [provideHttpClient()] + imports: [PoChartModalTableComponent, PoModalModule, PoTableModule], + providers: [provideHttpClient(withXhr())] }).compileComponents(); fixture = TestBed.createComponent(PoChartModalTableComponent); diff --git a/projects/ui/src/lib/components/po-chart/po-chart-modal-table/po-chart-modal-table.component.ts b/projects/ui/src/lib/components/po-chart/po-chart-modal-table/po-chart-modal-table.component.ts index 92305d85c1..bd5f00435b 100644 --- a/projects/ui/src/lib/components/po-chart/po-chart-modal-table/po-chart-modal-table.component.ts +++ b/projects/ui/src/lib/components/po-chart/po-chart-modal-table/po-chart-modal-table.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, ViewChild } from '@angular/core'; +import { Component, Input, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoModalComponent, PoModalModule } from '../../po-modal'; import { PoTableModule } from '../../po-table'; @@ -7,6 +7,7 @@ import { PoTableModule } from '../../po-table'; standalone: true, imports: [PoModalModule, PoTableModule], selector: 'po-chart-modal-table', + changeDetection: ChangeDetectionStrategy.Eager, template: ` diff --git a/projects/ui/src/lib/components/po-chart/po-chart.component.spec.ts b/projects/ui/src/lib/components/po-chart/po-chart.component.spec.ts index 278ed88189..d06a0a393b 100644 --- a/projects/ui/src/lib/components/po-chart/po-chart.component.spec.ts +++ b/projects/ui/src/lib/components/po-chart/po-chart.component.spec.ts @@ -1,9 +1,7 @@ import { CurrencyPipe, DecimalPipe } from '@angular/common'; import { ElementRef, NO_ERRORS_SCHEMA, SimpleChanges, ViewContainerRef } from '@angular/core'; import { ComponentFixture, fakeAsync, flush, TestBed, tick, waitForAsync } from '@angular/core/testing'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; - -import { provideHttpClient } from '@angular/common/http'; +import { provideHttpClient, withXhr } from '@angular/common/http'; import { provideHttpClientTesting } from '@angular/common/http/testing'; import type { EChartsType } from 'echarts/core'; import { PoTooltipModule } from '../../directives'; @@ -66,7 +64,7 @@ describe('PoChartComponent', () => { mockVcr = jasmine.createSpyObj('ViewContainerRef', ['clear', 'createComponent']); TestBed.configureTestingModule({ - imports: [NoopAnimationsModule, PoTooltipModule], + imports: [PoTooltipModule], declarations: [PoChartComponent], providers: [ CurrencyPipe, @@ -76,7 +74,7 @@ describe('PoChartComponent', () => { { provide: PoChartBaseComponent, useValue: {} }, { provide: ElementRef, useValue: createMockElementRef }, { provide: ViewContainerRef, useValue: mockVcr }, - provideHttpClient(), + provideHttpClient(withXhr()), provideHttpClientTesting() ], schemas: [NO_ERRORS_SCHEMA] @@ -1110,6 +1108,7 @@ describe('PoChartComponent', () => { it('should return an empty string when element is not found or CSS variable is not set', () => { spyOn(document, 'querySelector').and.returnValue(null); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(window, 'getComputedStyle').and.returnValue({ getPropertyValue: () => '' } as unknown as CSSStyleDeclaration); @@ -1395,6 +1394,7 @@ describe('PoChartComponent', () => { }); it('should call getComputedStyle with document.documentElement and use its value for var(...) color', () => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spyGetComputed = spyOn(window, 'getComputedStyle').and.returnValue({ getPropertyValue: (prop: string) => '#112233' } as unknown as CSSStyleDeclaration); @@ -2422,6 +2422,7 @@ describe('PoChartComponent', () => { it('should use default font size of 16px if parent font size is undefined', () => { spyOn(component, 'getCSSVariable').and.returnValue('2em'); spyOn(document, 'querySelector').and.returnValue(null); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(window, 'getComputedStyle').and.returnValue({ fontSize: '16px' } as CSSStyleDeclaration); const result = (component as any)['chartGridUtils'].resolvePx('2em'); @@ -2435,6 +2436,7 @@ describe('PoChartComponent', () => { spyOn(component, 'getCSSVariable').and.returnValue('1.5em'); spyOn(document, 'querySelector').and.returnValue(mockParentElement); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(window, 'getComputedStyle').and.returnValue({ fontSize: '18px' } as CSSStyleDeclaration); const result = (component as any)['chartGridUtils'].resolvePx('--some-size', '.some-selector'); diff --git a/projects/ui/src/lib/components/po-chart/po-chart.component.ts b/projects/ui/src/lib/components/po-chart/po-chart.component.ts index c9579ac957..85ed5ddf59 100644 --- a/projects/ui/src/lib/components/po-chart/po-chart.component.ts +++ b/projects/ui/src/lib/components/po-chart/po-chart.component.ts @@ -12,7 +12,8 @@ import { SimpleChanges, ViewChild, ViewChildren, - ViewContainerRef + ViewContainerRef, + ChangeDetectionStrategy } from '@angular/core'; import { CurrencyPipe, DecimalPipe } from '@angular/common'; @@ -107,6 +108,7 @@ use([ @Component({ selector: 'po-chart', templateUrl: './po-chart.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoChartComponent extends PoChartBaseComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy { diff --git a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-basic/sample-po-chart-basic.component.ts b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-basic/sample-po-chart-basic.component.ts index a6191d620e..0e06c8093b 100644 --- a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-basic/sample-po-chart-basic.component.ts +++ b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-basic/sample-po-chart-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-chart-basic', templateUrl: './sample-po-chart-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoChartBasicComponent {} diff --git a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-coffee-ranking/sample-po-chart-coffee-ranking.component.ts b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-coffee-ranking/sample-po-chart-coffee-ranking.component.ts index 55b89ec1d4..46c3b26a7a 100644 --- a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-coffee-ranking/sample-po-chart-coffee-ranking.component.ts +++ b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-coffee-ranking/sample-po-chart-coffee-ranking.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoChartType, PoChartOptions, PoChartSerie, PoDialogService, PoChartLabelFormat } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoChartType, PoChartOptions, PoChartSerie, PoDialogService, PoChartLabe selector: 'sample-po-chart-coffee-ranking', templateUrl: './sample-po-chart-coffee-ranking.component.html', providers: [PoDialogService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoChartCoffeeRankingComponent { diff --git a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-labs/sample-po-chart-labs.component.ts b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-labs/sample-po-chart-labs.component.ts index 59c9eb0c53..fd5c135d33 100644 --- a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-labs/sample-po-chart-labs.component.ts +++ b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-labs/sample-po-chart-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoChartSerie, @@ -12,6 +12,7 @@ import { @Component({ selector: 'sample-po-chart-labs', templateUrl: './sample-po-chart-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoChartLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-stacked/sample-po-chart-stacked.component.ts b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-stacked/sample-po-chart-stacked.component.ts index 4ec989d664..6fe439ab8d 100644 --- a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-stacked/sample-po-chart-stacked.component.ts +++ b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-stacked/sample-po-chart-stacked.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoChartOptions, PoChartSerie, PoChartType } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-chart-stacked', templateUrl: './sample-po-chart-stacked.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoChartStackedComponent { diff --git a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-summary/sample-po-chart-summary.component.ts b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-summary/sample-po-chart-summary.component.ts index 481e4691b9..51f74cd9ca 100644 --- a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-summary/sample-po-chart-summary.component.ts +++ b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-summary/sample-po-chart-summary.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoChartOptions, PoChartSerie, PoChartType } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-chart-summary', templateUrl: './sample-po-chart-summary.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoChartSummaryComponent { diff --git a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-technology-skill/sample-po-chart-technology-skill.component.ts b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-technology-skill/sample-po-chart-technology-skill.component.ts index 05b2bb279b..76ec158e29 100644 --- a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-technology-skill/sample-po-chart-technology-skill.component.ts +++ b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-technology-skill/sample-po-chart-technology-skill.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoChartOptions, PoChartType } from '@po-ui/ng-components'; import { PoChartRadarOptions } from '@po-ui/ng-components/lib/components/po-chart/interfaces/po-chart-radar-options.interface'; @Component({ selector: 'sample-po-chart-technology-skill', templateUrl: './sample-po-chart-technology-skill.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoChartTechnologySkillComponent { diff --git a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-world-exports/sample-po-chart-world-exports.component.ts b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-world-exports/sample-po-chart-world-exports.component.ts index 29f8a7689c..f0d4dd3f4c 100644 --- a/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-world-exports/sample-po-chart-world-exports.component.ts +++ b/projects/ui/src/lib/components/po-chart/samples/sample-po-chart-world-exports/sample-po-chart-world-exports.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoChartOptions, PoChartSerie, PoChartType } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-chart-world-exports', templateUrl: './sample-po-chart-world-exports.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoChartWorldExportsComponent { diff --git a/projects/ui/src/lib/components/po-container/po-container.component.ts b/projects/ui/src/lib/components/po-container/po-container.component.ts index 03ad249444..4b3e312206 100644 --- a/projects/ui/src/lib/components/po-container/po-container.component.ts +++ b/projects/ui/src/lib/components/po-container/po-container.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoContainerBaseComponent } from './po-container-base.component'; @@ -27,6 +27,7 @@ import { PoContainerBaseComponent } from './po-container-base.component'; @Component({ selector: 'po-container', templateUrl: './po-container.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoContainerComponent extends PoContainerBaseComponent {} diff --git a/projects/ui/src/lib/components/po-container/samples/sample-po-container-basic/sample-po-container-basic.component.ts b/projects/ui/src/lib/components/po-container/samples/sample-po-container-basic/sample-po-container-basic.component.ts index 205a98e862..953b013a57 100644 --- a/projects/ui/src/lib/components/po-container/samples/sample-po-container-basic/sample-po-container-basic.component.ts +++ b/projects/ui/src/lib/components/po-container/samples/sample-po-container-basic/sample-po-container-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-container-basic', templateUrl: './sample-po-container-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoContainerBasicComponent {} diff --git a/projects/ui/src/lib/components/po-container/samples/sample-po-container-dashboard/sample-po-container-dashboard.component.ts b/projects/ui/src/lib/components/po-container/samples/sample-po-container-dashboard/sample-po-container-dashboard.component.ts index b88be19d50..87eab6d7f9 100644 --- a/projects/ui/src/lib/components/po-container/samples/sample-po-container-dashboard/sample-po-container-dashboard.component.ts +++ b/projects/ui/src/lib/components/po-container/samples/sample-po-container-dashboard/sample-po-container-dashboard.component.ts @@ -1,4 +1,4 @@ -import { AfterContentChecked, Component, ViewChild, OnInit, inject } from '@angular/core'; +import { AfterContentChecked, Component, ViewChild, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { SampleDashboardService } from './sample-po-container-dashboard.service'; @@ -17,6 +17,7 @@ import { templateUrl: './sample-po-container-dashboard.component.html', styleUrls: ['./sample-po-container-dashboard.component.css'], providers: [SampleDashboardService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoContainerDashboardComponent implements AfterContentChecked, OnInit { diff --git a/projects/ui/src/lib/components/po-container/samples/sample-po-container-labs/sample-po-container-labs.component.ts b/projects/ui/src/lib/components/po-container/samples/sample-po-container-labs/sample-po-container-labs.component.ts index 0610b9a414..852fbd68d7 100644 --- a/projects/ui/src/lib/components/po-container/samples/sample-po-container-labs/sample-po-container-labs.component.ts +++ b/projects/ui/src/lib/components/po-container/samples/sample-po-container-labs/sample-po-container-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-container-labs', templateUrl: './sample-po-container-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoContainerLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-context-menu/po-context-menu-base.component.spec.ts b/projects/ui/src/lib/components/po-context-menu/po-context-menu-base.component.spec.ts index 78cc90d850..8f01386388 100644 --- a/projects/ui/src/lib/components/po-context-menu/po-context-menu-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-context-menu/po-context-menu-base.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { PoContextMenuBaseComponent } from './po-context-menu-base.component'; @@ -6,6 +6,7 @@ import { PoContextMenuItem } from './po-context-menu-item.interface'; @Component({ template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: true }) class PoContextMenuTestComponent extends PoContextMenuBaseComponent {} diff --git a/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-basic/sample-po-context-menu-basic.component.ts b/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-basic/sample-po-context-menu-basic.component.ts index 027747dbe4..6734709175 100644 --- a/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-basic/sample-po-context-menu-basic.component.ts +++ b/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-basic/sample-po-context-menu-basic.component.ts @@ -1,10 +1,11 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoContextMenuItem, PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-context-menu-basic', templateUrl: './sample-po-context-menu-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoContextMenuBasicComponent { diff --git a/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-labs/sample-po-context-menu-labs.component.ts b/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-labs/sample-po-context-menu-labs.component.ts index e1599e1757..05ed1cfa91 100644 --- a/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-labs/sample-po-context-menu-labs.component.ts +++ b/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-labs/sample-po-context-menu-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, inject, signal } from '@angular/core'; +import { Component, inject, signal, ChangeDetectionStrategy } from '@angular/core'; import { PoContextMenuItem, PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-context-menu-labs', templateUrl: './sample-po-context-menu-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoContextMenuLabsComponent { diff --git a/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-user/sample-po-context-menu-user.component.ts b/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-user/sample-po-context-menu-user.component.ts index 2e70b38db4..c87993a2a7 100644 --- a/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-user/sample-po-context-menu-user.component.ts +++ b/projects/ui/src/lib/components/po-context-menu/samples/sample-po-context-menu-user/sample-po-context-menu-user.component.ts @@ -1,10 +1,11 @@ -import { Component, signal, viewChild } from '@angular/core'; +import { Component, signal, viewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoContextMenuItem, PoContextTabsComponent, PoDynamicFormField, PoTabComponent } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-context-menu-user', templateUrl: './sample-po-context-menu-user.component.html', styleUrls: ['./sample-po-context-menu-user.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoContextMenuUserComponent { diff --git a/projects/ui/src/lib/components/po-context-tabs/po-context-tab-button/po-context-tab-button.component.spec.ts b/projects/ui/src/lib/components/po-context-tabs/po-context-tab-button/po-context-tab-button.component.spec.ts index 06635b366c..dafecef386 100644 --- a/projects/ui/src/lib/components/po-context-tabs/po-context-tab-button/po-context-tab-button.component.spec.ts +++ b/projects/ui/src/lib/components/po-context-tabs/po-context-tab-button/po-context-tab-button.component.spec.ts @@ -21,7 +21,7 @@ describe('PoContextTabButtonComponent:', () => { beforeEach(() => { fixture = TestBed.createComponent(PoContextTabButtonComponent); component = fixture.componentInstance; - component.literals = { close: 'Close' }; + component.literals = { close: 'Close Tab' }; nativeElement = fixture.debugElement.nativeElement; }); diff --git a/projects/ui/src/lib/components/po-context-tabs/po-context-tab-button/po-context-tab-button.component.ts b/projects/ui/src/lib/components/po-context-tabs/po-context-tab-button/po-context-tab-button.component.ts index f01af64cb1..9dc7301d31 100644 --- a/projects/ui/src/lib/components/po-context-tabs/po-context-tab-button/po-context-tab-button.component.ts +++ b/projects/ui/src/lib/components/po-context-tabs/po-context-tab-button/po-context-tab-button.component.ts @@ -1,4 +1,13 @@ -import { AfterViewInit, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; +import { + AfterViewInit, + Component, + EventEmitter, + Input, + OnChanges, + Output, + SimpleChanges, + ChangeDetectionStrategy +} from '@angular/core'; import { PoTabButtonComponent } from '../../po-tabs/po-tab-button/po-tab-button.component'; @@ -12,6 +21,7 @@ import { PoTabButtonComponent } from '../../po-tabs/po-tab-button/po-tab-button. @Component({ selector: 'po-context-tab-button', templateUrl: './po-context-tab-button.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoContextTabButtonComponent extends PoTabButtonComponent implements OnChanges, AfterViewInit { diff --git a/projects/ui/src/lib/components/po-context-tabs/po-context-tabs.component.html b/projects/ui/src/lib/components/po-context-tabs/po-context-tabs.component.html index 88b33911eb..c7a36c9fd3 100644 --- a/projects/ui/src/lib/components/po-context-tabs/po-context-tabs.component.html +++ b/projects/ui/src/lib/components/po-context-tabs/po-context-tabs.component.html @@ -1,44 +1,46 @@
    - - - - + @for (tab of tabs; track trackByFn($index, tab)) { + @if (!tab.removed) { + + + } + } - - + @if (isShowTabDropdown) { + + + }
    diff --git a/projects/ui/src/lib/components/po-context-tabs/po-context-tabs.component.ts b/projects/ui/src/lib/components/po-context-tabs/po-context-tabs.component.ts index accdca747a..40e19a5776 100644 --- a/projects/ui/src/lib/components/po-context-tabs/po-context-tabs.component.ts +++ b/projects/ui/src/lib/components/po-context-tabs/po-context-tabs.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoTabComponent, PoTabsComponent } from '../po-tabs'; /** @@ -48,6 +48,7 @@ import { PoTabComponent, PoTabsComponent } from '../po-tabs'; @Component({ selector: 'po-context-tabs', templateUrl: './po-context-tabs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoContextTabsComponent extends PoTabsComponent { diff --git a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-basic/sample-po-context-tabs-basic.component.ts b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-basic/sample-po-context-tabs-basic.component.ts index f5b33e356e..de1bd92df0 100644 --- a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-basic/sample-po-context-tabs-basic.component.ts +++ b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-basic/sample-po-context-tabs-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-context-tabs-basic', templateUrl: './sample-po-context-tabs-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoContextTabsBasicComponent {} diff --git a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-business-conf/sample-po-context-tabs-business-conf.component.html b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-business-conf/sample-po-context-tabs-business-conf.component.html index 5d63cfc311..8e808ee11c 100644 --- a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-business-conf/sample-po-context-tabs-business-conf.component.html +++ b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-business-conf/sample-po-context-tabs-business-conf.component.html @@ -1,64 +1,65 @@ - -
    -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    - + @for (speaker of speakers; track speaker.id) { + +
    +
    +
    +
    + +
    +
    +
    -
    - +
    +
    + +
    +
    + +
    +
    + +
    -
    -
    -
    + +
    -
    - -
    TFace Conference Week
    -
    From 21th September until 26th setember 2018
    -
    -
    -
    - - - - {{ speaker.createdDate | date: 'MM/dd/yyyy' }} +
    + +
    TFace Conference Week
    +
    From 21th September until 26th setember 2018
    +
    +
    +
    + + + + {{ speaker.createdDate | date: 'MM/dd/yyyy' }} +
    +
    + + + + Av. Braz Leme, 1000, Santana +
    -
    - - - - Av. Braz Leme, 1000, Santana +
    + +
    -
    -
    - - -
    -
    + +
    -
    - + + }
    diff --git a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-business-conf/sample-po-context-tabs-business-conf.component.ts b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-business-conf/sample-po-context-tabs-business-conf.component.ts index 327f50a583..7e2c548bd0 100644 --- a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-business-conf/sample-po-context-tabs-business-conf.component.ts +++ b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-business-conf/sample-po-context-tabs-business-conf.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService, PoContextTabsComponent } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-context-tabs-business-conf', templateUrl: './sample-po-context-tabs-business-conf.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoContextTabsBusinessConfComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-labs/sample-po-context-tabs-labs.component.html b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-labs/sample-po-context-tabs-labs.component.html index bca707f093..fe89969c8b 100644 --- a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-labs/sample-po-context-tabs-labs.component.html +++ b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-labs/sample-po-context-tabs-labs.component.html @@ -1,16 +1,17 @@ - -
    Tab Content {{ i }}
    -
    + @for (tab of tabs; track $index; let i = $index) { + +
    Tab Content {{ i }}
    +
    + }
    diff --git a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-labs/sample-po-context-tabs-labs.component.ts b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-labs/sample-po-context-tabs-labs.component.ts index f95818b50f..12f7441d7a 100644 --- a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-labs/sample-po-context-tabs-labs.component.ts +++ b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-labs/sample-po-context-tabs-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoDynamicFormField, @@ -11,6 +11,7 @@ import { @Component({ selector: 'sample-po-context-tabs-labs', templateUrl: './sample-po-context-tabs-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoContextTabsLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-travel/sample-po-context-tabs-travel.component.ts b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-travel/sample-po-context-tabs-travel.component.ts index 70e44f1017..3f99ca3523 100644 --- a/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-travel/sample-po-context-tabs-travel.component.ts +++ b/projects/ui/src/lib/components/po-context-tabs/samples/sample-po-context-tabs-travel/sample-po-context-tabs-travel.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService, PoRadioGroupOption, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-context-tabs-travel', templateUrl: './sample-po-context-tabs-travel.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoContextTabsTravelComponent { diff --git a/projects/ui/src/lib/components/po-disclaimer-group/po-disclaimer-remove/po-disclaimer-remove.component.ts b/projects/ui/src/lib/components/po-disclaimer-group/po-disclaimer-remove/po-disclaimer-remove.component.ts index 1f35404d8e..9fff1a4126 100644 --- a/projects/ui/src/lib/components/po-disclaimer-group/po-disclaimer-remove/po-disclaimer-remove.component.ts +++ b/projects/ui/src/lib/components/po-disclaimer-group/po-disclaimer-remove/po-disclaimer-remove.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from '@angular/core'; /** * @docsPrivate * @@ -10,6 +10,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector: 'po-disclaimer-remove', templateUrl: './po-disclaimer-remove.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoDisclaimerRemoveComponent { diff --git a/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-basic/sample-po-disclaimer-group-basic.component.ts b/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-basic/sample-po-disclaimer-group-basic.component.ts index c9b3a6447a..44394a3314 100644 --- a/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-basic/sample-po-disclaimer-group-basic.component.ts +++ b/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-basic/sample-po-disclaimer-group-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-disclaimer-group-basic', templateUrl: './sample-po-disclaimer-group-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDisclaimerGroupBasicComponent {} diff --git a/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-labs/sample-po-disclaimer-group-labs.component.ts b/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-labs/sample-po-disclaimer-group-labs.component.ts index b9450266c7..5b684fc180 100644 --- a/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-labs/sample-po-disclaimer-group-labs.component.ts +++ b/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-labs/sample-po-disclaimer-group-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoDisclaimer } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-disclaimer-group-labs', templateUrl: './sample-po-disclaimer-group-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDisclaimerGroupLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-sw-planets/sample-po-disclaimer-group-sw-planets.component.ts b/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-sw-planets/sample-po-disclaimer-group-sw-planets.component.ts index af67590219..d3d6d950a1 100644 --- a/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-sw-planets/sample-po-disclaimer-group-sw-planets.component.ts +++ b/projects/ui/src/lib/components/po-disclaimer-group/samples/sample-po-disclaimer-group-sw-planets/sample-po-disclaimer-group-sw-planets.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoComboOption, PoDisclaimer, PoTableColumn } from '@po-ui/ng-components'; @@ -8,6 +8,7 @@ import { SamplePoDisclaimerGroupSwPlanetsService } from './sample-po-disclaimer- selector: 'sample-po-disclaimer-group-sw-planets', templateUrl: './sample-po-disclaimer-group-sw-planets.component.html', providers: [SamplePoDisclaimerGroupSwPlanetsService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDisclaimerGroupSwPlanetsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-disclaimer/po-disclaimer.component.ts b/projects/ui/src/lib/components/po-disclaimer/po-disclaimer.component.ts index b90bd1ffe1..0b1f42ff2d 100644 --- a/projects/ui/src/lib/components/po-disclaimer/po-disclaimer.component.ts +++ b/projects/ui/src/lib/components/po-disclaimer/po-disclaimer.component.ts @@ -19,6 +19,7 @@ import { PoDisclaimerBaseComponent } from './po-disclaimer-base.component'; @Component({ selector: 'po-disclaimer', templateUrl: './po-disclaimer.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoDisclaimerComponent extends PoDisclaimerBaseComponent { diff --git a/projects/ui/src/lib/components/po-disclaimer/samples/sample-po-disclaimer.component.ts b/projects/ui/src/lib/components/po-disclaimer/samples/sample-po-disclaimer.component.ts index b4516a6df3..76d54fb8e3 100644 --- a/projects/ui/src/lib/components/po-disclaimer/samples/sample-po-disclaimer.component.ts +++ b/projects/ui/src/lib/components/po-disclaimer/samples/sample-po-disclaimer.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-disclaimer', templateUrl: './sample-po-disclaimer.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDisclaimerComponent { diff --git a/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-basic/sample-po-divider-basic.component.ts b/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-basic/sample-po-divider-basic.component.ts index 3e26129609..0ebb3b9fb3 100644 --- a/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-basic/sample-po-divider-basic.component.ts +++ b/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-basic/sample-po-divider-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-divider-basic', templateUrl: './sample-po-divider-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDividerBasicComponent {} diff --git a/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-labs/sample-po-divider-labs.component.ts b/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-labs/sample-po-divider-labs.component.ts index 26da20b7b1..e2d6703b16 100644 --- a/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-labs/sample-po-divider-labs.component.ts +++ b/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-labs/sample-po-divider-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-divider-labs', templateUrl: './sample-po-divider-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDividerLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-user-detail/sample-po-divider-user-detail.component.ts b/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-user-detail/sample-po-divider-user-detail.component.ts index 2cc01f135e..e0b73df0fa 100644 --- a/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-user-detail/sample-po-divider-user-detail.component.ts +++ b/projects/ui/src/lib/components/po-divider/samples/sample-po-divider-user-detail/sample-po-divider-user-detail.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; import { PoBreadcrumb } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoBreadcrumb } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-divider-user-detail', templateUrl: './sample-po-divider-user-detail.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDividerUserDetailComponent { diff --git a/projects/ui/src/lib/components/po-dropdown/po-dropdown.component.spec.ts b/projects/ui/src/lib/components/po-dropdown/po-dropdown.component.spec.ts index c5c9181847..40d1f434df 100644 --- a/projects/ui/src/lib/components/po-dropdown/po-dropdown.component.spec.ts +++ b/projects/ui/src/lib/components/po-dropdown/po-dropdown.component.spec.ts @@ -1,5 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { PoUtils as UtilsFunction } from '../../utils/util'; @@ -20,8 +21,9 @@ describe('PoDropdownComponent: ', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([])], - declarations: [PoDropdownComponent, PoPopupComponent] + imports: [RouterModule.forRoot([])], + declarations: [PoDropdownComponent, PoPopupComponent], + providers: [provideLocationMocks()] }) .overrideComponent(PoDropdownComponent, { set: { changeDetection: ChangeDetectionStrategy.Default } diff --git a/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-basic/sample-po-dropdown-basic.component.ts b/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-basic/sample-po-dropdown-basic.component.ts index 080b9264e2..26db633a9e 100644 --- a/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-basic/sample-po-dropdown-basic.component.ts +++ b/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-basic/sample-po-dropdown-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-dropdown-basic', templateUrl: './sample-po-dropdown-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDropdownBasicComponent {} diff --git a/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-labs/sample-po-dropdown-labs.component.ts b/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-labs/sample-po-dropdown-labs.component.ts index 0613fbadbb..5c05353ee9 100644 --- a/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-labs/sample-po-dropdown-labs.component.ts +++ b/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-labs/sample-po-dropdown-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, @@ -11,6 +11,7 @@ import { @Component({ selector: 'sample-po-dropdown-labs', templateUrl: './sample-po-dropdown-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDropdownLabsComponent implements OnInit { @@ -130,7 +131,7 @@ export class SamplePoDropdownLabsComponent implements OnInit { label: undefined, visible: null, parent: undefined - } as any; + }; } showAction(label: string): void { diff --git a/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-social-network/sample-po-dropdown-social-network.component.ts b/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-social-network/sample-po-dropdown-social-network.component.ts index 7996f37a2c..08a7032e42 100644 --- a/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-social-network/sample-po-dropdown-social-network.component.ts +++ b/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-social-network/sample-po-dropdown-social-network.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-dropdown-social-network', templateUrl: './sample-po-dropdown-social-network.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDropdownSocialNetworkComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-subitems/sample-po-dropdown-subitems.component.ts b/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-subitems/sample-po-dropdown-subitems.component.ts index 8c14a7db03..01566635b4 100644 --- a/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-subitems/sample-po-dropdown-subitems.component.ts +++ b/projects/ui/src/lib/components/po-dropdown/samples/sample-po-dropdown-subitems/sample-po-dropdown-subitems.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoDropdownAction } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-dropdown-subitems', templateUrl: './sample-po-dropdown-subitems.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDropdownSubitemsComponent { diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-container/po-dynamic-container.component.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-container/po-dynamic-container.component.ts index 54d4be5643..6b3e51a326 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-container/po-dynamic-container.component.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-container/po-dynamic-container.component.ts @@ -1,8 +1,9 @@ -import { Component, Input, TemplateRef } from '@angular/core'; +import { Component, Input, TemplateRef, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'po-dynamic-container', templateUrl: './po-dynamic-container.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoDynamicContainerComponent { diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-fields/po-dynamic-form-fields.component.spec.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-fields/po-dynamic-form-fields.component.spec.ts index cb612f6f67..4df2039e9b 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-fields/po-dynamic-form-fields.component.spec.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-fields/po-dynamic-form-fields.component.spec.ts @@ -4,7 +4,7 @@ import { FormsModule, NgForm, ReactiveFormsModule } from '@angular/forms'; import { of } from 'rxjs'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { provideHttpClientTesting } from '@angular/common/http/testing'; import { PoDynamicModule } from '../../po-dynamic.module'; import { PoDynamicFormField } from '../interfaces/po-dynamic-form-field.interface'; @@ -22,7 +22,7 @@ describe('PoDynamicFormFieldsComponent: ', () => { imports: [FormsModule, ReactiveFormsModule, PoDynamicModule], providers: [ { provide: NgForm, useValue: new NgForm(null, null) }, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }).compileComponents(); diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-fields/po-dynamic-form-fields.component.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-fields/po-dynamic-form-fields.component.ts index 5122914b61..094c23ac8f 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-fields/po-dynamic-form-fields.component.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-fields/po-dynamic-form-fields.component.ts @@ -1,5 +1,14 @@ import { TitleCasePipe } from '@angular/common'; -import { ChangeDetectorRef, Component, OnChanges, QueryList, SimpleChanges, ViewChildren, inject } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + OnChanges, + QueryList, + SimpleChanges, + ViewChildren, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { ControlContainer, NgForm } from '@angular/forms'; import { PoDynamicFormField } from '../interfaces/po-dynamic-form-field.interface'; @@ -19,6 +28,7 @@ import { PoDynamicFormFieldsBaseComponent } from './po-dynamic-form-fields-base. templateUrl: 'po-dynamic-form-fields.component.html', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], providers: [PoDynamicFormValidationService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoDynamicFormFieldsComponent extends PoDynamicFormFieldsBaseComponent implements OnChanges { diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-load/po-dynamic-form-load.service.spec.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-load/po-dynamic-form-load.service.spec.ts index 18b7d2afc2..4bb8705fbe 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-load/po-dynamic-form-load.service.spec.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-load/po-dynamic-form-load.service.spec.ts @@ -4,7 +4,7 @@ import { TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; import { PoDynamicFormLoadService } from './po-dynamic-form-load.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoDynamicFormLoadService:', () => { let service: PoDynamicFormLoadService; @@ -15,7 +15,11 @@ describe('PoDynamicFormLoadService:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoDynamicFormLoadService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoDynamicFormLoadService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); service = TestBed.inject(PoDynamicFormLoadService); diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-operation/po-dynamic-form-operation.spec.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-operation/po-dynamic-form-operation.spec.ts index c229404dbf..3dd6524743 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-operation/po-dynamic-form-operation.spec.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-operation/po-dynamic-form-operation.spec.ts @@ -1,4 +1,4 @@ -import { HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { HttpClient, provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; @@ -17,7 +17,7 @@ describe('PoDynamicFormOperation:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting()] }); httpMock = TestBed.inject(HttpTestingController); diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-validation/po-dynamic-form-validation.service.spec.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-validation/po-dynamic-form-validation.service.spec.ts index 55c77ed124..6feaf7db28 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-validation/po-dynamic-form-validation.service.spec.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form-validation/po-dynamic-form-validation.service.spec.ts @@ -3,7 +3,7 @@ import { TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { PoDynamicFormField } from '../interfaces/po-dynamic-form-field.interface'; import { PoDynamicFormValidationService } from './po-dynamic-form-validation.service'; @@ -20,7 +20,7 @@ describe('PoDynamicFormValidationService:', () => { imports: [], providers: [ PoDynamicFormValidationService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }); diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form.component.spec.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form.component.spec.ts index f10bb645c6..1eb7e6d379 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form.component.spec.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form.component.spec.ts @@ -7,7 +7,7 @@ import { PoDynamicFormBaseComponent } from './po-dynamic-form-base.component'; import { PoDynamicFormComponent } from './po-dynamic-form.component'; import { PoDynamicModule } from '../po-dynamic.module'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoDynamicFormComponent:', () => { let component: PoDynamicFormComponent; @@ -18,7 +18,7 @@ describe('PoDynamicFormComponent:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [PoDynamicModule], - providers: [NgForm, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [NgForm, provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting()] }).compileComponents(); fixture = TestBed.createComponent(PoDynamicFormComponent); diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form.component.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form.component.ts index aaaef9b506..afab153a39 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form.component.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/po-dynamic-form.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { Observable, Subject, Subscription } from 'rxjs'; @@ -37,6 +37,7 @@ import { PoDynamicFormValidationService } from './po-dynamic-form-validation/po- @Component({ selector: 'po-dynamic-form', templateUrl: './po-dynamic-form.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoDynamicFormComponent extends PoDynamicFormBaseComponent implements OnInit, OnDestroy { diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-basic/sample-po-dynamic-form-basic.component.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-basic/sample-po-dynamic-form-basic.component.ts index 188e8f2a74..f5a824b5aa 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-basic/sample-po-dynamic-form-basic.component.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-basic/sample-po-dynamic-form-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-dynamic-form-basic', templateUrl: './sample-po-dynamic-form-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDynamicFormBasicComponent {} diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-container/sample-po-dynamic-form-container.component.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-container/sample-po-dynamic-form-container.component.ts index 2018f78bc3..a8eec291ed 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-container/sample-po-dynamic-form-container.component.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-container/sample-po-dynamic-form-container.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { ForceBooleanComponentEnum, @@ -15,6 +15,7 @@ import { PoDynamicFormContainerService } from './sample-po-dynamic-form-containe selector: 'sample-po-dynamic-form-container', templateUrl: './sample-po-dynamic-form-container.component.html', providers: [PoDynamicFormContainerService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDynamicFormContainerComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-register/sample-po-dynamic-form-register.component.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-register/sample-po-dynamic-form-register.component.ts index ca4a269881..a3290bb495 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-register/sample-po-dynamic-form-register.component.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-form/samples/sample-po-dynamic-form-register/sample-po-dynamic-form-register.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoDynamicFormField, @@ -14,6 +14,7 @@ import { PoDynamicFormRegisterService } from './sample-po-dynamic-form-register. selector: 'sample-po-dynamic-form-register', templateUrl: './sample-po-dynamic-form-register.component.html', providers: [PoDynamicFormRegisterService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDynamicFormRegisterComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/po-dynamic-view.component.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/po-dynamic-view.component.ts index 1a6f2b91cc..f265e7699d 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/po-dynamic-view.component.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/po-dynamic-view.component.ts @@ -1,5 +1,5 @@ import { CurrencyPipe, DatePipe, DecimalPipe, TitleCasePipe } from '@angular/common'; -import { Component, OnChanges, OnInit, SimpleChanges, inject } from '@angular/core'; +import { Component, OnChanges, OnInit, SimpleChanges, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoTimePipe } from '../../../pipes/po-time/po-time.pipe'; @@ -38,6 +38,7 @@ import { PoMultiselectFilterService } from '../../po-field/po-multiselect/po-mul @Component({ selector: 'po-dynamic-view', templateUrl: './po-dynamic-view.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoDynamicViewComponent extends PoDynamicViewBaseComponent implements OnChanges, OnInit { diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-basic/sample-po-dynamic-view-basic.component.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-basic/sample-po-dynamic-view-basic.component.ts index 4d8203939f..3a6cd636cc 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-basic/sample-po-dynamic-view-basic.component.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-basic/sample-po-dynamic-view-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-dynamic-view-basic', templateUrl: './sample-po-dynamic-view-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDynamicViewBasicComponent {} diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-container/sample-po-dynamic-view-container.component.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-container/sample-po-dynamic-view-container.component.ts index 877527f1f8..66a31fb096 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-container/sample-po-dynamic-view-container.component.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-container/sample-po-dynamic-view-container.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoDynamicViewField } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-dynamic-view-container', templateUrl: './sample-po-dynamic-view-container.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDynamicViewContainerComponent { diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-employee-on-load/sample-po-dynamic-view-employee-on-load.component.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-employee-on-load/sample-po-dynamic-view-employee-on-load.component.ts index 37b44fdcc6..1170160519 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-employee-on-load/sample-po-dynamic-view-employee-on-load.component.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-employee-on-load/sample-po-dynamic-view-employee-on-load.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoDynamicViewField } from '@po-ui/ng-components'; import { SamplePoDynamicViewEmployeeOnLoadService } from './sample-po-dynamic-view-employee-on-load.service'; @@ -7,6 +7,7 @@ import { SamplePoDynamicViewEmployeeOnLoadService } from './sample-po-dynamic-vi selector: 'sample-po-dynamic-view-employee-on-load', templateUrl: './sample-po-dynamic-view-employee-on-load.component.html', providers: [SamplePoDynamicViewEmployeeOnLoadService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDynamicViewEmployeeOnLoadComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-employee/sample-po-dynamic-view-employee.component.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-employee/sample-po-dynamic-view-employee.component.ts index 54a75f9ecb..292d29cb54 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-employee/sample-po-dynamic-view-employee.component.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/samples/sample-po-dynamic-view-employee/sample-po-dynamic-view-employee.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoDynamicViewField } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-dynamic-view-employee', templateUrl: './sample-po-dynamic-view-employee.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDynamicViewEmployeeComponent { diff --git a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/services/po-dynamic-view.service.spec.ts b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/services/po-dynamic-view.service.spec.ts index bdcfdf7751..3869d87ae6 100644 --- a/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/services/po-dynamic-view.service.spec.ts +++ b/projects/ui/src/lib/components/po-dynamic/po-dynamic-view/services/po-dynamic-view.service.spec.ts @@ -2,7 +2,7 @@ import { HttpTestingController, provideHttpClientTesting } from '@angular/common import { TestBed, fakeAsync, tick } from '@angular/core/testing'; import { PoDynamicViewService } from './po-dynamic-view.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoDynamicViewService:', () => { let httpMock: HttpTestingController; @@ -11,7 +11,11 @@ describe('PoDynamicViewService:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoDynamicViewService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoDynamicViewService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); poDynamicViewService = TestBed.inject(PoDynamicViewService); diff --git a/projects/ui/src/lib/components/po-field/po-checkbox-group/po-checkbox-group-base.component.spec.ts b/projects/ui/src/lib/components/po-field/po-checkbox-group/po-checkbox-group-base.component.spec.ts index 5c4b21c7e5..cf15db26a1 100644 --- a/projects/ui/src/lib/components/po-field/po-checkbox-group/po-checkbox-group-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-checkbox-group/po-checkbox-group-base.component.spec.ts @@ -7,12 +7,13 @@ import { expectPropertiesValues } from './../../../util-test/util-expect.spec'; import { PoThemeA11yEnum } from '../../../services'; import { PoCheckboxGroupOption } from './interfaces/po-checkbox-group-option.interface'; import { PoCheckboxGroupBaseComponent } from './po-checkbox-group-base.component'; -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; @Component({ selector: 'po-checkbox-group-base-host', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class PoCheckboxGroupBaseHostComponent extends PoCheckboxGroupBaseComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-basic/sample-po-checkbox-group-basic.component.ts b/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-basic/sample-po-checkbox-group-basic.component.ts index 689b1a1fd8..43c8bf068e 100644 --- a/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-basic/sample-po-checkbox-group-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-basic/sample-po-checkbox-group-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-checkbox-group-basic', templateUrl: './sample-po-checkbox-group-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCheckboxGroupBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-labs/sample-po-checkbox-group-labs.component.ts b/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-labs/sample-po-checkbox-group-labs.component.ts index d07fa69195..79a531e5cf 100644 --- a/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-labs/sample-po-checkbox-group-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-labs/sample-po-checkbox-group-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-checkbox-group-labs', templateUrl: './sample-po-checkbox-group-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCheckboxGroupLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-password-policy/sample-po-checkbox-group-password-policy.component.ts b/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-password-policy/sample-po-checkbox-group-password-policy.component.ts index dc797c18f2..cae29522aa 100644 --- a/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-password-policy/sample-po-checkbox-group-password-policy.component.ts +++ b/projects/ui/src/lib/components/po-field/po-checkbox-group/samples/sample-po-checkbox-group-password-policy/sample-po-checkbox-group-password-policy.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption } from '@po-ui/ng-components'; @@ -7,6 +7,7 @@ import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-checkbox-group-password-policy', templateUrl: './sample-po-checkbox-group-password-policy.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCheckboxGroupPasswordPolicyComponent { diff --git a/projects/ui/src/lib/components/po-field/po-checkbox/po-checkbox-base.component.spec.ts b/projects/ui/src/lib/components/po-field/po-checkbox/po-checkbox-base.component.spec.ts index a179a2f18a..d87a424180 100644 --- a/projects/ui/src/lib/components/po-field/po-checkbox/po-checkbox-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-checkbox/po-checkbox-base.component.spec.ts @@ -1,4 +1,4 @@ -import { Component, Directive } from '@angular/core'; +import { Component, Directive, ChangeDetectionStrategy } from '@angular/core'; import { expectPropertiesValues } from '../../../util-test/util-expect.spec'; @@ -9,6 +9,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; @Component({ selector: 'po-checkbox-base-host', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class PoCheckboxBaseHostComponent extends PoCheckboxBaseComponent { diff --git a/projects/ui/src/lib/components/po-field/po-checkbox/po-checkbox-base.component.ts b/projects/ui/src/lib/components/po-field/po-checkbox/po-checkbox-base.component.ts index 82c03c48e1..1c7773db56 100644 --- a/projects/ui/src/lib/components/po-field/po-checkbox/po-checkbox-base.component.ts +++ b/projects/ui/src/lib/components/po-field/po-checkbox/po-checkbox-base.component.ts @@ -6,7 +6,8 @@ import { HostListener, input, Input, - Output + Output, + ChangeDetectionStrategy } from '@angular/core'; import { ControlValueAccessor } from '@angular/forms'; @@ -60,6 +61,7 @@ import { PoHelperOptions } from '../../po-helper'; @Component({ selector: 'po-checkbox-base', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export abstract class PoCheckboxBaseComponent implements ControlValueAccessor { diff --git a/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-acceptance-term/sample-po-checkbox-acceptance-term.component.ts b/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-acceptance-term/sample-po-checkbox-acceptance-term.component.ts index d679199279..8b75b044ee 100644 --- a/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-acceptance-term/sample-po-checkbox-acceptance-term.component.ts +++ b/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-acceptance-term/sample-po-checkbox-acceptance-term.component.ts @@ -1,10 +1,11 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoModalAction, PoModalComponent } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-checkbox-acceptance-term', templateUrl: './sample-po-checkbox-acceptance-term.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCheckboxAcceptanceTermComponent { diff --git a/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-basic/sample-po-checkbox-basic.component.ts b/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-basic/sample-po-checkbox-basic.component.ts index d97fea01e2..57845e8a3f 100644 --- a/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-basic/sample-po-checkbox-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-basic/sample-po-checkbox-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-checkbox-basic', templateUrl: './sample-po-checkbox-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCheckboxBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-labs/sample-po-checkbox-labs.component.ts b/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-labs/sample-po-checkbox-labs.component.ts index fa177760af..fbbf7b9d4c 100644 --- a/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-labs/sample-po-checkbox-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-checkbox/samples/sample-po-checkbox-labs/sample-po-checkbox-labs.component.ts @@ -1,8 +1,9 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-checkbox-labs', templateUrl: './sample-po-checkbox-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCheckboxLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-clean/po-clean.component.ts b/projects/ui/src/lib/components/po-field/po-clean/po-clean.component.ts index cd0f082b8b..f6ce213349 100644 --- a/projects/ui/src/lib/components/po-field/po-clean/po-clean.component.ts +++ b/projects/ui/src/lib/components/po-field/po-clean/po-clean.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoCleanBaseComponent } from './po-clean-base.component'; @@ -17,6 +17,7 @@ import { PoCleanBaseComponent } from './po-clean-base.component'; @Component({ selector: 'po-clean', templateUrl: './po-clean.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoCleanComponent extends PoCleanBaseComponent { diff --git a/projects/ui/src/lib/components/po-field/po-clean/samples/sample-po-clean-labs.component.ts b/projects/ui/src/lib/components/po-field/po-clean/samples/sample-po-clean-labs.component.ts index 47a31e9309..1eda89e6dd 100644 --- a/projects/ui/src/lib/components/po-field/po-clean/samples/sample-po-clean-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-clean/samples/sample-po-clean-labs.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-clean-labs', templateUrl: './sample-po-clean-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoCleanLabsComponent { diff --git a/projects/ui/src/lib/components/po-field/po-combo/po-combo-filter.service.spec.ts b/projects/ui/src/lib/components/po-field/po-combo/po-combo-filter.service.spec.ts index 61bb52e163..aa37b6c55b 100644 --- a/projects/ui/src/lib/components/po-field/po-combo/po-combo-filter.service.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-combo/po-combo-filter.service.spec.ts @@ -1,5 +1,5 @@ import { TestBed } from '@angular/core/testing'; -import { HttpRequest, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { HttpRequest, provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { PoComboFilterService } from './po-combo-filter.service'; @@ -14,7 +14,11 @@ describe('PoComboFilterService ', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoComboFilterService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoComboFilterService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); comboService = TestBed.inject(PoComboFilterService); diff --git a/projects/ui/src/lib/components/po-field/po-combo/po-combo.component.spec.ts b/projects/ui/src/lib/components/po-field/po-combo/po-combo.component.spec.ts index df6ee22335..1516e46ce1 100644 --- a/projects/ui/src/lib/components/po-field/po-combo/po-combo.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-combo/po-combo.component.spec.ts @@ -1,6 +1,6 @@ import { By } from '@angular/platform-browser'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; -import { HttpClient, HttpHandler, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { HttpClient, HttpHandler, provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { Observable, of, throwError } from 'rxjs'; @@ -2021,7 +2021,7 @@ describe('PoComboComponent - with service:', () => { HttpClient, HttpHandler, PoComboFilterService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }).compileComponents(); diff --git a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-basic/sample-po-combo-basic.component.ts b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-basic/sample-po-combo-basic.component.ts index 470405b2a7..0629c9853b 100644 --- a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-basic/sample-po-combo-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-basic/sample-po-combo-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-combo-basic', templateUrl: './sample-po-combo-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoComboBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-heroes-reactive-form/sample-po-combo-heroes-reactive-form.component.ts b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-heroes-reactive-form/sample-po-combo-heroes-reactive-form.component.ts index 3e05809934..de7733cc46 100644 --- a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-heroes-reactive-form/sample-po-combo-heroes-reactive-form.component.ts +++ b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-heroes-reactive-form/sample-po-combo-heroes-reactive-form.component.ts @@ -1,5 +1,5 @@ import { HttpClient } from '@angular/common/http'; -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { Observable } from 'rxjs'; @@ -7,6 +7,7 @@ import { Observable } from 'rxjs'; @Component({ selector: 'sample-po-combo-heroes-reactive-form', templateUrl: './sample-po-combo-heroes-reactive-form.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoComboHeroesReactiveFormComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-heroes/sample-po-combo-heroes.component.ts b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-heroes/sample-po-combo-heroes.component.ts index 0fea53dba5..b3bae30182 100644 --- a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-heroes/sample-po-combo-heroes.component.ts +++ b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-heroes/sample-po-combo-heroes.component.ts @@ -1,11 +1,12 @@ import { HttpClient } from '@angular/common/http'; -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ selector: 'sample-po-combo-heroes', templateUrl: './sample-po-combo-heroes.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoComboHeroesComponent { diff --git a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-hotels/sample-po-combo-hotels.component.ts b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-hotels/sample-po-combo-hotels.component.ts index fe98867367..9255b0914b 100644 --- a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-hotels/sample-po-combo-hotels.component.ts +++ b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-hotels/sample-po-combo-hotels.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, inject } from '@angular/core'; +import { Component, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoDatepickerComponent, PoNotificationService, PoSelectOption } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoDatepickerComponent, PoNotificationService, PoSelectOption } from '@p @Component({ selector: 'sample-po-combo-hotels', templateUrl: './sample-po-combo-hotels.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoComboHotelsComponent { diff --git a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-infinity-scroll/sample-po-combo-infinity-scroll.component.ts b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-infinity-scroll/sample-po-combo-infinity-scroll.component.ts index d67d427b0c..e92dcfbb2b 100644 --- a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-infinity-scroll/sample-po-combo-infinity-scroll.component.ts +++ b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-infinity-scroll/sample-po-combo-infinity-scroll.component.ts @@ -1,10 +1,11 @@ import { HttpClient } from '@angular/common/http'; -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { Observable } from 'rxjs'; @Component({ selector: 'sample-po-combo-infinity-scroll', templateUrl: './sample-po-combo-infinity-scroll.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoComboInfinityScrollComponent { diff --git a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-labs/sample-po-combo-labs.component.ts b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-labs/sample-po-combo-labs.component.ts index f1b6b91d3f..539dc2f618 100644 --- a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-labs/sample-po-combo-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-labs/sample-po-combo-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, @@ -12,6 +12,7 @@ import { @Component({ selector: 'sample-po-combo-labs', templateUrl: './sample-po-combo-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoComboLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-scheduling/sample-po-combo-scheduling.component.ts b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-scheduling/sample-po-combo-scheduling.component.ts index beccb4744f..4ec3f6a6db 100644 --- a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-scheduling/sample-po-combo-scheduling.component.ts +++ b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-scheduling/sample-po-combo-scheduling.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoComboOption, PoComboOptionGroup, PoNotificationService, PoSelectOption } from '@po-ui/ng-components'; @@ -9,6 +9,7 @@ import { SamplePoComboSchedulingService } from './sample-po-combo-scheduling.ser templateUrl: './sample-po-combo-scheduling.component.html', styleUrls: ['./sample-po-combo-scheduling.component.css'], providers: [SamplePoComboSchedulingService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoComboSchedulingComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-transfer/sample-po-combo-transfer.component.ts b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-transfer/sample-po-combo-transfer.component.ts index 79a0693291..4d8fa66363 100644 --- a/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-transfer/sample-po-combo-transfer.component.ts +++ b/projects/ui/src/lib/components/po-field/po-combo/samples/sample-po-combo-transfer/sample-po-combo-transfer.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, inject } from '@angular/core'; +import { Component, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoModalAction, PoModalComponent, PoNotificationService, PoSelectOption } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoModalAction, PoModalComponent, PoNotificationService, PoSelectOption @Component({ selector: 'sample-po-combo-transfer', templateUrl: './sample-po-combo-transfer.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoComboTransferComponent { diff --git a/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-basic/sample-po-datepicker-range-basic.component.ts b/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-basic/sample-po-datepicker-range-basic.component.ts index 8b9acd7bff..832f5fd129 100644 --- a/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-basic/sample-po-datepicker-range-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-basic/sample-po-datepicker-range-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-datepicker-range-basic', templateUrl: './sample-po-datepicker-range-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatepickerRangeBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-labs/sample-po-datepicker-range-labs.component.ts b/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-labs/sample-po-datepicker-range-labs.component.ts index 082ae720df..79008f1165 100644 --- a/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-labs/sample-po-datepicker-range-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-labs/sample-po-datepicker-range-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, @@ -12,6 +12,7 @@ import { @Component({ selector: 'sample-po-datepicker-range-labs', templateUrl: './sample-po-datepicker-range-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatepickerRangeLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-presets/sample-po-datepicker-range-presets.component.ts b/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-presets/sample-po-datepicker-range-presets.component.ts index 20e1e0c05b..0ac52fc577 100644 --- a/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-presets/sample-po-datepicker-range-presets.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-presets/sample-po-datepicker-range-presets.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-datepicker-range-presets', templateUrl: './sample-po-datepicker-range-presets.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatepickerRangePresetsComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-vacations-reactive-form/sample-po-datepicker-range-vacations-reactive-form.component.ts b/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-vacations-reactive-form/sample-po-datepicker-range-vacations-reactive-form.component.ts index 7da8802778..16230a69c5 100644 --- a/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-vacations-reactive-form/sample-po-datepicker-range-vacations-reactive-form.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-vacations-reactive-form/sample-po-datepicker-range-vacations-reactive-form.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { PoDatepickerRange, PoModalAction, PoModalComponent, PoNotificationService } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoDatepickerRange, PoModalAction, PoModalComponent, PoNotificationServi @Component({ selector: 'sample-po-datepicker-range-vacations-reactive-form', templateUrl: './sample-po-datepicker-range-vacations-reactive-form.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatepickerRangeVacationsReactiveFormComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-vacations/sample-po-datepicker-range-vacations.component.ts b/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-vacations/sample-po-datepicker-range-vacations.component.ts index feedafeb93..860e18934f 100644 --- a/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-vacations/sample-po-datepicker-range-vacations.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datepicker-range/samples/sample-po-datepicker-range-vacations/sample-po-datepicker-range-vacations.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, inject } from '@angular/core'; +import { Component, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { PoDatepickerRange, PoModalAction, PoModalComponent, PoNotificationService } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoDatepickerRange, PoModalAction, PoModalComponent, PoNotificationServi @Component({ selector: 'sample-po-datepicker-range-vacations', templateUrl: './sample-po-datepicker-range-vacations.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatepickerRangeVacationsComponent { diff --git a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-airfare-reactive-form/sample-po-datepicker-airfare-reactive-form.component.ts b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-airfare-reactive-form/sample-po-datepicker-airfare-reactive-form.component.ts index 1b700b28af..34280f15d5 100644 --- a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-airfare-reactive-form/sample-po-datepicker-airfare-reactive-form.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-airfare-reactive-form/sample-po-datepicker-airfare-reactive-form.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { PoDialogService, PoNotificationService, PoSelectOption } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoDialogService, PoNotificationService, PoSelectOption } from '@po-ui/n @Component({ selector: 'sample-po-datepicker-airfare-reactive-form', templateUrl: './sample-po-datepicker-airfare-reactive-form.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatepickerAirfareReactiveFormComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-airfare/sample-po-datepicker-airfare.component.ts b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-airfare/sample-po-datepicker-airfare.component.ts index 00d0295d33..08656079d8 100644 --- a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-airfare/sample-po-datepicker-airfare.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-airfare/sample-po-datepicker-airfare.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, inject } from '@angular/core'; +import { Component, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { PoDialogService, PoNotificationService, PoSelectOption } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoDialogService, PoNotificationService, PoSelectOption } from '@po-ui/n @Component({ selector: 'sample-po-datepicker-airfare', templateUrl: './sample-po-datepicker-airfare.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatepickerAirfareComponent { diff --git a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-basic/sample-po-datepicker-basic.component.ts b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-basic/sample-po-datepicker-basic.component.ts index eba58f6496..c613ca1b51 100644 --- a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-basic/sample-po-datepicker-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-basic/sample-po-datepicker-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-datepicker-basic', templateUrl: './sample-po-datepicker-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatepickerBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-labs/sample-po-datepicker-labs.component.ts b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-labs/sample-po-datepicker-labs.component.ts index 16149bb42f..8c786aee55 100644 --- a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-labs/sample-po-datepicker-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-labs/sample-po-datepicker-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoDatepickerIsoFormat, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-datepicker-labs', templateUrl: './sample-po-datepicker-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatepickerLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-month-year/sample-po-datepicker-month-year.component.ts b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-month-year/sample-po-datepicker-month-year.component.ts index 818d1d66fc..7db9de34ff 100644 --- a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-month-year/sample-po-datepicker-month-year.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-month-year/sample-po-datepicker-month-year.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-datepicker-month-year', templateUrl: './sample-po-datepicker-month-year.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatepickerMonthYearComponent { diff --git a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-year/sample-po-datepicker-year.component.ts b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-year/sample-po-datepicker-year.component.ts index 99ed2b2c84..caa1ff742c 100644 --- a/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-year/sample-po-datepicker-year.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datepicker/samples/sample-po-datepicker-year/sample-po-datepicker-year.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-datepicker-year', templateUrl: './sample-po-datepicker-year.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatepickerYearComponent { diff --git a/projects/ui/src/lib/components/po-field/po-datetimepicker/po-datetimepicker.component.spec.ts b/projects/ui/src/lib/components/po-field/po-datetimepicker/po-datetimepicker.component.spec.ts index 7f4959a732..6ff99e20f1 100644 --- a/projects/ui/src/lib/components/po-field/po-datetimepicker/po-datetimepicker.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-datetimepicker/po-datetimepicker.component.spec.ts @@ -18,10 +18,44 @@ describe('PoDatetimepickerComponent:', () => { component = fixture.componentInstance; nativeElement = fixture.nativeElement; + // Diversos testes atribuem um `objMask` mockado parcial (ex.: apenas + // `{ valueToModel }`), sem os métodos `blur`/`keyup`/`keydown`/`click`. Como o + // ambiente roda com `teardown: { destroyAfterEach: false }`, a instância + // permanece no DOM e o listener `(blur)` do template continua ativo; quando o + // foco sai do input (de forma assíncrona, por outros specs ou pelo teardown + // geral), `eventOnBlur` executa `this.objMask?.blur()` e lança + // `TypeError: this.objMask?.blur is not a function`. + // + // Sem alterar o componente, interceptamos as atribuições de `objMask` para + // garantir, de forma centralizada e à prova de timing, que os métodos usados + // pelos handlers existam como no-op quando o mock não os fornecer. Mocks que + // definem seus próprios métodos (ex.: spies) são preservados. + let objMaskValue: any; + Object.defineProperty(component, 'objMask', { + configurable: true, + get: () => objMaskValue, + set: (value: any) => { + if (value && typeof value === 'object') { + for (const method of ['blur', 'keyup', 'keydown', 'click'] as const) { + if (typeof value[method] !== 'function') { + value[method] = () => {}; + } + } + } + objMaskValue = value; + } + }); + fixture.componentRef.setInput('p-locale', 'pt'); fixture.detectChanges(); }); + afterEach(() => { + // Garante o ngOnDestroy -> removeListeners() e remove o elemento (com seus + // listeners) do DOM, evitando que listeners vazem entre os testes. + fixture?.destroy(); + }); + it('should create', () => { expect(component).toBeTruthy(); }); @@ -1521,10 +1555,21 @@ describe('PoDatetimepickerComponent:', () => { describe('initializeListeners:', () => { it('should register click listener that calls wasClickedOnPicker', () => { spyOn(component, 'wasClickedOnPicker'); + + // Captura o callback registrado para 'click' no document ao invés de disparar + // um evento global em `document`, que acionaria listeners vazados de outras + // instâncias/testes e tornaria o teste intermitente. + let clickCallback: (event: MouseEvent) => void; + spyOn(component['renderer'], 'listen').and.callFake((target: any, eventName: string, callback: any) => { + if (target === 'document' && eventName === 'click') { + clickCallback = callback; + } + return () => {}; + }); + component['initializeListeners'](); - const event = new MouseEvent('click'); - document.dispatchEvent(event); + clickCallback(new MouseEvent('click')); expect(component.wasClickedOnPicker).toHaveBeenCalled(); component['removeListeners'](); diff --git a/projects/ui/src/lib/components/po-field/po-datetimepicker/po-datetimepicker.component.ts b/projects/ui/src/lib/components/po-field/po-datetimepicker/po-datetimepicker.component.ts index 0959e0849b..aa98ecb772 100644 --- a/projects/ui/src/lib/components/po-field/po-datetimepicker/po-datetimepicker.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datetimepicker/po-datetimepicker.component.ts @@ -8,7 +8,8 @@ import { forwardRef, HostListener, AfterViewInit, - ChangeDetectorRef + ChangeDetectorRef, + ChangeDetectionStrategy } from '@angular/core'; import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms'; @@ -70,6 +71,7 @@ const providers = [ selector: 'po-datetimepicker', templateUrl: './po-datetimepicker.component.html', providers, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoDatetimepickerComponent extends PoDatetimepickerBaseComponent implements AfterViewInit, OnDestroy { diff --git a/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-12h-seconds/sample-po-datetimepicker-12h-seconds.component.ts b/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-12h-seconds/sample-po-datetimepicker-12h-seconds.component.ts index 903d29e6b8..2b9a3ab3e4 100644 --- a/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-12h-seconds/sample-po-datetimepicker-12h-seconds.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-12h-seconds/sample-po-datetimepicker-12h-seconds.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-datetimepicker-12h-seconds', templateUrl: './sample-po-datetimepicker-12h-seconds.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatetimepicker12hSecondsComponent { diff --git a/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-basic/sample-po-datetimepicker-basic.component.ts b/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-basic/sample-po-datetimepicker-basic.component.ts index de3e94aa49..816911d15c 100644 --- a/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-basic/sample-po-datetimepicker-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-basic/sample-po-datetimepicker-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-datetimepicker-basic', templateUrl: './sample-po-datetimepicker-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatetimepickerBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-labs/sample-po-datetimepicker-labs.component.ts b/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-labs/sample-po-datetimepicker-labs.component.ts index c6505c374e..0cedeaeef0 100644 --- a/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-labs/sample-po-datetimepicker-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-labs/sample-po-datetimepicker-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-datetimepicker-labs', templateUrl: './sample-po-datetimepicker-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatetimepickerLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-scheduling/sample-po-datetimepicker-scheduling.component.ts b/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-scheduling/sample-po-datetimepicker-scheduling.component.ts index afee80dcde..04dd4d5ca6 100644 --- a/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-scheduling/sample-po-datetimepicker-scheduling.component.ts +++ b/projects/ui/src/lib/components/po-field/po-datetimepicker/samples/sample-po-datetimepicker-scheduling/sample-po-datetimepicker-scheduling.component.ts @@ -1,11 +1,12 @@ import { UntypedFormControl } from '@angular/forms'; -import { Component, ViewChild, inject } from '@angular/core'; +import { Component, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoDialogService, PoNotificationService, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-datetimepicker-scheduling', templateUrl: './sample-po-datetimepicker-scheduling.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDatetimepickerSchedulingComponent { diff --git a/projects/ui/src/lib/components/po-field/po-decimal/po-decimal.component.spec.ts b/projects/ui/src/lib/components/po-field/po-decimal/po-decimal.component.spec.ts index 0b8b0a5dac..2394a8f240 100644 --- a/projects/ui/src/lib/components/po-field/po-decimal/po-decimal.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-decimal/po-decimal.component.spec.ts @@ -189,6 +189,7 @@ describe('PoDecimalComponent:', () => { describe('decimalsLength: ', () => { it('should call refreshOnPropertyChange when set', () => { fixture.detectChanges(); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spy = spyOn(component as never, 'refreshOnPropertyChange' as never); component.decimalsLength = 4; @@ -200,6 +201,7 @@ describe('PoDecimalComponent:', () => { describe('thousandMaxlength: ', () => { it('should call refreshOnPropertyChange when set', () => { fixture.detectChanges(); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spy = spyOn(component as never, 'refreshOnPropertyChange' as never); component.thousandMaxlength = 8; @@ -1837,6 +1839,7 @@ describe('PoDecimalComponent:', () => { it('should not call setViewValue when modelValue is null', () => { fixture.detectChanges(); component['setViewValue'](''); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spy = spyOn(component as never, 'setViewValue' as never); component['refreshOnPropertyChange'](); @@ -1846,6 +1849,7 @@ describe('PoDecimalComponent:', () => { it('should not call setViewValue when inputEl is undefined', () => { component.inputEl = undefined; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spy = spyOn(component as never, 'setViewValue' as never); component['refreshOnPropertyChange'](); @@ -1900,6 +1904,7 @@ describe('PoDecimalComponent:', () => { it('should apply format on blur when formatParsed is active and value is valid', () => { const fakeEvent = { target: { value: '1234,56' } }; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spy = spyOn(component as never, 'setViewValue' as never).and.callThrough(); component.onBlur(fakeEvent); @@ -1911,6 +1916,7 @@ describe('PoDecimalComponent:', () => { it('should clear model when value results in null model', () => { const fakeEvent = { target: { value: '' } }; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(component as never, 'callOnChange' as never); component.onBlur(fakeEvent); @@ -1923,6 +1929,7 @@ describe('PoDecimalComponent:', () => { fixture.detectChanges(); const fakeEvent = { target: { value: '99999,99' } }; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spy = spyOn(component as never, 'setViewValue' as never).and.callThrough(); component.onBlur(fakeEvent); @@ -1932,6 +1939,7 @@ describe('PoDecimalComponent:', () => { it('should call callOnChange with undefined when model value is undefined', () => { const fakeEvent = { target: { value: 'ABC' } }; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(component as never, 'callOnChange' as never); component.onBlur(fakeEvent); @@ -1983,6 +1991,7 @@ describe('PoDecimalComponent:', () => { } }; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(component as never, 'setViewValue' as never).and.callThrough(); component.onInput(fakeEvent); @@ -2003,6 +2012,7 @@ describe('PoDecimalComponent:', () => { } }; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spy = spyOn(component as never, 'setViewValue' as never).and.callThrough(); component.onInput(fakeEvent); @@ -2021,6 +2031,7 @@ describe('PoDecimalComponent:', () => { } }; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(component as never, 'callOnChange' as never); component.onInput(fakeEvent); @@ -2099,6 +2110,7 @@ describe('PoDecimalComponent:', () => { }); it('should format value using advanced format when formatParsed is active', () => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spy = spyOn(component as never, 'setViewValue' as never).and.callThrough(); component.writeValueModel(1234.56); @@ -2112,6 +2124,7 @@ describe('PoDecimalComponent:', () => { fixture.componentRef.setInput('p-display-format', '99.99'); fixture.detectChanges(); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spy = spyOn(component as never, 'setViewValue' as never).and.callThrough(); component.writeValueModel(9999.99); @@ -2129,6 +2142,7 @@ describe('PoDecimalComponent:', () => { }); it('should format string value parsed to number', () => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const spy = spyOn(component as never, 'setViewValue' as never).and.callThrough(); component.writeValueModel('4567.89'); diff --git a/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-basic/sample-po-decimal-basic.component.ts b/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-basic/sample-po-decimal-basic.component.ts index eb6db18251..7a0c97f289 100644 --- a/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-basic/sample-po-decimal-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-basic/sample-po-decimal-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-decimal-basic', templateUrl: './sample-po-decimal-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDecimalBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-hourly-wage-reactive-form/sample-po-decimal-hourly-wage-reactive-form.component.ts b/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-hourly-wage-reactive-form/sample-po-decimal-hourly-wage-reactive-form.component.ts index 4b23d56820..1e473c3d86 100644 --- a/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-hourly-wage-reactive-form/sample-po-decimal-hourly-wage-reactive-form.component.ts +++ b/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-hourly-wage-reactive-form/sample-po-decimal-hourly-wage-reactive-form.component.ts @@ -1,9 +1,10 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; @Component({ selector: 'sample-po-decimal-hourly-wage-reactive-form', templateUrl: './sample-po-decimal-hourly-wage-reactive-form.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDecimalHourlyWageReactiveFormComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-hourly-wage/sample-po-decimal-hourly-wage.component.ts b/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-hourly-wage/sample-po-decimal-hourly-wage.component.ts index 979c05f0e3..8d745f81db 100644 --- a/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-hourly-wage/sample-po-decimal-hourly-wage.component.ts +++ b/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-hourly-wage/sample-po-decimal-hourly-wage.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-decimal-hourly-wage', templateUrl: './sample-po-decimal-hourly-wage.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDecimalHourlyWageComponent { diff --git a/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-labs/sample-po-decimal-labs.component.ts b/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-labs/sample-po-decimal-labs.component.ts index a24f3b8532..079c1fcaa0 100644 --- a/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-labs/sample-po-decimal-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-decimal/samples/sample-po-decimal-labs/sample-po-decimal-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-decimal-labs', templateUrl: './sample-po-decimal-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDecimalLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-basic/sample-po-email-basic.component.ts b/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-basic/sample-po-email-basic.component.ts index 6fd48786d8..df1a34fd85 100644 --- a/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-basic/sample-po-email-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-basic/sample-po-email-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-email-basic', templateUrl: './sample-po-email-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoEmailBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-labs/sample-po-email-labs.component.ts b/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-labs/sample-po-email-labs.component.ts index 9838e3f550..a0de165f44 100644 --- a/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-labs/sample-po-email-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-labs/sample-po-email-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-email-labs', templateUrl: './sample-po-email-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoEmailLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-newsletter/sample-po-email-newsletter.component.ts b/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-newsletter/sample-po-email-newsletter.component.ts index 4fc43bce62..cac8456129 100644 --- a/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-newsletter/sample-po-email-newsletter.component.ts +++ b/projects/ui/src/lib/components/po-field/po-email/samples/sample-po-email-newsletter/sample-po-email-newsletter.component.ts @@ -1,10 +1,11 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoDialogService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-email-newsletter', templateUrl: './sample-po-email-newsletter.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoEmailNewsletterComponent { diff --git a/projects/ui/src/lib/components/po-field/po-input-generic/po-input-generic.spec.ts b/projects/ui/src/lib/components/po-field/po-input-generic/po-input-generic.spec.ts index f4d9bd4fbc..600c454725 100644 --- a/projects/ui/src/lib/components/po-field/po-input-generic/po-input-generic.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-input-generic/po-input-generic.spec.ts @@ -1,6 +1,6 @@ import { AbstractControl } from '@angular/forms'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; -import { ChangeDetectorRef, Component, ElementRef, EventEmitter, inject } from '@angular/core'; +import { ChangeDetectorRef, Component, ElementRef, EventEmitter, inject, ChangeDetectionStrategy } from '@angular/core'; import { configureTestSuite } from './../../../util-test/util-expect.spec'; @@ -13,6 +13,7 @@ import { of, Subscription } from 'rxjs'; `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class ContentProjectionComponent extends PoInputGeneric { diff --git a/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-basic/sample-po-input-basic.component.ts b/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-basic/sample-po-input-basic.component.ts index bfa541de10..51eae9ee64 100644 --- a/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-basic/sample-po-input-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-basic/sample-po-input-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-input-basic', templateUrl: './sample-po-input-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoInputBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-labs/sample-po-input-labs.component.ts b/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-labs/sample-po-input-labs.component.ts index 694ed2edd7..06a59b6aa6 100644 --- a/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-labs/sample-po-input-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-labs/sample-po-input-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-input-labs', templateUrl: './sample-po-input-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoInputLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-reactive-form/sample-po-input-reactive-form.component.ts b/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-reactive-form/sample-po-input-reactive-form.component.ts index 0d0b4e7809..ea990d6e02 100644 --- a/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-reactive-form/sample-po-input-reactive-form.component.ts +++ b/projects/ui/src/lib/components/po-field/po-input/samples/sample-po-input-reactive-form/sample-po-input-reactive-form.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, inject } from '@angular/core'; +import { Component, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { PoModalAction, PoModalComponent } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoModalAction, PoModalComponent } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-input-reactive-form', templateUrl: './sample-po-input-reactive-form.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoInputReactiveFormComponent { diff --git a/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-basic/sample-po-login-basic.component.ts b/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-basic/sample-po-login-basic.component.ts index 3f30c9d30c..177d9a473d 100644 --- a/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-basic/sample-po-login-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-basic/sample-po-login-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-login-basic', templateUrl: './sample-po-login-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLoginBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-confirm/sample-po-login-confirm.component.ts b/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-confirm/sample-po-login-confirm.component.ts index 8fa5623de2..4dbecd8202 100644 --- a/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-confirm/sample-po-login-confirm.component.ts +++ b/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-confirm/sample-po-login-confirm.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, inject } from '@angular/core'; +import { Component, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoModalAction, PoModalComponent } from '@po-ui/ng-components'; import { PoNotificationService } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-login-confirm', templateUrl: './sample-po-login-confirm.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLoginConfirmComponent { diff --git a/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-labs/sample-po-login-labs.component.ts b/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-labs/sample-po-login-labs.component.ts index d59caf2bad..0080f78408 100644 --- a/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-labs/sample-po-login-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-login/samples/sample-po-login-labs/sample-po-login-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-login-labs', templateUrl: './sample-po-login-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLoginLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-base.component.spec.ts b/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-base.component.spec.ts index bc5e6aa5c9..ab7791a3c5 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-base.component.spec.ts @@ -49,7 +49,12 @@ describe('PoLookupBaseComponent:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [], - providers: [LookupFilterService, Injector, NgControl, PoLookupModalService] + providers: [ + LookupFilterService, + Injector, + { provide: NgControl, useValue: { control: new UntypedFormControl() } }, + PoLookupModalService + ] }).compileComponents(); defaultService = new PoLookupFilterService(undefined); diff --git a/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal-base.component.spec.ts b/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal-base.component.spec.ts index d21fe19c63..8e5893ee95 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal-base.component.spec.ts @@ -9,7 +9,7 @@ import { PoTableColumnSortType } from '../../../po-table/enums/po-table-column-s import { PoTableColumnSort } from '../../../po-table/interfaces/po-table-column-sort.interface'; import { PoLookupResponseApi } from '../interfaces/po-lookup-response-api.interface'; import { poLookupLiteralsDefault, PoLookupModalBaseComponent } from './po-lookup-modal-base.component'; -import { convertToBoolean } from 'projects/ui/src/lib/utils/util'; +import { convertToBoolean } from '../../../../utils/util'; @Directive() class PoLookupModalComponent extends PoLookupModalBaseComponent { diff --git a/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal.component.spec.ts b/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal.component.spec.ts index dd0f23c909..5e0efdbb7b 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal.component.spec.ts @@ -1,6 +1,6 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, discardPeriodicTasks, fakeAsync, flush, TestBed, tick } from '@angular/core/testing'; +import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing'; import { provideRouter } from '@angular/router'; import { Observable, of } from 'rxjs'; import { PoLookupFilter } from '../../../../components/po-field/po-lookup/interfaces/po-lookup-filter.interface'; @@ -10,10 +10,10 @@ import { PoComponentInjectorService } from '../../../../services/po-component-in import { PoDynamicModule } from '../../../po-dynamic/po-dynamic.module'; import { PoTableColumnSortType } from '../../../po-table/enums/po-table-column-sort-type.enum'; import { PoTableColumnSort } from '../../../po-table/interfaces/po-table-column-sort.interface'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { PoTableColumnSpacing } from '../../../po-table'; -import { PoFieldSize } from 'projects/ui/src/lib/enums/po-field-size.enum'; -import { PoThemeA11yEnum } from 'projects/ui/src/public-api'; +import { PoFieldSize } from '../../../../enums/po-field-size.enum'; +import { PoThemeA11yEnum } from '../../../../../public-api'; class LookupFilterService implements PoLookupFilter { getFilteredItems(params: any): Observable { @@ -38,7 +38,7 @@ describe('PoLookupModalComponent', () => { providers: [ LookupFilterService, PoComponentInjectorService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting(), provideRouter([]) ] @@ -333,17 +333,16 @@ describe('PoLookupModalComponent', () => { }); describe('AdvancedSearch: ', () => { - beforeEach(fakeAsync(() => { + beforeEach(async () => { component.advancedFilters = advancedFilters; fixture.detectChanges(); component.onAdvancedFilter(); + await (component as any).dynamicFormReady; - tick(10); fixture.detectChanges(); - - flush(); - discardPeriodicTasks(); - })); + await fixture.whenStable(); + fixture.detectChanges(); + }); afterEach(() => { component.advancedFilters = []; diff --git a/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal.component.ts b/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal.component.ts index cd3b3dba67..7aacdc71b9 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal.component.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/po-lookup-modal/po-lookup-modal.component.ts @@ -43,6 +43,8 @@ export class PoLookupModalComponent extends PoLookupModalBaseComponent implement componentRef: ComponentRef; dynamicForm: NgForm; + private dynamicFormReady: Promise; + constructor() { const poLanguage = inject(PoLanguageService); const changeDetector = inject(ChangeDetectorRef); @@ -142,9 +144,9 @@ export class PoLookupModalComponent extends PoLookupModalBaseComponent implement } } - onAdvancedFilter() { + onAdvancedFilter(): void { this.setupModalAdvancedFilter(); - this.createDynamicForm(); + this.dynamicFormReady = this.createDynamicForm(); } private setTableHeight(): void { @@ -192,25 +194,27 @@ export class PoLookupModalComponent extends PoLookupModalBaseComponent implement // PoDynamicFormComponent -> PoDynamicFormFieldsComponent-> PoLookupComponent -> // PoLookupModalService -> PoLookupModalComponent -> PoDynamicFormComponent - // eslint-disable-next-line @typescript-eslint/naming-convention - import('./../../../po-dynamic/po-dynamic-form/po-dynamic-form.component').then(({ PoDynamicFormComponent }) => { - this.componentRef = this.container.createComponent(PoDynamicFormComponent); - this.componentRef.instance.fields = this.advancedFilters; - this.componentRef.instance.value = this.dynamicFormValue; - this.componentRef.instance.componentsSize = this.size; - - this.componentRef.instance.formOutput - .pipe( - tap((form: NgForm) => { - this.dynamicForm = form; + return import('./../../../po-dynamic/po-dynamic-form/po-dynamic-form.component').then( + // eslint-disable-next-line @typescript-eslint/naming-convention + ({ PoDynamicFormComponent }) => { + this.componentRef = this.container.createComponent(PoDynamicFormComponent); + this.componentRef.instance.fields = this.advancedFilters; + this.componentRef.instance.value = this.dynamicFormValue; + this.componentRef.instance.componentsSize = this.size; + + this.componentRef.instance.formOutput + .pipe( + tap((form: NgForm) => { + this.dynamicForm = form; + this.primaryActionAdvancedFilter.disabled = this.dynamicForm.invalid; + }), + switchMap((form: NgForm) => form.valueChanges) + ) + .subscribe(() => { this.primaryActionAdvancedFilter.disabled = this.dynamicForm.invalid; - }), - switchMap((form: NgForm) => form.valueChanges) - ) - .subscribe(() => { - this.primaryActionAdvancedFilter.disabled = this.dynamicForm.invalid; - }); - this.changeDetector.markForCheck(); - }); + }); + this.changeDetector.markForCheck(); + } + ); } } diff --git a/projects/ui/src/lib/components/po-field/po-lookup/po-lookup.component.spec.ts b/projects/ui/src/lib/components/po-field/po-lookup/po-lookup.component.spec.ts index af96e88934..6952666478 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/po-lookup.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/po-lookup.component.spec.ts @@ -1,7 +1,7 @@ import { ComponentRef, EventEmitter, Injector } from '@angular/core'; import { ComponentFixture, fakeAsync, flush, inject, TestBed, tick } from '@angular/core/testing'; -import { Routes } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { Routes, RouterModule } from '@angular/router'; import { Observable, of } from 'rxjs'; @@ -9,7 +9,7 @@ import { PoFieldModule } from '../../../components/po-field'; import { PoComponentInjectorService } from '../../../services/po-component-injector/po-component-injector.service'; import { PoControlPositionService } from '../../../services/po-control-position/po-control-position.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { provideHttpClientTesting } from '@angular/common/http/testing'; import { NgControl } from '@angular/forms'; import { PoFieldSize } from '../../../enums/po-field-size.enum'; @@ -44,14 +44,15 @@ describe('PoLookupComponent:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes(routes), PoFieldModule], + imports: [RouterModule.forRoot(routes), PoFieldModule], providers: [ + provideLocationMocks(), LookupFilterService, PoComponentInjectorService, PoControlPositionService, Injector, - NgControl, - provideHttpClient(withInterceptorsFromDi()), + { provide: NgControl, useValue: { control: null } }, + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }).compileComponents(); diff --git a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-basic/sample-po-lookup-basic.component.ts b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-basic/sample-po-lookup-basic.component.ts index d71b617426..3247679a1d 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-basic/sample-po-lookup-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-basic/sample-po-lookup-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-lookup-basic', templateUrl: './sample-po-lookup-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLookupBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-hero-reactive-form/sample-po-lookup-hero-reactive-form.component.ts b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-hero-reactive-form/sample-po-lookup-hero-reactive-form.component.ts index 9a23b0869e..a4c9c11001 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-hero-reactive-form/sample-po-lookup-hero-reactive-form.component.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-hero-reactive-form/sample-po-lookup-hero-reactive-form.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { PoLookupColumn, PoSelectOption } from '@po-ui/ng-components'; @@ -11,6 +11,7 @@ import { SamplePoLookupService } from '../sample-po-lookup.service'; selector: 'sample-po-lookup-hero-reactive-form', templateUrl: './sample-po-lookup-hero-reactive-form.component.html', providers: [SamplePoLookupService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLookupHeroReactiveFormComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-hero/sample-po-lookup-hero.component.ts b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-hero/sample-po-lookup-hero.component.ts index 57ea5c63d7..425652eef4 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-hero/sample-po-lookup-hero.component.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-hero/sample-po-lookup-hero.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoLookupColumn, PoSelectOption } from '@po-ui/ng-components'; @@ -10,6 +10,7 @@ import { SamplePoLookupService } from '../sample-po-lookup.service'; selector: 'sample-po-lookup-hero', templateUrl: './sample-po-lookup-hero.component.html', providers: [SamplePoLookupService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLookupHeroComponent { diff --git a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-labs/sample-po-lookup-labs.component.ts b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-labs/sample-po-lookup-labs.component.ts index 8d08d7700e..cea0562607 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-labs/sample-po-lookup-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-labs/sample-po-lookup-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, @@ -17,6 +17,7 @@ import { SamplePoLookupService } from '../sample-po-lookup.service'; selector: 'sample-po-lookup-labs', templateUrl: './sample-po-lookup-labs.component.html', providers: [SamplePoLookupService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLookupLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-multiple/sample-po-lookup-multiple.component.ts b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-multiple/sample-po-lookup-multiple.component.ts index 20239ef01a..822b833e6e 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-multiple/sample-po-lookup-multiple.component.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-multiple/sample-po-lookup-multiple.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoTableColumn } from '@po-ui/ng-components'; import { SamplePoLookupMultipleService } from './sample-po-lookup-multiple.service'; @@ -7,6 +7,7 @@ import { SamplePoLookupMultipleService } from './sample-po-lookup-multiple.servi selector: 'sample-po-lookup-multiple', templateUrl: './sample-po-lookup-multiple.component.html', styles: [], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLookupMultipleComponent { diff --git a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-sw-films/sample-po-lookup-sw-films.component.ts b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-sw-films/sample-po-lookup-sw-films.component.ts index 46318f35b0..82971833e8 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-sw-films/sample-po-lookup-sw-films.component.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/samples/sample-po-lookup-sw-films/sample-po-lookup-sw-films.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoRadioGroupOption } from '@po-ui/ng-components'; import { SamplePoLookupSwFilmsService } from './sample-po-lookup-sw-films.service'; @@ -6,6 +6,7 @@ import { SamplePoLookupSwFilmsService } from './sample-po-lookup-sw-films.servic selector: 'sample-po-lookup-sw-films', templateUrl: './sample-po-lookup-sw-films.component.html', providers: [SamplePoLookupSwFilmsService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLookupSwFilmsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-lookup/services/po-lookup-filter.service.spec.ts b/projects/ui/src/lib/components/po-field/po-lookup/services/po-lookup-filter.service.spec.ts index 53b37d0485..ee6332ccd5 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/services/po-lookup-filter.service.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/services/po-lookup-filter.service.spec.ts @@ -1,7 +1,7 @@ import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { PoLookupFilterService } from './po-lookup-filter.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoLookupFilterService', () => { let service: PoLookupFilterService; @@ -10,7 +10,11 @@ describe('PoLookupFilterService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoLookupFilterService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoLookupFilterService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); service = TestBed.inject(PoLookupFilterService); diff --git a/projects/ui/src/lib/components/po-field/po-lookup/services/po-lookup-modal.service.spec.ts b/projects/ui/src/lib/components/po-field/po-lookup/services/po-lookup-modal.service.spec.ts index 4e0747277e..4c9447c2b2 100644 --- a/projects/ui/src/lib/components/po-field/po-lookup/services/po-lookup-modal.service.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-lookup/services/po-lookup-modal.service.spec.ts @@ -1,7 +1,7 @@ import { ComponentRef, EventEmitter, NO_ERRORS_SCHEMA } from '@angular/core'; -import { RouterTestingModule } from '@angular/router/testing'; -import { Routes } from '@angular/router'; +import { Routes, RouterModule } from '@angular/router'; import { TestBed } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; import { Observable, of } from 'rxjs'; @@ -11,7 +11,7 @@ import { PoFieldModule } from '../../../../components/po-field/po-field.module'; import { PoLookupFilter } from '../../../../components/po-field/po-lookup/interfaces/po-lookup-filter.interface'; import { PoLookupModalService } from '../../../../components/po-field/po-lookup/services/po-lookup-modal.service'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; class LookupFilterService implements PoLookupFilter { getObjectByValue(id: string): Observable { @@ -58,13 +58,14 @@ describe('PoLookupModalService:', () => { beforeEach(() => { TestBed.configureTestingModule({ schemas: [NO_ERRORS_SCHEMA], - imports: [RouterTestingModule.withRoutes(routes), PoFieldModule], + imports: [RouterModule.forRoot(routes), PoFieldModule], providers: [ + provideLocationMocks(), LookupFilterService, PoComponentInjectorService, PoControlPositionService, PoLookupModalService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }); diff --git a/projects/ui/src/lib/components/po-field/po-multiselect/po-multiselect-filter.service.spec.ts b/projects/ui/src/lib/components/po-field/po-multiselect/po-multiselect-filter.service.spec.ts index 14c6321918..93e79ab21e 100644 --- a/projects/ui/src/lib/components/po-field/po-multiselect/po-multiselect-filter.service.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-multiselect/po-multiselect-filter.service.spec.ts @@ -1,5 +1,5 @@ import { TestBed } from '@angular/core/testing'; -import { HttpRequest, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { HttpRequest, provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { PoMultiselectFilterService } from './po-multiselect-filter.service'; @@ -12,7 +12,11 @@ describe('PoMultiSelectFilterService ', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoMultiselectFilterService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoMultiselectFilterService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); multiSelectService = TestBed.inject(PoMultiselectFilterService); diff --git a/projects/ui/src/lib/components/po-field/po-multiselect/po-multiselect.component.spec.ts b/projects/ui/src/lib/components/po-field/po-multiselect/po-multiselect.component.spec.ts index 6bbbb73024..c56db07aa1 100644 --- a/projects/ui/src/lib/components/po-field/po-multiselect/po-multiselect.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-multiselect/po-multiselect.component.spec.ts @@ -1,5 +1,5 @@ import { OverlayModule } from '@angular/cdk/overlay'; -import { HttpClient, HttpHandler, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { HttpClient, HttpHandler, provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { ComponentFixture, fakeAsync, flush, TestBed, tick } from '@angular/core/testing'; import { Observable, of, throwError } from 'rxjs'; @@ -65,7 +65,7 @@ describe('PoMultiselectComponent:', () => { Renderer2, PoMultiselectFilterService, PoControlPositionService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }).compileComponents(); @@ -761,6 +761,31 @@ describe('PoMultiselectComponent:', () => { expect(fakeThis.visibleElement).toBeFalsy(); }); + it(`ngDoCheck: should call debounceResize via second condition when element is already visible + but isCalculateVisibleItems is true`, () => { + // Primeiro grupo falha em !visibleElement (visibleElement = true), forçando a + // avaliação do segundo grupo (inputWidth && isCalculateVisibleItems), que cobre + // o ramo do isCalculateVisibleItems. + const fakeThis = { + inputElement: { + nativeElement: { + offsetWidth: 10 + } + }, + visibleElement: true, + initialized: true, + isCalculateVisibleItems: true, + debounceResize: () => true + }; + + spyOn(fakeThis, 'debounceResize'); + + component.ngDoCheck.call(fakeThis); + + expect(fakeThis.debounceResize).toHaveBeenCalled(); + expect(fakeThis.visibleElement).toBeTruthy(); + }); + it('ngOnDestroy: should call removeListeners and call unsubscribe from subscription', () => { const removeListenersSpy = spyOn(component, 'removeListeners'); component['getObjectsByValuesSubscription'] = { unsubscribe: () => {} }; diff --git a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-any-array/sample-po-multiselect-any-array.component.ts b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-any-array/sample-po-multiselect-any-array.component.ts index 6cd953366f..4f40072e1e 100644 --- a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-any-array/sample-po-multiselect-any-array.component.ts +++ b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-any-array/sample-po-multiselect-any-array.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-multiselect-any-array', templateUrl: './sample-po-multiselect-any-array.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMultiselectAnyArrayComponent { diff --git a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-basic/sample-po-multiselect-basic.component.ts b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-basic/sample-po-multiselect-basic.component.ts index 754817d32d..072223862b 100644 --- a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-basic/sample-po-multiselect-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-basic/sample-po-multiselect-basic.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoMultiselectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-multiselect-basic', templateUrl: './sample-po-multiselect-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMultiselectBasicComponent { diff --git a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-heroes/sample-po-multiselect-heroes.component.ts b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-heroes/sample-po-multiselect-heroes.component.ts index f73737c1da..5c1961494b 100644 --- a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-heroes/sample-po-multiselect-heroes.component.ts +++ b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-heroes/sample-po-multiselect-heroes.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoTableColumn, PoMultiselectFilter } from '@po-ui/ng-components'; import { SamplePoMultiselectHeroesService } from './sample-po-multiselect-heroes.service'; @@ -7,6 +7,7 @@ import { SamplePoMultiselectHeroesService } from './sample-po-multiselect-heroes selector: 'sample-po-multiselect-heroes', templateUrl: './sample-po-multiselect-heroes.component.html', providers: [SamplePoMultiselectHeroesService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMultiselectHeroesComponent { diff --git a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-labs/sample-po-multiselect-labs.component.ts b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-labs/sample-po-multiselect-labs.component.ts index a97022717b..5136b2b714 100644 --- a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-labs/sample-po-multiselect-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-labs/sample-po-multiselect-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, @@ -10,6 +10,7 @@ import { @Component({ selector: 'sample-po-multiselect-labs', templateUrl: './sample-po-multiselect-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMultiselectLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-template/sample-po-multiselect-template.component.ts b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-template/sample-po-multiselect-template.component.ts index 5d189d0832..b8f1add215 100644 --- a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-template/sample-po-multiselect-template.component.ts +++ b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-template/sample-po-multiselect-template.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-multiselect-template', templateUrl: './sample-po-multiselect-template.component.html', styleUrls: ['./sample-po-multiselect-template.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMultiselectTemplateComponent { diff --git a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-vacation-reactive-form/sample-po-multiselect-vacation-reactive-form.component.ts b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-vacation-reactive-form/sample-po-multiselect-vacation-reactive-form.component.ts index 154dc24c08..e7a2422f4e 100644 --- a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-vacation-reactive-form/sample-po-multiselect-vacation-reactive-form.component.ts +++ b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-vacation-reactive-form/sample-po-multiselect-vacation-reactive-form.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { PoMultiselectOption, PoRadioGroupOption } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoMultiselectOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-multiselect-vacation-reactive-form', templateUrl: './sample-po-multiselect-vacation-reactive-form.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMultiselectVacationReactiveFormComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-vacation/sample-po-multiselect-vacation.component.ts b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-vacation/sample-po-multiselect-vacation.component.ts index 75d63bc9e5..32966342be 100644 --- a/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-vacation/sample-po-multiselect-vacation.component.ts +++ b/projects/ui/src/lib/components/po-field/po-multiselect/samples/sample-po-multiselect-vacation/sample-po-multiselect-vacation.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoMultiselectOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-multiselect-vacation', templateUrl: './sample-po-multiselect-vacation.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMultiselectVacationComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-number/po-number-base.component.spec.ts b/projects/ui/src/lib/components/po-field/po-number/po-number-base.component.spec.ts index 00c6469cce..0093ab34b9 100644 --- a/projects/ui/src/lib/components/po-field/po-number/po-number-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-number/po-number-base.component.spec.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component, ElementRef, inject } from '@angular/core'; +import { ChangeDetectorRef, Component, ElementRef, inject, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AbstractControl } from '@angular/forms'; @@ -13,6 +13,7 @@ import { PoNumberBaseComponent } from './po-number-base.component'; `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class ContentProjectionComponent extends PoNumberBaseComponent { diff --git a/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-basic/sample-po-number-basic.component.ts b/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-basic/sample-po-number-basic.component.ts index 95daddbf00..9210a512bb 100644 --- a/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-basic/sample-po-number-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-basic/sample-po-number-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-number-basic', templateUrl: './sample-po-number-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoNumberBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-calculate/sample-po-number-calculate.component.ts b/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-calculate/sample-po-number-calculate.component.ts index 4215c32322..6e9cb2fd79 100644 --- a/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-calculate/sample-po-number-calculate.component.ts +++ b/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-calculate/sample-po-number-calculate.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-number-calculate', templateUrl: './sample-po-number-calculate.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoNumberCalculateComponent { diff --git a/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-labs/sample-po-number-labs.component.ts b/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-labs/sample-po-number-labs.component.ts index 626aab041f..e7daaabaad 100644 --- a/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-labs/sample-po-number-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-number/samples/sample-po-number-labs/sample-po-number-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-number-labs', templateUrl: './sample-po-number-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoNumberLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-basic/sample-po-password-basic.component.ts b/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-basic/sample-po-password-basic.component.ts index cb5a8bade5..27545d56eb 100644 --- a/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-basic/sample-po-password-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-basic/sample-po-password-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-password-basic', templateUrl: './sample-po-password-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPasswordBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-labs/sample-po-password-labs.component.ts b/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-labs/sample-po-password-labs.component.ts index 1cf6005a89..16cef2d5e6 100644 --- a/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-labs/sample-po-password-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-labs/sample-po-password-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-password-labs', templateUrl: './sample-po-password-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPasswordLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-reset/sample-po-password-reset.component.ts b/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-reset/sample-po-password-reset.component.ts index b4cf919e10..6f2e580a9f 100644 --- a/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-reset/sample-po-password-reset.component.ts +++ b/projects/ui/src/lib/components/po-field/po-password/samples/sample-po-password-reset/sample-po-password-reset.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoDialogService } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoDialogService } from '@po-ui/ng-components'; selector: 'sample-po-password-reset', templateUrl: './sample-po-password-reset.component.html', providers: [PoDialogService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPasswordResetComponent { diff --git a/projects/ui/src/lib/components/po-field/po-radio-group/po-radio-group-base.component.spec.ts b/projects/ui/src/lib/components/po-field/po-radio-group/po-radio-group-base.component.spec.ts index cdb8c97573..65f61df2a4 100644 --- a/projects/ui/src/lib/components/po-field/po-radio-group/po-radio-group-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-radio-group/po-radio-group-base.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { expectPropertiesValues } from '../../../util-test/util-expect.spec'; @@ -12,6 +12,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; @Component({ selector: 'po-radio-group-base-host', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class PoRadioHostGroupComponent extends PoRadioGroupBaseComponent { diff --git a/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-basic/sample-po-radio-group-basic.component.ts b/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-basic/sample-po-radio-group-basic.component.ts index 76cff302eb..13413e6887 100644 --- a/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-basic/sample-po-radio-group-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-basic/sample-po-radio-group-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-radio-group-basic', templateUrl: './sample-po-radio-group-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoRadioGroupBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-labs/sample-po-radio-group-labs.component.ts b/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-labs/sample-po-radio-group-labs.component.ts index 91e115d334..19cff298df 100644 --- a/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-labs/sample-po-radio-group-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-labs/sample-po-radio-group-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-radio-group-labs', templateUrl: './sample-po-radio-group-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoRadioGroupLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-translator-reactive-form/sample-po-radio-group-translator-reactive-form.component.ts b/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-translator-reactive-form/sample-po-radio-group-translator-reactive-form.component.ts index cd992a497c..55f4dede8b 100644 --- a/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-translator-reactive-form/sample-po-radio-group-translator-reactive-form.component.ts +++ b/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-translator-reactive-form/sample-po-radio-group-translator-reactive-form.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { PoRadioGroupOption, PoSelectOption } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoRadioGroupOption, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-radio-group-translator-reactive-form', templateUrl: './sample-po-radio-group-translator-reactive-form.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoRadioGroupTranslatorReactiveFormComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-translator/sample-po-radio-group-translator.component.ts b/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-translator/sample-po-radio-group-translator.component.ts index 405cb5ad41..825ee590b5 100644 --- a/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-translator/sample-po-radio-group-translator.component.ts +++ b/projects/ui/src/lib/components/po-field/po-radio-group/samples/sample-po-radio-group-translator/sample-po-radio-group-translator.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoRadioGroupOption, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-radio-group-translator', templateUrl: './sample-po-radio-group-translator.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoRadioGroupTranslatorComponent { diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-base.component.spec.ts b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-base.component.spec.ts index 0ecd9b968f..220294744f 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-base.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { expectPropertiesValues } from '../../../util-test/util-expect.spec'; @@ -14,6 +14,7 @@ import { convertToBoolean } from '../../../utils/util'; @Component({ selector: 'po-rich-texts-base-host', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class PoRichTextHostComponent extends PoRichTextBaseComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.ts b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.ts index 140d123b9a..83232ff14f 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-body/po-rich-text-body.component.ts @@ -12,7 +12,8 @@ import { SimpleChanges, ViewChild, inject, - ChangeDetectorRef + ChangeDetectorRef, + ChangeDetectionStrategy } from '@angular/core'; import { Subscription } from 'rxjs'; @@ -36,6 +37,7 @@ const poRichTextBodyCommands = [ @Component({ selector: 'po-rich-text-body', templateUrl: './po-rich-text-body.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoRichTextBodyComponent implements OnInit, OnDestroy, OnChanges { diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-image-modal/po-rich-text-image-modal.component.spec.ts b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-image-modal/po-rich-text-image-modal.component.spec.ts index e4009cca28..6c1d63e846 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-image-modal/po-rich-text-image-modal.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-image-modal/po-rich-text-image-modal.component.spec.ts @@ -7,7 +7,7 @@ import { PoButtonGroupModule } from '../../../po-button-group'; import { PoModalModule } from '../../../po-modal/po-modal.module'; import { PoRichTextImageModalComponent } from './po-rich-text-image-modal.component'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoRichTextImageModalComponent', () => { let component: PoRichTextImageModalComponent; @@ -18,7 +18,7 @@ describe('PoRichTextImageModalComponent', () => { await TestBed.configureTestingModule({ declarations: [], imports: [PoButtonGroupModule, PoModalModule, PoFieldModule], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting()] }).compileComponents(); fixture = TestBed.createComponent(PoRichTextImageModalComponent); diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-image-modal/po-rich-text-image-modal.component.ts b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-image-modal/po-rich-text-image-modal.component.ts index 9877df93ba..4656514b28 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-image-modal/po-rich-text-image-modal.component.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-image-modal/po-rich-text-image-modal.component.ts @@ -1,4 +1,13 @@ -import { Component, EventEmitter, HostBinding, Input, Output, ViewChild, inject } from '@angular/core'; +import { + Component, + EventEmitter, + HostBinding, + Input, + Output, + ViewChild, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoUtils } from '../../../../utils/util'; @@ -14,6 +23,7 @@ const uploadRestrictions = ['.apng', '.bmp', '.gif', '.ico', '.jpeg', '.jpg', '. @Component({ selector: 'po-rich-text-image-modal', templateUrl: './po-rich-text-image-modal.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoRichTextImageModalComponent { diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-link-modal/po-rich-text-link-modal.component.ts b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-link-modal/po-rich-text-link-modal.component.ts index d067fa646b..1f79cfc802 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-link-modal/po-rich-text-link-modal.component.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-link-modal/po-rich-text-link-modal.component.ts @@ -7,7 +7,8 @@ import { OnInit, Output, ViewChild, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { AbstractControl, NgForm } from '@angular/forms'; @@ -20,6 +21,7 @@ import { poRichTextLiteralsDefault } from '../po-rich-text-literals'; @Component({ selector: 'po-rich-text-link-modal', templateUrl: './po-rich-text-link-modal.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoRichTextLinkModalComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-toolbar/po-rich-text-toolbar.component.spec.ts b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-toolbar/po-rich-text-toolbar.component.spec.ts index 6b5b0c51f8..0ebf817eb6 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-toolbar/po-rich-text-toolbar.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-toolbar/po-rich-text-toolbar.component.spec.ts @@ -3,7 +3,7 @@ import { FormsModule } from '@angular/forms'; import { PoUtils as UtilsFunction } from '../../../../utils/util'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { provideHttpClientTesting } from '@angular/common/http/testing'; import { PoButtonGroupModule } from '../../../po-button-group'; import { PoModalModule } from '../../../po-modal/po-modal.module'; @@ -21,7 +21,7 @@ describe('PoRichTextToolbarComponent:', () => { await TestBed.configureTestingModule({ declarations: [], imports: [FormsModule, PoButtonGroupModule, PoModalModule, PoTooltipModule, PoFieldModule], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting()] }).compileComponents(); fixture = TestBed.createComponent(PoRichTextToolbarComponent); diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-toolbar/po-rich-text-toolbar.component.ts b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-toolbar/po-rich-text-toolbar.component.ts index df63f1b095..67d0515597 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-toolbar/po-rich-text-toolbar.component.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text-toolbar/po-rich-text-toolbar.component.ts @@ -7,7 +7,8 @@ import { Input, Output, ViewChild, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { PoLanguageService } from '../../../../services/po-language/po-language.service'; @@ -25,6 +26,7 @@ const poRichTextDefaultColor = '#000000'; @Component({ selector: 'po-rich-text-toolbar', templateUrl: './po-rich-text-toolbar.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoRichTextToolbarComponent implements AfterViewInit { diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text.component.spec.ts b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text.component.spec.ts index 2643142ef8..862610e4de 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/po-rich-text.component.spec.ts @@ -1,7 +1,6 @@ import { EventEmitter, NO_ERRORS_SCHEMA, SimpleChange, SimpleChanges } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { PoFieldContainerBottomComponent } from '../po-field-container/po-field-container-bottom/po-field-container-bottom.component'; import { PoFieldContainerComponent } from '../po-field-container/po-field-container.component'; @@ -25,7 +24,7 @@ describe('PoRichTextComponent:', () => { PoRichTextToolbarComponent ], schemas: [NO_ERRORS_SCHEMA], - imports: [BrowserAnimationsModule, FormsModule] + imports: [FormsModule] }).compileComponents(); fixture = TestBed.createComponent(PoRichTextComponent); diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-basic/sample-po-rich-text-basic.component.ts b/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-basic/sample-po-rich-text-basic.component.ts index 48156ff668..3719ff2586 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-basic/sample-po-rich-text-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-basic/sample-po-rich-text-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-rich-text-basic', templateUrl: './sample-po-rich-text-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoRichTextBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-labs/sample-po-rich-text-labs.component.ts b/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-labs/sample-po-rich-text-labs.component.ts index 71d895cae4..ccf916728e 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-labs/sample-po-rich-text-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-labs/sample-po-rich-text-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, @@ -10,6 +10,7 @@ import { @Component({ selector: 'sample-po-rich-text-labs', templateUrl: './sample-po-rich-text-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoRichTextLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-recipe/sample-po-rich-text-recipe.component.ts b/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-recipe/sample-po-rich-text-recipe.component.ts index 06dfb952f0..da08383db8 100644 --- a/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-recipe/sample-po-rich-text-recipe.component.ts +++ b/projects/ui/src/lib/components/po-field/po-rich-text/samples/sample-po-rich-text-recipe/sample-po-rich-text-recipe.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import image from './sample-po-rich-text-recipe-image-base-64'; @Component({ selector: 'sample-po-rich-text-recipe', templateUrl: './sample-po-rich-text-recipe.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoRichTextRecipeComponent { diff --git a/projects/ui/src/lib/components/po-field/po-search-ai/po-search-ai-base.component.ts b/projects/ui/src/lib/components/po-field/po-search-ai/po-search-ai-base.component.ts index bd58d1dac9..1a185ad8d1 100644 --- a/projects/ui/src/lib/components/po-field/po-search-ai/po-search-ai-base.component.ts +++ b/projects/ui/src/lib/components/po-field/po-search-ai/po-search-ai-base.component.ts @@ -24,10 +24,6 @@ const PO_SEARCH_AI_DEFAULT_MIN_CONFIDENCE = 0.5; * em um filtro estruturado (normalmente OData) que pode ser aplicado por outro componente, * como o [`po-table`](/documentation/po-table). * - * > **Componente experimental:** o `po-search-ai` está em fase experimental. Sua API - * > (propriedades, eventos e contrato com o backend) pode sofrer alterações - * > entre versões. Utilize com cautela em ambientes de produção. - * * O componente é **agnóstico ao provedor de IA**. Toda a comunicação ocorre através do * endpoint informado em `p-url`, que recebe `{ query, columns }` e deve retornar * `{ filter, description, confidence }`. Isso garante que nenhuma chave de IA seja diff --git a/projects/ui/src/lib/components/po-field/po-select/po-select.component.html b/projects/ui/src/lib/components/po-field/po-select/po-select.component.html index 46672f44e4..67f2b19fee 100644 --- a/projects/ui/src/lib/components/po-field/po-select/po-select.component.html +++ b/projects/ui/src/lib/components/po-field/po-select/po-select.component.html @@ -50,7 +50,7 @@ @if (optionWithoutGroup.length > 0) { @for (item of optionWithoutGroup; track item) { - } @@ -60,7 +60,7 @@ @if (item?.options.length > 0) { @for (subItem of item.options; track subItem) { - } diff --git a/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-basic/sample-po-select-basic.component.ts b/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-basic/sample-po-select-basic.component.ts index 9e092b13a2..3edb3176b1 100644 --- a/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-basic/sample-po-select-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-basic/sample-po-select-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-select-basic', templateUrl: './sample-po-select-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSelectBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-companies/sample-po-select-companies.component.ts b/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-companies/sample-po-select-companies.component.ts index 8671ba8a62..4b2d0b0fa4 100644 --- a/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-companies/sample-po-select-companies.component.ts +++ b/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-companies/sample-po-select-companies.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoSelectOption, PoSelectOptionGroup } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-select-companies', templateUrl: './sample-po-select-companies.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSelectCompaniesComponent { diff --git a/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-customer-registration/sample-po-select-customer-registration.component.ts b/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-customer-registration/sample-po-select-customer-registration.component.ts index 94cf98c2f2..91a8283479 100644 --- a/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-customer-registration/sample-po-select-customer-registration.component.ts +++ b/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-customer-registration/sample-po-select-customer-registration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit, inject } from '@angular/core'; +import { Component, OnDestroy, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { Subscription } from 'rxjs'; @@ -11,6 +11,7 @@ import { SamplePoSelectCustomerRegistrationService } from './sample-po-select-cu templateUrl: './sample-po-select-customer-registration.component.html', providers: [SamplePoSelectCustomerRegistrationService], styleUrls: ['./sample-po-select-customer-registration.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSelectCustomerRegistrationComponent implements OnDestroy, OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-labs/sample-po-select-labs.component.ts b/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-labs/sample-po-select-labs.component.ts index b6afa0017e..4aef7fa160 100644 --- a/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-labs/sample-po-select-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-select/samples/sample-po-select-labs/sample-po-select-labs.component.ts @@ -1,10 +1,11 @@ -import { ChangeDetectorRef, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectorRef, Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption, PoSelectOption, PoSelectOptionGroup } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-select-labs', templateUrl: './sample-po-select-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSelectLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-basic/sample-po-switch-basic.component.ts b/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-basic/sample-po-switch-basic.component.ts index 6bc64f40f2..48005f0e4e 100644 --- a/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-basic/sample-po-switch-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-basic/sample-po-switch-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-switch-basic', templateUrl: './sample-po-switch-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSwitchBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-labs/sample-po-switch-labs.component.ts b/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-labs/sample-po-switch-labs.component.ts index 076d4edcb4..a5940e188a 100644 --- a/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-labs/sample-po-switch-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-labs/sample-po-switch-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption, PoSwitchLabelPosition } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-switch-labs', templateUrl: './sample-po-switch-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSwitchLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-order-reactive-form/sample-po-switch-order-reactive-form.component.ts b/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-order-reactive-form/sample-po-switch-order-reactive-form.component.ts index f336d7d649..417dbbecc7 100644 --- a/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-order-reactive-form/sample-po-switch-order-reactive-form.component.ts +++ b/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-order-reactive-form/sample-po-switch-order-reactive-form.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { PoNotificationService, PoSwitchLabelPosition, PoTableColumn } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoNotificationService, PoSwitchLabelPosition, PoTableColumn } from '@po @Component({ selector: 'sample-po-switch-order-reactive-form', templateUrl: './sample-po-switch-order-reactive-form.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSwitchOrderReactiveFormComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-order/sample-po-switch-order.component.ts b/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-order/sample-po-switch-order.component.ts index 4dd0a1abe0..0b1247c6ab 100644 --- a/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-order/sample-po-switch-order.component.ts +++ b/projects/ui/src/lib/components/po-field/po-switch/samples/sample-po-switch-order/sample-po-switch-order.component.ts @@ -1,10 +1,11 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService, PoSwitchLabelPosition, PoTableColumn } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-switch-order', templateUrl: './sample-po-switch-order.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSwitchOrderComponent { diff --git a/projects/ui/src/lib/components/po-field/po-textarea/po-textarea-base.component.spec.ts b/projects/ui/src/lib/components/po-field/po-textarea/po-textarea-base.component.spec.ts index 6b38bc12cb..4bd40d009a 100644 --- a/projects/ui/src/lib/components/po-field/po-textarea/po-textarea-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-textarea/po-textarea-base.component.spec.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component } from '@angular/core'; +import { ChangeDetectorRef, Component, ChangeDetectionStrategy } from '@angular/core'; import { FormControl, UntypedFormControl, Validators } from '@angular/forms'; import { expectPropertiesValues, expectSettersMethod } from '../../../util-test/util-expect.spec'; @@ -12,6 +12,7 @@ import { mapInputSizeToLoadingIcon } from '../../../utils/util'; @Component({ selector: 'po-textarea-base-host', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class PoTextareaHostComponent extends PoTextareaBaseComponent { diff --git a/projects/ui/src/lib/components/po-field/po-textarea/po-textarea.component.spec.ts b/projects/ui/src/lib/components/po-field/po-textarea/po-textarea.component.spec.ts index 0f80637aba..e1b31c0370 100644 --- a/projects/ui/src/lib/components/po-field/po-textarea/po-textarea.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-textarea/po-textarea.component.spec.ts @@ -324,6 +324,16 @@ describe('PoTextareaComponent:', () => { }); describe('initResizeObserver:', () => { + let originalResizeObserver: typeof ResizeObserver; + + beforeEach(() => { + originalResizeObserver = window.ResizeObserver; + }); + + afterEach(() => { + (window as any).ResizeObserver = originalResizeObserver; + }); + it('should observe the input element', () => { const observeSpy = jasmine.createSpy('observe'); const disconnectSpy = jasmine.createSpy('disconnect'); @@ -875,8 +885,10 @@ describe('PoTextareaComponent:', () => { describe('initResizeObserver:', () => { let observeSpy: jasmine.Spy; let observerCallback: Function; + let originalResizeObserver: typeof ResizeObserver; beforeEach(() => { + originalResizeObserver = window.ResizeObserver; observeSpy = jasmine.createSpy('observe'); (window as any).ResizeObserver = function (callback: Function) { observerCallback = callback; @@ -884,6 +896,10 @@ describe('PoTextareaComponent:', () => { }; }); + afterEach(() => { + (window as any).ResizeObserver = originalResizeObserver; + }); + it('should create ResizeObserver and observe the textarea element', () => { component['initResizeObserver'](); expect(observeSpy).toHaveBeenCalledWith(component.inputEl.nativeElement); diff --git a/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-basic/sample-po-textarea-basic.component.ts b/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-basic/sample-po-textarea-basic.component.ts index 57d7eb7e8a..5ee2552156 100644 --- a/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-basic/sample-po-textarea-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-basic/sample-po-textarea-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-textarea-basic', templateUrl: './sample-po-textarea-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTextareaBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-email-reactive-form/sample-po-textarea-email-reactive-form.component.ts b/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-email-reactive-form/sample-po-textarea-email-reactive-form.component.ts index 124b9fa0d2..33ec81059b 100644 --- a/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-email-reactive-form/sample-po-textarea-email-reactive-form.component.ts +++ b/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-email-reactive-form/sample-po-textarea-email-reactive-form.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { PoModalAction, PoModalComponent } from '@po-ui/ng-components'; @@ -7,6 +7,7 @@ import { PoPageAction } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-textarea-email-reactive-form', templateUrl: './sample-po-textarea-email-reactive-form.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTextareaEmailReactiveFormComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-email/sample-po-textarea-email.component.ts b/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-email/sample-po-textarea-email.component.ts index cc6c1bd1da..d4b220d5af 100644 --- a/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-email/sample-po-textarea-email.component.ts +++ b/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-email/sample-po-textarea-email.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { PoModalAction, PoModalComponent } from '@po-ui/ng-components'; @@ -7,6 +7,7 @@ import { PoPageAction } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-textarea-email', templateUrl: './sample-po-textarea-email.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTextareaEmailComponent { diff --git a/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-labs/sample-po-textarea-labs.component.ts b/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-labs/sample-po-textarea-labs.component.ts index 80c3870e17..d75f59ae7e 100644 --- a/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-labs/sample-po-textarea-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-textarea/samples/sample-po-textarea-labs/sample-po-textarea-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-textarea-labs', templateUrl: './sample-po-textarea-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTextareaLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-timepicker/po-timepicker.component.spec.ts b/projects/ui/src/lib/components/po-field/po-timepicker/po-timepicker.component.spec.ts index f3e6390b86..ffefbbf47b 100644 --- a/projects/ui/src/lib/components/po-field/po-timepicker/po-timepicker.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-timepicker/po-timepicker.component.spec.ts @@ -26,6 +26,18 @@ describe('PoTimepickerComponent:', () => { component.locale = 'pt'; }); + afterEach(() => { + // O ambiente roda com `teardown: { destroyAfterEach: false }`, então o + // `ngOnDestroy` não é chamado automaticamente entre os testes. Sem isso, o + // listener global de `scroll` (window.addEventListener('scroll', this.onScroll)) + // registrado em `initializeListeners` (ao abrir o timepicker) permanece vivo + // apontando para uma instância órfã. Qualquer scroll posterior — inclusive no + // afterAll da suíte — dispara `onScroll` -> `adjustPosition`, que acessa `width` + // de um elemento já inexistente, lançando "Cannot read properties of undefined". + // Destruir o fixture executa o removeListeners e elimina o vazamento. + fixture?.destroy(); + }); + it('should be created', () => { expect(component).toBeTruthy(); }); diff --git a/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-basic/sample-po-timepicker-basic.component.ts b/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-basic/sample-po-timepicker-basic.component.ts index 7a6124c487..237e8f0a8f 100644 --- a/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-basic/sample-po-timepicker-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-basic/sample-po-timepicker-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-timepicker-basic', templateUrl: './sample-po-timepicker-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTimepickerBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-business-hours/sample-po-timepicker-business-hours.component.ts b/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-business-hours/sample-po-timepicker-business-hours.component.ts index ca6253a56e..72f238a3b7 100644 --- a/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-business-hours/sample-po-timepicker-business-hours.component.ts +++ b/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-business-hours/sample-po-timepicker-business-hours.component.ts @@ -1,10 +1,11 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-timepicker-business-hours', templateUrl: './sample-po-timepicker-business-hours.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTimepickerBusinessHoursComponent { diff --git a/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-labs/sample-po-timepicker-labs.component.ts b/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-labs/sample-po-timepicker-labs.component.ts index fcdad6262f..615e50bee6 100644 --- a/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-labs/sample-po-timepicker-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-labs/sample-po-timepicker-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption, PoTimepickerModelFormat } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-timepicker-labs', templateUrl: './sample-po-timepicker-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTimepickerLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-scheduling/sample-po-timepicker-scheduling.component.ts b/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-scheduling/sample-po-timepicker-scheduling.component.ts index 494c69e9f7..42f12ea312 100644 --- a/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-scheduling/sample-po-timepicker-scheduling.component.ts +++ b/projects/ui/src/lib/components/po-field/po-timepicker/samples/sample-po-timepicker-scheduling/sample-po-timepicker-scheduling.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, inject } from '@angular/core'; +import { Component, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { PoDialogService, PoNotificationService, PoSelectOption } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoDialogService, PoNotificationService, PoSelectOption } from '@po-ui/n @Component({ selector: 'sample-po-timepicker-scheduling', templateUrl: './sample-po-timepicker-scheduling.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTimepickerSchedulingComponent { diff --git a/projects/ui/src/lib/components/po-field/po-upload/po-upload-base.component.spec.ts b/projects/ui/src/lib/components/po-field/po-upload/po-upload-base.component.spec.ts index 8ae0dc7df2..2a5e1f42c8 100644 --- a/projects/ui/src/lib/components/po-field/po-upload/po-upload-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-upload/po-upload-base.component.spec.ts @@ -1,5 +1,5 @@ import { HttpClient, HttpHandler } from '@angular/common/http'; -import { ChangeDetectorRef, Component, inject } from '@angular/core'; +import { ChangeDetectorRef, Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { FormsModule, UntypedFormControl } from '@angular/forms'; @@ -19,6 +19,7 @@ import { PoUploadService } from './po-upload.service'; @Component({ selector: 'po-upload', template: ` `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class PoUploadComponent extends PoUploadBaseComponent { diff --git a/projects/ui/src/lib/components/po-field/po-upload/po-upload-base.service.spec.ts b/projects/ui/src/lib/components/po-field/po-upload/po-upload-base.service.spec.ts index 73a198ed57..fa779d60ad 100644 --- a/projects/ui/src/lib/components/po-field/po-upload/po-upload-base.service.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-upload/po-upload-base.service.spec.ts @@ -1,7 +1,7 @@ import { ChangeDetectorRef, EventEmitter } from '@angular/core'; import { inject, TestBed } from '@angular/core/testing'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { HttpResponse, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { HttpResponse, provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { Observable } from 'rxjs'; @@ -12,7 +12,11 @@ describe('PoUploadBaseService:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoUploadBaseService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [ + PoUploadBaseService, + provideHttpClient(withXhr(), withInterceptorsFromDi()), + provideHttpClientTesting() + ] }); }); diff --git a/projects/ui/src/lib/components/po-field/po-upload/po-upload-drag-drop/po-upload-drag-drop.directive.spec.ts b/projects/ui/src/lib/components/po-field/po-upload/po-upload-drag-drop/po-upload-drag-drop.directive.spec.ts index fbbd5c98cd..91ffa63988 100644 --- a/projects/ui/src/lib/components/po-field/po-upload/po-upload-drag-drop/po-upload-drag-drop.directive.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-upload/po-upload-drag-drop/po-upload-drag-drop.directive.spec.ts @@ -1,11 +1,12 @@ import { By } from '@angular/platform-browser'; -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { PoUploadDragDropDirective } from './po-upload-drag-drop.directive'; @Component({ template: `
    `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class TestComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-upload/po-upload.component.spec.ts b/projects/ui/src/lib/components/po-field/po-upload/po-upload.component.spec.ts index 90dc964fb3..8c0b2bcd37 100644 --- a/projects/ui/src/lib/components/po-field/po-upload/po-upload.component.spec.ts +++ b/projects/ui/src/lib/components/po-field/po-upload/po-upload.component.spec.ts @@ -319,7 +319,7 @@ describe('PoUploadComponent:', () => { component.autoUpload = false; component.currentFiles = [file]; - spyOn(component, 'hasFileNotUploaded').and.returnValue(true); + spyOnProperty(component, 'hasFileNotUploaded', 'get').and.returnValue(true); expect(component.displaySendButton).toBeTruthy(); }); @@ -329,7 +329,7 @@ describe('PoUploadComponent:', () => { component.autoUpload = false; component.currentFiles = [file]; - spyOn(component, 'hasFileNotUploaded').and.returnValue(true); + spyOnProperty(component, 'hasFileNotUploaded', 'get').and.returnValue(true); expect(component.displaySendButton).toBeFalsy(); }); @@ -339,7 +339,7 @@ describe('PoUploadComponent:', () => { component.autoUpload = true; component.currentFiles = [file]; - spyOn(component, 'hasFileNotUploaded').and.returnValue(true); + spyOnProperty(component, 'hasFileNotUploaded', 'get').and.returnValue(true); expect(component.displaySendButton).toBeFalsy(); }); @@ -349,7 +349,7 @@ describe('PoUploadComponent:', () => { component.autoUpload = true; component.currentFiles = []; - spyOn(component, 'hasFileNotUploaded').and.returnValue(true); + spyOnProperty(component, 'hasFileNotUploaded', 'get').and.returnValue(true); expect(component.displaySendButton).toBeFalsy(); }); @@ -359,7 +359,7 @@ describe('PoUploadComponent:', () => { component.autoUpload = true; component.currentFiles = [file]; - spyOn(component, 'hasFileNotUploaded').and.returnValue(false); + spyOnProperty(component, 'hasFileNotUploaded', 'get').and.returnValue(false); expect(component.displaySendButton).toBeFalsy(); }); diff --git a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-basic/sample-po-upload-basic.component.ts b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-basic/sample-po-upload-basic.component.ts index ad1dccf509..488db7635a 100644 --- a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-basic/sample-po-upload-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-basic/sample-po-upload-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-upload-basic', templateUrl: 'sample-po-upload-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUploadBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-download/sample-po-upload-download.component.ts b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-download/sample-po-upload-download.component.ts index 32e6ec5faf..e7c490190e 100644 --- a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-download/sample-po-upload-download.component.ts +++ b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-download/sample-po-upload-download.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoProgressAction } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-upload-download', templateUrl: 'sample-po-upload-download.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUploadDownloadComponent { diff --git a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-labs/sample-po-upload-labs.component.ts b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-labs/sample-po-upload-labs.component.ts index 39ae89c659..7cb2ce4934 100644 --- a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-labs/sample-po-upload-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-labs/sample-po-upload-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { @@ -14,6 +14,7 @@ import { @Component({ selector: 'sample-po-upload-labs', templateUrl: './sample-po-upload-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUploadLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-preview/sample-po-upload-preview.component.ts b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-preview/sample-po-upload-preview.component.ts index a445f5f2c9..af596d9a11 100644 --- a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-preview/sample-po-upload-preview.component.ts +++ b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-preview/sample-po-upload-preview.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoProgressAction } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-upload-preview', templateUrl: 'sample-po-upload-preview.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUploadPreviewComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-resume-drag-drop/sample-po-upload-resume-drag-drop.component.ts b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-resume-drag-drop/sample-po-upload-resume-drag-drop.component.ts index f2e83251b7..be85c9c4c5 100644 --- a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-resume-drag-drop/sample-po-upload-resume-drag-drop.component.ts +++ b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-resume-drag-drop/sample-po-upload-resume-drag-drop.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { PoNotificationService } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-upload-resume-drag-drop', templateUrl: 'sample-po-upload-resume-drag-drop.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUploadResumeDragDropComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-resume/sample-po-upload-resume.component.ts b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-resume/sample-po-upload-resume.component.ts index e3dbdaeb88..749f4936f4 100644 --- a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-resume/sample-po-upload-resume.component.ts +++ b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-resume/sample-po-upload-resume.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { PoNotificationService } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-upload-resume', templateUrl: 'sample-po-upload-resume.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUploadResumeComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-rs/sample-po-upload-rs.component.ts b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-rs/sample-po-upload-rs.component.ts index 9199322ade..c8b53477c2 100644 --- a/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-rs/sample-po-upload-rs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-upload/samples/sample-po-upload-rs/sample-po-upload-rs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoModalAction, PoModalComponent, PoStepperComponent, PoUploadComponent } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoModalAction, PoModalComponent, PoStepperComponent, PoUploadComponent @Component({ selector: 'sample-po-upload-rs', templateUrl: 'sample-po-upload-rs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUploadRsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-basic/sample-po-url-basic.component.ts b/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-basic/sample-po-url-basic.component.ts index 0bf1e8f7fe..741783182f 100644 --- a/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-basic/sample-po-url-basic.component.ts +++ b/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-basic/sample-po-url-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-url-basic', templateUrl: './sample-po-url-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUrlBasicComponent {} diff --git a/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-labs/sample-po-url-labs.component.ts b/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-labs/sample-po-url-labs.component.ts index 2b4185e657..9c965033cf 100644 --- a/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-labs/sample-po-url-labs.component.ts +++ b/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-labs/sample-po-url-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-url-labs', templateUrl: './sample-po-url-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUrlLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-shortener/sample-po-url-shortener.component.ts b/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-shortener/sample-po-url-shortener.component.ts index c43075600e..2da17d215b 100644 --- a/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-shortener/sample-po-url-shortener.component.ts +++ b/projects/ui/src/lib/components/po-field/po-url/samples/sample-po-url-shortener/sample-po-url-shortener.component.ts @@ -1,10 +1,11 @@ -import { Component, ElementRef, ViewChild, inject } from '@angular/core'; +import { Component, ElementRef, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService, PoTableColumn } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-url-shortener', templateUrl: './sample-po-url-shortener.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUrlShortenerComponent { diff --git a/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-basic/sample-po-filter-chip-basic.component.ts b/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-basic/sample-po-filter-chip-basic.component.ts index e8fbc275ad..bb182003bb 100644 --- a/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-basic/sample-po-filter-chip-basic.component.ts +++ b/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-basic/sample-po-filter-chip-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-filter-chip-basic', templateUrl: './sample-po-filter-chip-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoFilterChipBasicComponent {} diff --git a/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-filter-list/sample-po-filter-chip-filter-list.component.ts b/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-filter-list/sample-po-filter-chip-filter-list.component.ts index 386d5f67e9..eb0a1cebf5 100644 --- a/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-filter-list/sample-po-filter-chip-filter-list.component.ts +++ b/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-filter-list/sample-po-filter-chip-filter-list.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoFilterChipSelectedChange } from '@po-ui/ng-components/lib'; interface FilterOption { @@ -14,6 +14,7 @@ interface Product { @Component({ selector: 'sample-po-filter-chip-filter-list', templateUrl: './sample-po-filter-chip-filter-list.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoFilterChipFilterListComponent { diff --git a/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-labs/sample-po-filter-chip-labs.component.ts b/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-labs/sample-po-filter-chip-labs.component.ts index a206f6e5ad..01e1773efa 100644 --- a/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-labs/sample-po-filter-chip-labs.component.ts +++ b/projects/ui/src/lib/components/po-filter-chip/samples/sample-po-filter-chip-labs/sample-po-filter-chip-labs.component.ts @@ -1,9 +1,10 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoFilterChipSelectedChange } from '@po-ui/ng-components/lib'; @Component({ selector: 'sample-po-filter-chip-labs', templateUrl: './sample-po-filter-chip-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoFilterChipLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-gauge/index.ts b/projects/ui/src/lib/components/po-gauge/index.ts deleted file mode 100644 index 02822f2a51..0000000000 --- a/projects/ui/src/lib/components/po-gauge/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './interfaces/po-gauge-ranges.interface'; -export * from './interfaces/po-gauge-options.interface'; - -export * from './po-gauge.component'; - -export * from './po-gauge.module'; diff --git a/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-coordinates.interface.ts b/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-coordinates.interface.ts deleted file mode 100644 index 23c3752b95..0000000000 --- a/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-coordinates.interface.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @docsPrivate - * - * @usedBy PoGaugeComponent - * - * @description - * - * Interface que define o objeto com as coordenadas do gauge. - */ -export interface PoGaugeCoordinates { - /** A cor do alcance. Aceita hexadecimais, string com nome da cor, RGB ou então uma das classes de cor do PO. */ - color?: string; - - /** Definição de coordenadas. */ - coordinates: string; - - /** O raio do circulo. Utilizado para posicionar o ponteiro no centro do gauge. */ - radius?: number; - - /** O grau de angulação do ponteiro. */ - pointerDegrees?: number; -} diff --git a/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-options.interface.ts b/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-options.interface.ts deleted file mode 100644 index e2f83ec809..0000000000 --- a/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-options.interface.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { PoChartHeaderOptions } from '../../po-chart'; - -/** - * @usedBy PoGaugeComponent - * - * @description - * - * *Interface* para configurações dos elementos do gráfico. - */ -export interface PoGaugeOptions { - /** - * @optional - * - * @description - * - * Define a descrição do gráfico exibido acima do gráfico. - * - */ - descriptionChart?: string; - - /** - * @optional - * - * @description - * - * Define um objeto do tipo `PoChartHeaderOptions` para configurar a exibição de botões no cabeçalho do gráfico. - */ - header?: PoChartHeaderOptions; - - /** - * @optional - * - * @description - * - * Esconde a estilização do container em volta do gráfico. - * - * @default `true` - */ - showContainerGauge?: boolean; - - /** - * @optional - * - * @description - * - * Exibe os valores das propriedades `from` e `to` no gráfico do no texto da legenda entre parênteses. - * - * > Válido para gráfico do tipo `Gauge`. - * - */ - showFromToLegend?: boolean; - - /** - * @optional - * - * @description - * - * Define um subtítulo para o Gauge. Indicamos um subtítulo pequeno, com uma quantidade máxima de 32 caracteres na altura padrão. - * - */ - subtitleGauge?: string; - - /** - * @optional - * - * @description - * - * Define a exibição do ponteiro. - * - * > Válido para gráfico do tipo `Gauge`. - * - * @default `true` - */ - pointer?: boolean; -} diff --git a/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-ranges.interface.ts b/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-ranges.interface.ts deleted file mode 100644 index ca7f8f517c..0000000000 --- a/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-ranges.interface.ts +++ /dev/null @@ -1,47 +0,0 @@ -/** - * @usedBy PoGaugeComponent - * - * @description - * - * Interface que define os alcances das cores do gauge. - */ -export interface PoGaugeRanges { - /** Alcance inicial da cor. O valor padrão é 0. */ - from?: number; - - /** Alcance final da cor. O valor padrão é 100. */ - to?: number; - - /** - * @description - * - * O texto para a legenda do alcance. - * - * > Se desejar ocultar a legenda basta ignorar esta propriedade. - */ - label?: string; - - /** - * @description - * - * Determina a cor do alcance. As maneiras de customizar o *preset* padrão de cores são: - * - Hexadeximal, por exemplo `#c64840`; - * - RGB, como `rgb(0, 0, 165)` - * - O nome da cor, por exemplo *blue*); - * - Usando uma das cores do tema do PO: - * Valores válidos: - * - `color-01` - * - `color-02` - * - `color-03` - * - `color-04` - * - `color-05` - * - `color-06` - * - `color-07` - * - `color-08` - * - `color-09` - * - `color-10` - * - `color-11` - * - `color-12` - */ - color?: string; -} diff --git a/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-svg-container.interface.ts b/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-svg-container.interface.ts deleted file mode 100644 index 2b6c9f69f2..0000000000 --- a/projects/ui/src/lib/components/po-gauge/interfaces/po-gauge-svg-container.interface.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @docsPrivate - * - * @usedBy PoGaugeComponent - * - * @description - * - * Interface que implementa as dimensões do container do SVG. - */ -export interface PoGaugeSvgContainer { - /** Altura do container. */ - height?: number; - - /** Largura do container. */ - width: number; -} diff --git a/projects/ui/src/lib/components/po-gauge/po-gauge-base.component.spec.ts b/projects/ui/src/lib/components/po-gauge/po-gauge-base.component.spec.ts deleted file mode 100644 index fe639406e2..0000000000 --- a/projects/ui/src/lib/components/po-gauge/po-gauge-base.component.spec.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { Component } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { PoGaugeBaseComponent } from './po-gauge-base.component'; -import { poGaugeMinHeight } from './po-gauge-default-values.constant'; -import { PoGaugeRanges } from './interfaces/po-gauge-ranges.interface'; - -@Component({ selector: 'po-gauge-base-test', template: '', standalone: false }) -class TestComponent extends PoGaugeBaseComponent {} - -describe('PoGaugeBaseComponent', () => { - let component: TestComponent; - let fixture: ComponentFixture; - - beforeEach(() => { - TestBed.configureTestingModule({ - declarations: [TestComponent] - }); - - fixture = TestBed.createComponent(TestComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create the component', () => { - expect(component).toBeTruthy(); - }); - - describe('Properties:', () => { - it('should set and get description', () => { - component.description = 'Descriptive text'; - expect(component.description).toBe('Descriptive text'); - }); - - it('should return default height as poGaugeMinHeight', () => { - expect(component.height).toBe(poGaugeMinHeight); - }); - - it('should set height greater than poGaugeMinHeight', () => { - component.height = 500; - expect(component.height).toBe(500); - }); - - it('should fallback to poGaugeMinHeight if height is invalid or less than minimum', () => { - component.height = 100; - expect(component.height).toBe(poGaugeMinHeight); - - component.height = undefined; - expect(component.height).toBe(poGaugeMinHeight); - - component.height = null; - expect(component.height).toBe(poGaugeMinHeight); - }); - - it('should set ranges when it is an array', () => { - const ranges: Array = [{ from: 0, to: 50, color: 'red' }]; - component.ranges = ranges; - expect(component.ranges).toEqual(ranges); - }); - - it('should fallback ranges to empty array if input is not array', () => { - component.ranges = null; - expect(component.ranges).toEqual([]); - - component.ranges = 'invalid'; - expect(component.ranges).toEqual([]); - }); - - it('should set and get title', () => { - component.title = 'My Gauge'; - expect(component.title).toBe('My Gauge'); - }); - - it('should set value when it is a valid number', () => { - component.value = 75; - expect(component.value).toBe(75); - }); - - it('should convert string number to number in value', () => { - component.value = '123'; - expect(component.value).toBe(123); - }); - - it('should set value to undefined if invalid', () => { - component.value = ' '; - expect(component.value).toBeUndefined(); - - component.value = null; - expect(component.value).toBeUndefined(); - }); - - it('should have default values for showFromToLegend and showPointer', () => { - expect(component.showFromToLegend).toBeFalse(); - expect(component.showPointer).toBeTrue(); - }); - - it('should set value as undefined when gaugeValue is a non-numeric string', () => { - component.value = 'abc'; - expect(component.value).toBeUndefined(); - }); - }); -}); diff --git a/projects/ui/src/lib/components/po-gauge/po-gauge-base.component.ts b/projects/ui/src/lib/components/po-gauge/po-gauge-base.component.ts deleted file mode 100644 index c58044227d..0000000000 --- a/projects/ui/src/lib/components/po-gauge/po-gauge-base.component.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { Directive, Input } from '@angular/core'; - -import { convertToInt } from '../../utils/util'; -import { poGaugeMinHeight } from './po-gauge-default-values.constant'; - -import { PoGaugeRanges } from './interfaces/po-gauge-ranges.interface'; -import { PoGaugeOptions } from './interfaces/po-gauge-options.interface'; - -/** - * @description - * - * > ESSE COMPONENTE ESTÁ DEPRECIADO E SERÁ REMOVIDO NA v22.x.x. Indicamos a utilização do `po-chart` com `type` Gauge. - * - * O componente `po-gauge` provê a representação de um valor através de um arco. É muito comum, por exemplo, para demonstrar o desempenho ou progresso de algo. - * O `po-gauge` possui dois tipos de tratamentos: - * - É possível demonstrar um dado percentual simples em conjunto com uma descrição resumida em seu interior; - * - Para um demonstrativo mais elaborado, consegue-se definir alcances em cores, um breve texto descritivo e um ponteiro indicando o valor desejado. - * - * #### Guia de uso para Gráficos - * - * > Veja nosso [guia de uso para gráficos](/guides/guide-charts) para auxiliar na construção do seu gráfico, - * informando em qual caso utilizar, o que devemos evitar e boas práticas relacionada a cores. - */ -@Directive() -export abstract class PoGaugeBaseComponent { - private _description: string; - private _height: number = poGaugeMinHeight; - private _ranges: Array = []; - private _title: string; - private _value: number; - - /** - * @optional - * - * @description - * - * Define a exibição dos valores de `from` - `to` entre parênteses caso haja definição de `p-ranges`. - * - * @default `false` - */ - @Input('p-show-from-to-legend') showFromToLegend: boolean = false; - - /** - * @optional - * - * @description - * - * Define a exibição do ponteiro caso haja definição de `p-ranges`. - * - * @default `true` - */ - @Input('p-show-pointer') showPointer: boolean = true; - - /** - * @optional - * - * @description - * - * Objeto com as configurações usadas no `po-gauge`. - * - * É possível, por exemplo, esconder as funcionalidades do header, - * ou habilitar uma legenda com `From` `To` da seguinte forma: - * - * ``` - * chartOptions: PoGaugeOptions = { - * showFromToLegend: true, - * header: { - * hideExpand: true, - * }, - * }; - * ``` - */ - @Input('p-options') options: PoGaugeOptions; - - /** - * @optional - * - * @description - * - * Define o texto que será exibido no gauge. - * Há dois posicionamentos para ele: - * - Se houver definição para `p-ranges`, o descritivo será exibido no topo do container, ficando acima do gauge; - * - Na ausência de `p-ranges`, será incorporado dentro do arco do gauge, e abaixo de `p-value`. - * - * > Para uma melhor experiência do usuário, é recomendado um descritivo breve e com poucas palavras. - * > Indicamos a utilização da nova propriedade `descriptionChart` em `p-options`. - */ - @Input('p-description') set description(value: string) { - this._description = value; - } - - get description() { - return this._description; - } - - /** - * @optional - * - * @description - * - * Define a altura do gauge. - * - * O valor mínimo aceito é 300px. - * - * @default `300px` - */ - @Input('p-height') set height(value: number) { - this._height = this.setGaugeHeight(value); - } - - get height(): number { - return this._height; - } - - /** - * @optional - * - * @description - * - * Definição para o alcance de cores. Ao adicionar pelo menos um item na lista, - * incorpora-se o ponteiro que assinala o valor passado em `p-value`. - * Se o valor de `p-value` for inferior ao mínimo valor definido em `PoGaugeRanges.from`, o domínio mínimo do gauge será `p-value`. - * A mesma regra prevalece para valores máximos. - */ - @Input('p-ranges') set ranges(value: Array) { - this._ranges = Array.isArray(value) ? value : []; - } - - get ranges(): Array { - return this._ranges; - } - - /** - * @optional - * - * @description - * - * Define o título do gauge. - */ - @Input('p-title') set title(value: string) { - this._title = value; - } - - get title() { - return this._title; - } - - /** - * @optional - * - * @description - * - * Valor referente ao valor da série. Seu comportamento segue a seguintes regras: - * - * - Sem `p-ranges`: Os valores passados para `p-value` e `p-description` serão centralizados no interior do arco. - * A base do valor será percentual tendo como base os alcances entre zero e 100%. Se passado um valor superior a 100, - * A colorização do gauge será completa e o valor passado será exibido no interior do arco. - * - Com `p-ranges`: A descrição será exibida acima do gauge e haverá um ponteiro marcando o valor passado em `p-value`. - * Considerando que o alcance em `ranges` é aberto, então a escala de `p-value` será em relação ao menor/maior alcance - * absoluto definido em `p-ranges`. - * Se passado um `p-value` inferior em relação ao mínimo valor definido em `p-ranges`, o domínio mínimo do gauge partirá de `p-value`. - * A mesma regra prevalece para valores máximos. - * - */ - @Input('p-value') set value(gaugeValue: number) { - if (typeof gaugeValue === 'number' || (typeof gaugeValue === 'string' && (gaugeValue).trim())) { - const value = !isNaN(gaugeValue) ? Number(gaugeValue) : undefined; - - this._value = value; - } else { - this._value = undefined; - } - } - - get value(): number { - return this._value; - } - - private setGaugeHeight(height: number): number { - const gaugeHeight = convertToInt(height); - - return gaugeHeight && gaugeHeight > poGaugeMinHeight ? gaugeHeight : poGaugeMinHeight; - } -} diff --git a/projects/ui/src/lib/components/po-gauge/po-gauge-default-values.constant.ts b/projects/ui/src/lib/components/po-gauge/po-gauge-default-values.constant.ts deleted file mode 100644 index 6a22d97001..0000000000 --- a/projects/ui/src/lib/components/po-gauge/po-gauge-default-values.constant.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Padding existente nas bordas do componente -export const PoGaugePadding = 24; - -// Altura mínima aceita pelo po-gauge. -export const poGaugeMinHeight = 300; - -// Chamado de coroa circular, refere-se à área entre os círculos externos e internos e que define a espessura do gauge. -export const PoGaugeThickness = 16; - -// A medida referente ao quanto o ponteiro se sobressai em relação ao gráfico. É necessário esse desconto no viewBox para não haver overflow. -export const PoGaugePointerEnd = 4; - -// Base default para cálculo da angulação final. Para gauge simples, seria como se fosse 100%. -export const poGaugeTotalValueDefault = 100; diff --git a/projects/ui/src/lib/components/po-gauge/po-gauge.component.html b/projects/ui/src/lib/components/po-gauge/po-gauge.component.html deleted file mode 100644 index 2f244e5420..0000000000 --- a/projects/ui/src/lib/components/po-gauge/po-gauge.component.html +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/projects/ui/src/lib/components/po-gauge/po-gauge.component.spec.ts b/projects/ui/src/lib/components/po-gauge/po-gauge.component.spec.ts deleted file mode 100644 index 7c3abf1c10..0000000000 --- a/projects/ui/src/lib/components/po-gauge/po-gauge.component.spec.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { PoGaugeComponent } from './po-gauge.component'; -import { PoChartSerie } from '../po-chart'; - -describe('PoGaugeComponent', () => { - let component: PoGaugeComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [PoGaugeComponent] - }).compileComponents(); - - fixture = TestBed.createComponent(PoGaugeComponent); - component = fixture.componentInstance; - }); - - it('should create the component', () => { - expect(component).toBeTruthy(); - }); - - describe('ngOnInit', () => { - it('should set showContainerGauge by default', () => { - component.ngOnInit(); - - expect(component.options).toEqual({ showContainerGauge: true }); - }); - }); - - describe('ngOnChanges', () => { - it('should set options when description, showFromToLegend or showPointer change', () => { - component.description = 'Teste'; - component.options = { - showFromToLegend: true, - pointer: false - }; - - component.ngOnChanges({ - description: { currentValue: 'Teste', previousValue: '', firstChange: true, isFirstChange: () => true }, - options: { - currentValue: { showFromToLegend: true, pointer: false }, - previousValue: false, - firstChange: true, - isFirstChange: () => true - } - }); - - expect(component.options).toEqual({ - descriptionChart: 'Teste', - showFromToLegend: true, - pointer: false, - showContainerGauge: true - }); - }); - - it('should set options when descriptionChart, showContainerGauge change', () => { - component.options = { - showContainerGauge: false, - descriptionChart: 'Test' - }; - - component.ngOnChanges({ - options: { - currentValue: { showContainerGauge: false, descriptionChart: 'Test' }, - previousValue: false, - firstChange: true, - isFirstChange: () => true - } - }); - - expect(component.options).toEqual({ - descriptionChart: 'Test', - showContainerGauge: false - }); - }); - - it('should set series and valuesMultiple when ranges is defined and not empty', () => { - const mockRanges: Array = [{ label: 'Faixa', data: 75 }]; - - component.ranges = mockRanges; - component.value = 75; - - component.ngOnChanges({ - options: { - currentValue: {}, - previousValue: false, - firstChange: true, - isFirstChange: () => true - }, - ranges: { currentValue: mockRanges, previousValue: [], firstChange: true, isFirstChange: () => true }, - value: { currentValue: 75, previousValue: 50, firstChange: true, isFirstChange: () => true } - }); - - expect(component.options).toEqual({ - descriptionChart: undefined, - showContainerGauge: true - }); - expect(component.series).toEqual(mockRanges); - expect(component.valuesMultiple).toBe(75); - }); - - it('should set series with single value when only value is defined', () => { - component.ranges = []; - component.value = 60; - - component.ngOnChanges({ - value: { currentValue: 60, previousValue: null, firstChange: true, isFirstChange: () => true } - }); - - expect(component.series).toEqual([{ data: 60 }]); - }); - - it('should set series to empty when neither ranges nor value are defined', () => { - component.ranges = undefined; - component.value = undefined; - - component.ngOnChanges({ - ranges: { currentValue: undefined, previousValue: undefined, firstChange: true, isFirstChange: () => true }, - value: { currentValue: undefined, previousValue: undefined, firstChange: true, isFirstChange: () => true } - }); - - expect(component.series).toEqual([]); - }); - }); -}); diff --git a/projects/ui/src/lib/components/po-gauge/po-gauge.component.ts b/projects/ui/src/lib/components/po-gauge/po-gauge.component.ts deleted file mode 100644 index 61f7607549..0000000000 --- a/projects/ui/src/lib/components/po-gauge/po-gauge.component.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Component, OnChanges, OnInit, SimpleChanges } from '@angular/core'; - -import { PoChartSerie } from '../po-chart'; -import { PoGaugeBaseComponent } from './po-gauge-base.component'; - -/** - * @docsExtends PoGaugeBaseComponent - * - * @example - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * @deprecated v22.x.x - * Utilize o `po-chart` com `type="gauge"` como alternativa recomendada. - */ -@Component({ - selector: 'po-gauge', - templateUrl: './po-gauge.component.html', - standalone: false -}) -export class PoGaugeComponent extends PoGaugeBaseComponent implements OnChanges, OnInit { - series: Array = []; - valuesMultiple: number; - - ngOnInit(): void { - if (this.options?.showContainerGauge !== false) { - this.options = { ...this.options, showContainerGauge: true }; - } - } - - ngOnChanges(changes: SimpleChanges): void { - const { description, ranges, value, options } = changes; - if (description || options) { - this.options = { - ...this.options, - showContainerGauge: this.options?.showContainerGauge !== false, - descriptionChart: this.description || options?.currentValue?.descriptionChart - }; - } - if (ranges || value) { - if (this.ranges?.length) { - this.series = [...this.ranges]; - this.valuesMultiple = this.value; - } else if (value?.currentValue) { - this.series = [{ data: this.value }]; - } else { - this.series = []; - } - } - } -} diff --git a/projects/ui/src/lib/components/po-gauge/po-gauge.module.ts b/projects/ui/src/lib/components/po-gauge/po-gauge.module.ts deleted file mode 100644 index 73764e3c53..0000000000 --- a/projects/ui/src/lib/components/po-gauge/po-gauge.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; - -import { PoGaugeComponent } from './po-gauge.component'; - -import { PoChartModule } from '../po-chart/po-chart.module'; - -/** - * @description - * Módulo do componente po-gauge. - */ -@NgModule({ - imports: [CommonModule, PoChartModule], - declarations: [PoGaugeComponent], - exports: [PoGaugeComponent] -}) -export class PoGaugeModule {} diff --git a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-basic/sample-po-gauge-basic.component.html b/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-basic/sample-po-gauge-basic.component.html deleted file mode 100644 index afea39225c..0000000000 --- a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-basic/sample-po-gauge-basic.component.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-basic/sample-po-gauge-basic.component.ts b/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-basic/sample-po-gauge-basic.component.ts deleted file mode 100644 index 36969c29e4..0000000000 --- a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-basic/sample-po-gauge-basic.component.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'sample-po-gauge-basic', - templateUrl: './sample-po-gauge-basic.component.html', - standalone: false -}) -export class SamplePoGaugeBasicComponent {} diff --git a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-labs/sample-po-gauge-labs.component.html b/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-labs/sample-po-gauge-labs.component.html deleted file mode 100644 index 54100dfd65..0000000000 --- a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-labs/sample-po-gauge-labs.component.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - -
    -
    - - - - - - -
    - - -
    - - - - - -
    -
    - - -
    -
    - -
    -
    - - -
    - - -
    diff --git a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-labs/sample-po-gauge-labs.component.ts b/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-labs/sample-po-gauge-labs.component.ts deleted file mode 100644 index a9ecd8ae4f..0000000000 --- a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-labs/sample-po-gauge-labs.component.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { PoCheckboxGroupOption, PoGaugeOptions, PoGaugeRanges } from '@po-ui/ng-components'; - -@Component({ - selector: 'sample-po-gauge-labs', - templateUrl: './sample-po-gauge-labs.component.html', - standalone: false -}) -export class SamplePoGaugeLabsComponent implements OnInit { - description: string; - subtitle: string; - gaugeValue: number; - height: number; - options: PoGaugeOptions; - optionsRanges: PoGaugeRanges = {}; - properties: Array; - ranges: Array = []; - title: string; - - public readonly propertiesOptions: Array = [ - { value: 'showFromToLegend', label: 'Show From To Legend' }, - { value: 'showPointer', label: 'Show Pointer' }, - { value: 'showContainerGauge', label: 'Show Container' }, - { value: 'hideExpand', label: 'Hide Expand' }, - { value: 'hideTableDetails', label: 'Hide Table Details' }, - { value: 'hideExportCsv', label: 'Hide Export Csv' }, - { value: 'hideExportImage', label: 'Hide Export Image' } - ]; - - get isEmptyObject() { - return Object.keys(this.optionsRanges).length === 0; - } - - ngOnInit() { - this.restore(); - } - - addRange() { - this.ranges = [...this.ranges, this.optionsRanges]; - this.optionsRanges = {}; - } - - restore() { - this.description = undefined; - this.gaugeValue = undefined; - this.height = undefined; - this.optionsRanges = {}; - this.ranges = []; - this.title = undefined; - this.properties = ['showPointer', 'showContainerGauge']; - this.changeOptions(); - } - - changeOptions() { - this.options = { - showFromToLegend: this.properties.includes('showFromToLegend'), - pointer: this.properties.includes('showPointer'), - showContainerGauge: this.properties.includes('showContainerGauge'), - subtitleGauge: this.subtitle, - header: { - hideExpand: this.properties.includes('hideExpand'), - hideTableDetails: this.properties.includes('hideTableDetails'), - hideExportCsv: this.properties.includes('hideExportCsv'), - hideExportImage: this.properties.includes('hideExportImage') - } - }; - } -} diff --git a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-summary/sample-po-gauge-summary.component.html b/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-summary/sample-po-gauge-summary.component.html deleted file mode 100644 index b6806f5b65..0000000000 --- a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-summary/sample-po-gauge-summary.component.html +++ /dev/null @@ -1,23 +0,0 @@ - -
    Sales Performance
    -
    -
    - -
    -
    - -
    -
    -
    diff --git a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-summary/sample-po-gauge-summary.component.ts b/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-summary/sample-po-gauge-summary.component.ts deleted file mode 100644 index 562292fde0..0000000000 --- a/projects/ui/src/lib/components/po-gauge/samples/sample-po-gauge-summary/sample-po-gauge-summary.component.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Component } from '@angular/core'; - -import { PoGaugeRanges } from '@po-ui/ng-components'; - -@Component({ - selector: 'sample-po-gauge-summary', - templateUrl: './sample-po-gauge-summary.component.html', - standalone: false -}) -export class SamplePoGaugeSummaryComponent { - salesRanges: Array = [ - { from: 0, to: 50, label: 'Sales reduction', color: '#c64840' }, - { from: 50, to: 75, label: 'Average sales', color: '#ea9b3e' }, - { from: 75, to: 100, label: 'Sales soared', color: '#00b28e' } - ]; - - turnoverRanges: Array = [ - { from: 0, to: 50, label: 'Low rate', color: '#00b28e' }, - { from: 50, to: 75, label: 'Average rate', color: '#ea9b3e' }, - { from: 75, to: 100, label: 'High rate', color: '#c64840' } - ]; -} diff --git a/projects/ui/src/lib/components/po-grid/po-grid-cell-action/po-grid-cell-action.component.ts b/projects/ui/src/lib/components/po-grid/po-grid-cell-action/po-grid-cell-action.component.ts index d3b7f37012..94a6bd26b6 100644 --- a/projects/ui/src/lib/components/po-grid/po-grid-cell-action/po-grid-cell-action.component.ts +++ b/projects/ui/src/lib/components/po-grid/po-grid-cell-action/po-grid-cell-action.component.ts @@ -1,8 +1,9 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'po-grid-cell-action', templateUrl: './po-grid-cell-action.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoGridCellActionComponent { diff --git a/projects/ui/src/lib/components/po-grid/po-grid-cell/po-grid-cell.component.ts b/projects/ui/src/lib/components/po-grid/po-grid-cell/po-grid-cell.component.ts index dc0cfda280..c602c1f8ad 100644 --- a/projects/ui/src/lib/components/po-grid/po-grid-cell/po-grid-cell.component.ts +++ b/projects/ui/src/lib/components/po-grid/po-grid-cell/po-grid-cell.component.ts @@ -6,12 +6,14 @@ import { ChangeDetectorRef, Output, EventEmitter, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'po-grid-cell', templateUrl: './po-grid-cell.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoGridCellComponent { diff --git a/projects/ui/src/lib/components/po-grid/po-grid-head/po-grid-head.component.ts b/projects/ui/src/lib/components/po-grid/po-grid-head/po-grid-head.component.ts index 8d77141878..c1ae27af05 100644 --- a/projects/ui/src/lib/components/po-grid/po-grid-head/po-grid-head.component.ts +++ b/projects/ui/src/lib/components/po-grid/po-grid-head/po-grid-head.component.ts @@ -1,8 +1,9 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'po-grid-head', templateUrl: './po-grid-head.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoGridHeadComponent { diff --git a/projects/ui/src/lib/components/po-grid/po-grid.component.ts b/projects/ui/src/lib/components/po-grid/po-grid.component.ts index b3a1db6a33..fef1d21e0a 100644 --- a/projects/ui/src/lib/components/po-grid/po-grid.component.ts +++ b/projects/ui/src/lib/components/po-grid/po-grid.component.ts @@ -6,7 +6,8 @@ import { OnDestroy, Renderer2, ViewChild, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { PoGridRowActions } from './po-grid-row-actions.interface'; @@ -43,6 +44,7 @@ import { PoGridRowActions } from './po-grid-row-actions.interface'; @Component({ selector: 'po-grid', templateUrl: './po-grid.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoGridComponent implements OnDestroy { diff --git a/projects/ui/src/lib/components/po-grid/samples/sample-po-grid-basic/sample-po-grid-basic.component.ts b/projects/ui/src/lib/components/po-grid/samples/sample-po-grid-basic/sample-po-grid-basic.component.ts index d058aaf36f..e2d5c03514 100644 --- a/projects/ui/src/lib/components/po-grid/samples/sample-po-grid-basic/sample-po-grid-basic.component.ts +++ b/projects/ui/src/lib/components/po-grid/samples/sample-po-grid-basic/sample-po-grid-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-grid-basic', templateUrl: './sample-po-grid-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoGridBasicComponent { diff --git a/projects/ui/src/lib/components/po-header/po-header-base.component.spec.ts b/projects/ui/src/lib/components/po-header/po-header-base.component.spec.ts index 895b77a544..a973c396c1 100644 --- a/projects/ui/src/lib/components/po-header/po-header-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-header/po-header-base.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, fakeAsync, flush, TestBed } from '@angular/core/testing'; import { PoLanguageService, PoThemeA11yEnum } from '../../services'; import { PoHeaderLiterals } from './interfaces/po-header-literals.interface'; @@ -6,6 +6,7 @@ import { PoHeaderBaseComponent, poNavbarLiteralsDefault } from './po-header-base @Component({ template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class TestHostComponent extends PoHeaderBaseComponent { diff --git a/projects/ui/src/lib/components/po-header/po-header-brand/po-header-brand.component.ts b/projects/ui/src/lib/components/po-header/po-header-brand/po-header-brand.component.ts index 7e44753417..a36e553b11 100644 --- a/projects/ui/src/lib/components/po-header/po-header-brand/po-header-brand.component.ts +++ b/projects/ui/src/lib/components/po-header/po-header-brand/po-header-brand.component.ts @@ -10,7 +10,8 @@ import { OnDestroy, Output, SimpleChanges, - ViewChild + ViewChild, + ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; import { debounceTime, fromEvent, map, startWith, Subscription } from 'rxjs'; @@ -21,6 +22,7 @@ import { PoHeaderBrand } from '../interfaces/po-header-brand.interface'; @Component({ selector: 'po-header-brand', templateUrl: './po-header-brand.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoHeaderbrandComponent implements AfterViewInit, OnChanges, OnDestroy { diff --git a/projects/ui/src/lib/components/po-header/po-header-customer/po-header-customer.component.ts b/projects/ui/src/lib/components/po-header/po-header-customer/po-header-customer.component.ts index e6bbe7de50..c48c78589f 100644 --- a/projects/ui/src/lib/components/po-header/po-header-customer/po-header-customer.component.ts +++ b/projects/ui/src/lib/components/po-header/po-header-customer/po-header-customer.component.ts @@ -1,4 +1,4 @@ -import { Component, input, Input, ViewChild } from '@angular/core'; +import { Component, input, Input, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoPopoverComponent } from '../../po-popover'; import { PoPopupComponent } from '../../po-popup'; import { PoHeaderUser } from '../interfaces/po-header-user.interface'; @@ -21,6 +21,7 @@ export const poHeaderCustomerLiteralsDefault = { @Component({ selector: 'po-header-customer', templateUrl: './po-header-customer.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoHeaderCustomerComponent { diff --git a/projects/ui/src/lib/components/po-header/po-header-menu-item/po-header-menu-item.component.ts b/projects/ui/src/lib/components/po-header/po-header-menu-item/po-header-menu-item.component.ts index 22e829e97b..1be9875336 100644 --- a/projects/ui/src/lib/components/po-header/po-header-menu-item/po-header-menu-item.component.ts +++ b/projects/ui/src/lib/components/po-header/po-header-menu-item/po-header-menu-item.component.ts @@ -10,7 +10,8 @@ import { OnInit, Output, SimpleChanges, - ViewChild + ViewChild, + ChangeDetectionStrategy } from '@angular/core'; import { NavigationCancel, NavigationEnd, Router } from '@angular/router'; import { debounceTime, fromEvent, Subscription } from 'rxjs'; @@ -37,6 +38,7 @@ export const poHeaderMoreLiteralsDefault = { @Component({ selector: 'po-header-menu-item', templateUrl: './po-header-menu-item.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoHeaderMenuItemComponent implements OnChanges, OnInit, OnDestroy { diff --git a/projects/ui/src/lib/components/po-header/po-header-tools/po-header-tools.component.ts b/projects/ui/src/lib/components/po-header/po-header-tools/po-header-tools.component.ts index 9ad919efcf..60a0976f19 100644 --- a/projects/ui/src/lib/components/po-header/po-header-tools/po-header-tools.component.ts +++ b/projects/ui/src/lib/components/po-header/po-header-tools/po-header-tools.component.ts @@ -6,7 +6,8 @@ import { Input, QueryList, TemplateRef, - ViewChildren + ViewChildren, + ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; import { PoUtils } from '../../../utils/util'; @@ -19,6 +20,7 @@ import { PoHeaderLiterals } from '../interfaces/po-header-literals.interface'; @Component({ selector: 'po-header-tools', templateUrl: './po-header-tools.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoHeaderToolsComponent { diff --git a/projects/ui/src/lib/components/po-header/po-header.component.spec.ts b/projects/ui/src/lib/components/po-header/po-header.component.spec.ts index 96e03d956a..05597da612 100644 --- a/projects/ui/src/lib/components/po-header/po-header.component.spec.ts +++ b/projects/ui/src/lib/components/po-header/po-header.component.spec.ts @@ -102,52 +102,80 @@ describe('PoHeaderComponent', () => { expect(component['currentWidth']).toBeDefined(); }); - it('should call detectChanges when receiveApplicationMenu emits', () => { + it('should update applicationMenu, updateMenu, combineItemsExternal and handleSmallSreen when receiveApplicationMenu emits a new id on small screen', fakeAsync(() => { spyOn(component['cd'], 'detectChanges'); + spyOn(component, 'updateMenu'); + spyOn(component, 'combineItemsExternal'); + spyOn(component, 'handleSmallSreen'); component.applicationMenu = {} as any; component.previousMenuComponentId = '1'; + Object.defineProperty(window, 'innerWidth', { value: 800, writable: true, configurable: true }); component.ngOnInit(); - receiveApplicationMenu$.next({ id: '2' }); + const newMenu = { id: '2' } as any; + receiveApplicationMenu$.next(newMenu); + tick(100); + expect(component.applicationMenu).toBe(newMenu); + expect(component.updateMenu).toHaveBeenCalled(); + expect(component['combineItemsExternal']).toHaveBeenCalled(); + expect(component.handleSmallSreen).toHaveBeenCalled(); expect(component['cd'].detectChanges).toHaveBeenCalled(); - }); + })); - it('should call detectChanges when receiveApplicationMenu emits and id is the same', () => { + it('should not call handleSmallSreen when receiveApplicationMenu emits a new id on large screen', fakeAsync(() => { spyOn(component['cd'], 'detectChanges'); + spyOn(component, 'updateMenu'); + spyOn(component, 'combineItemsExternal'); + spyOn(component, 'handleSmallSreen'); component.applicationMenu = {} as any; - component.previousMenuComponentId = '2'; - Object.defineProperty(window, 'innerWidth', { value: 800, writable: true, configurable: true }); + component.previousMenuComponentId = '1'; + Object.defineProperty(window, 'innerWidth', { value: 1000, writable: true, configurable: true }); component.ngOnInit(); - receiveApplicationMenu$.next({ id: '2' }); + receiveApplicationMenu$.next({ id: '2' } as any); + tick(100); + expect(component.updateMenu).toHaveBeenCalled(); + expect(component['combineItemsExternal']).toHaveBeenCalled(); + expect(component.handleSmallSreen).not.toHaveBeenCalled(); expect(component['cd'].detectChanges).toHaveBeenCalled(); - }); + })); - it('should not call detectChanges when receiveApplicationMenu has the same id and notChangeContext is true', () => { + it('should set applicationMenu to undefined when receiveApplicationMenu emits the same id', fakeAsync(() => { + spyOn(component['cd'], 'detectChanges'); spyOn(component, 'updateMenu'); component.applicationMenu = {} as any; component.previousMenuComponentId = '2'; - component.notChangeContext = true; component.ngOnInit(); - receiveApplicationMenu$.next({ id: '1' }); + receiveApplicationMenu$.next({ id: '2' } as any); + tick(100); + expect(component.applicationMenu).toBeUndefined(); expect(component.updateMenu).not.toHaveBeenCalled(); - }); + expect(component['cd'].detectChanges).toHaveBeenCalled(); + })); - it('should not call handleSmallSreen when receiveApplicationMenu emits', () => { + it('should return early and not change applicationMenu when notChangeContext is true and id differs', fakeAsync(() => { spyOn(component, 'updateMenu'); - component.applicationMenu = {} as any; + spyOn(component, 'combineItemsExternal'); + const currentMenu = {} as any; + component.applicationMenu = currentMenu; component.previousMenuComponentId = '2'; - Object.defineProperty(window, 'innerWidth', { value: 800, writable: true, configurable: true }); + component.notChangeContext = true; component.ngOnInit(); - receiveApplicationMenu$.next({ id: '1' }); + receiveApplicationMenu$.next({ id: '1' } as any); + tick(100); + // O callback executa o early return: o menu permanece o mesmo e nenhum + // recálculo de itens acontece. Não é assertado detectChanges porque outras + // subscriptions do ngOnInit (ex.: resize com startWith) também o disparam. + expect(component.applicationMenu).toBe(currentMenu); expect(component.updateMenu).not.toHaveBeenCalled(); - }); + expect(component['combineItemsExternal']).not.toHaveBeenCalled(); + })); it('should call detectChanges and handleSmallSreen when receiveRemovedApplicationMenu emits', fakeAsync(() => { spyOn(component['cd'], 'detectChanges'); diff --git a/projects/ui/src/lib/components/po-header/po-header.component.ts b/projects/ui/src/lib/components/po-header/po-header.component.ts index 2456361db8..8d2c079615 100644 --- a/projects/ui/src/lib/components/po-header/po-header.component.ts +++ b/projects/ui/src/lib/components/po-header/po-header.component.ts @@ -10,7 +10,8 @@ import { QueryList, SimpleChanges, ViewChild, - ViewChildren + ViewChildren, + ChangeDetectionStrategy } from '@angular/core'; import { debounceTime, delay, fromEvent, map, startWith, Subscription } from 'rxjs'; import { PoLanguageService } from '../../services'; @@ -45,6 +46,7 @@ import { PoHeaderMenuItemComponent } from './po-header-menu-item/po-header-menu- @Component({ selector: 'po-header', templateUrl: './po-header.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoHeaderComponent extends PoHeaderBaseComponent implements AfterViewInit, OnChanges, OnInit, OnDestroy { diff --git a/projects/ui/src/lib/components/po-header/samples/sample-po-header-apps/sample-po-header-apps.component.ts b/projects/ui/src/lib/components/po-header/samples/sample-po-header-apps/sample-po-header-apps.component.ts index 610f2bd844..88d480e678 100644 --- a/projects/ui/src/lib/components/po-header/samples/sample-po-header-apps/sample-po-header-apps.component.ts +++ b/projects/ui/src/lib/components/po-header/samples/sample-po-header-apps/sample-po-header-apps.component.ts @@ -1,4 +1,12 @@ -import { AfterViewInit, ChangeDetectorRef, Component, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core'; +import { + AfterViewInit, + ChangeDetectorRef, + Component, + TemplateRef, + ViewChild, + ViewEncapsulation, + ChangeDetectionStrategy +} from '@angular/core'; import { PoHeaderActions, @@ -16,6 +24,7 @@ import { templateUrl: './sample-po-header-apps.component.html', standalone: false, encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.Eager, styles: ` sample-po-header-apps { display: block; diff --git a/projects/ui/src/lib/components/po-header/samples/sample-po-header-basic/sample-po-header-basic.component.ts b/projects/ui/src/lib/components/po-header/samples/sample-po-header-basic/sample-po-header-basic.component.ts index d75c0f98ee..7ac1392731 100644 --- a/projects/ui/src/lib/components/po-header/samples/sample-po-header-basic/sample-po-header-basic.component.ts +++ b/projects/ui/src/lib/components/po-header/samples/sample-po-header-basic/sample-po-header-basic.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoHeaderBrand, PoNotificationService } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoHeaderBrand, PoNotificationService } from '@po-ui/ng-components'; selector: 'sample-po-header-basic', templateUrl: './sample-po-header-basic.component.html', standalone: false, + changeDetection: ChangeDetectionStrategy.Eager, styles: ` /* alterado apenas para demonstração no portal*/ po-header { diff --git a/projects/ui/src/lib/components/po-header/samples/sample-po-header-labs/sample-po-header-labs.component.ts b/projects/ui/src/lib/components/po-header/samples/sample-po-header-labs/sample-po-header-labs.component.ts index c5ff4abec1..226169224d 100644 --- a/projects/ui/src/lib/components/po-header/samples/sample-po-header-labs/sample-po-header-labs.component.ts +++ b/projects/ui/src/lib/components/po-header/samples/sample-po-header-labs/sample-po-header-labs.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoHeaderActions, @@ -12,6 +12,7 @@ import { selector: 'sample-po-header-labs', templateUrl: './sample-po-header-labs.component.html', standalone: false, + changeDetection: ChangeDetectionStrategy.Eager, styles: ` /* alterado apenas para demonstração no portal*/ po-header { diff --git a/projects/ui/src/lib/components/po-helper/po-helper-base.component.ts b/projects/ui/src/lib/components/po-helper/po-helper-base.component.ts index 2266122222..614e3ec414 100644 --- a/projects/ui/src/lib/components/po-helper/po-helper-base.component.ts +++ b/projects/ui/src/lib/components/po-helper/po-helper-base.component.ts @@ -1,4 +1,4 @@ -import { Component, HostBinding, input } from '@angular/core'; +import { Component, HostBinding, input, ChangeDetectionStrategy } from '@angular/core'; import { validateSizeFn } from '../../utils/util'; import { PoFieldSize } from '../../enums/po-field-size.enum'; @@ -59,6 +59,7 @@ import { PoHelperCustomAction } from './interfaces/po-helper-custom-action.inter @Component({ selector: 'po-helper-base', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoHelperBaseComponent { diff --git a/projects/ui/src/lib/components/po-helper/po-helper.component.ts b/projects/ui/src/lib/components/po-helper/po-helper.component.ts index fe9dd781b8..1f9548a536 100644 --- a/projects/ui/src/lib/components/po-helper/po-helper.component.ts +++ b/projects/ui/src/lib/components/po-helper/po-helper.component.ts @@ -1,5 +1,4 @@ import { - computed, Component, OnDestroy, OnChanges, @@ -7,7 +6,9 @@ import { ElementRef, AfterViewInit, SimpleChanges, - ChangeDetectorRef + ChangeDetectorRef, + computed, + ChangeDetectionStrategy } from '@angular/core'; import { PoButtonComponent } from '../po-button'; @@ -43,6 +44,7 @@ const PO_HELPER_ALLOWED_TAGS: Array = ['b', 'i', 'u', 'strong', @Component({ selector: 'po-helper', standalone: false, + changeDetection: ChangeDetectionStrategy.Eager, templateUrl: './po-helper.component.html' }) export class PoHelperComponent extends PoHelperBaseComponent implements AfterViewInit, OnDestroy, OnChanges { diff --git a/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-basic/sample-po-helper-basic.component.ts b/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-basic/sample-po-helper-basic.component.ts index a11f2d0152..1d28224975 100644 --- a/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-basic/sample-po-helper-basic.component.ts +++ b/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-basic/sample-po-helper-basic.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoHelperOptions } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-helper-basic', templateUrl: './sample-po-helper-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoHelperBasicComponent { diff --git a/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-labs/sample-po-helper-labs.component.ts b/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-labs/sample-po-helper-labs.component.ts index aa09252006..ec4f9bebb2 100644 --- a/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-labs/sample-po-helper-labs.component.ts +++ b/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-labs/sample-po-helper-labs.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoHelperOptions } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-helper-labs', templateUrl: './sample-po-helper-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoHelperLabsComponent { diff --git a/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-sales-performance/sample-po-helper-sales-performance.component.ts b/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-sales-performance/sample-po-helper-sales-performance.component.ts index d183c20bde..1669e1fb1a 100644 --- a/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-sales-performance/sample-po-helper-sales-performance.component.ts +++ b/projects/ui/src/lib/components/po-helper/samples/sample-po-helper-sales-performance/sample-po-helper-sales-performance.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoHelperOptions, PoChartType, PoChartOptions, PoChartSerie } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-helper-sales-performance', templateUrl: './sample-po-helper-sales-performance.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoHelperSalesPerformanceComponent { diff --git a/projects/ui/src/lib/components/po-image/po-image.component.ts b/projects/ui/src/lib/components/po-image/po-image.component.ts index 88a7d024e3..0fdd7be4f0 100644 --- a/projects/ui/src/lib/components/po-image/po-image.component.ts +++ b/projects/ui/src/lib/components/po-image/po-image.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoImageBaseComponent } from './po-image-base.component'; /** @@ -26,6 +26,7 @@ import { PoImageBaseComponent } from './po-image-base.component'; @Component({ selector: 'po-image', templateUrl: './po-image.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoImageComponent extends PoImageBaseComponent {} diff --git a/projects/ui/src/lib/components/po-image/samples/sample-po-image-basic/sample-po-image-basic.component.ts b/projects/ui/src/lib/components/po-image/samples/sample-po-image-basic/sample-po-image-basic.component.ts index b389cea436..3fc1162ab0 100644 --- a/projects/ui/src/lib/components/po-image/samples/sample-po-image-basic/sample-po-image-basic.component.ts +++ b/projects/ui/src/lib/components/po-image/samples/sample-po-image-basic/sample-po-image-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-image-basic', templateUrl: './sample-po-image-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoImageBasicComponent { diff --git a/projects/ui/src/lib/components/po-image/samples/sample-po-image-labs/sample-po-image-labs.component.ts b/projects/ui/src/lib/components/po-image/samples/sample-po-image-labs/sample-po-image-labs.component.ts index ad6b9b4c0b..69f8087e32 100644 --- a/projects/ui/src/lib/components/po-image/samples/sample-po-image-labs/sample-po-image-labs.component.ts +++ b/projects/ui/src/lib/components/po-image/samples/sample-po-image-labs/sample-po-image-labs.component.ts @@ -1,8 +1,9 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-image-labs', templateUrl: './sample-po-image-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoImageLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-image/samples/sample-po-image-travel/sample-po-image-travel.component.ts b/projects/ui/src/lib/components/po-image/samples/sample-po-image-travel/sample-po-image-travel.component.ts index d288aa1b73..d46136a081 100644 --- a/projects/ui/src/lib/components/po-image/samples/sample-po-image-travel/sample-po-image-travel.component.ts +++ b/projects/ui/src/lib/components/po-image/samples/sample-po-image-travel/sample-po-image-travel.component.ts @@ -1,10 +1,11 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoDatepickerComponent, PoNotificationService, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-image-travel', templateUrl: './sample-po-image-travel.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoImageTravelComponent { diff --git a/projects/ui/src/lib/components/po-info/samples/sample-po-info-basic/sample-po-info-basic.component.ts b/projects/ui/src/lib/components/po-info/samples/sample-po-info-basic/sample-po-info-basic.component.ts index 01d5b93ec3..065331e0fb 100644 --- a/projects/ui/src/lib/components/po-info/samples/sample-po-info-basic/sample-po-info-basic.component.ts +++ b/projects/ui/src/lib/components/po-info/samples/sample-po-info-basic/sample-po-info-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-info-basic', templateUrl: './sample-po-info-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoInfoBasicComponent {} diff --git a/projects/ui/src/lib/components/po-info/samples/sample-po-info-labs/sample-po-info-labs.component.ts b/projects/ui/src/lib/components/po-info/samples/sample-po-info-labs/sample-po-info-labs.component.ts index 453969c7a7..0a279a6a3a 100644 --- a/projects/ui/src/lib/components/po-info/samples/sample-po-info-labs/sample-po-info-labs.component.ts +++ b/projects/ui/src/lib/components/po-info/samples/sample-po-info-labs/sample-po-info-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoInfoOrientation, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-info-labs', templateUrl: './sample-po-info-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoInfoLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-label/po-label.component.ts b/projects/ui/src/lib/components/po-label/po-label.component.ts index 26bcb03758..641e5e5a36 100644 --- a/projects/ui/src/lib/components/po-label/po-label.component.ts +++ b/projects/ui/src/lib/components/po-label/po-label.component.ts @@ -1,4 +1,4 @@ -import { Component, input, Input } from '@angular/core'; +import { Component, input, Input, ChangeDetectionStrategy } from '@angular/core'; import { convertToBoolean } from '../../utils/util'; import { poFieldContainerLiterals } from '../po-field/po-field-container/po-field-container-literals'; @@ -11,6 +11,7 @@ import { poFieldContainerLiterals } from '../po-field/po-field-container/po-fiel @Component({ selector: 'po-label', templateUrl: './po-label.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoLabelComponent { diff --git a/projects/ui/src/lib/components/po-link/po-link.component.ts b/projects/ui/src/lib/components/po-link/po-link.component.ts index ac6900119d..fbc10d1433 100644 --- a/projects/ui/src/lib/components/po-link/po-link.component.ts +++ b/projects/ui/src/lib/components/po-link/po-link.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, ViewChild } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoLinkBaseComponent } from './po-link-base.component'; @@ -25,6 +25,7 @@ import { PoLinkBaseComponent } from './po-link-base.component'; @Component({ selector: 'po-link', templateUrl: './po-link.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoLinkComponent extends PoLinkBaseComponent { diff --git a/projects/ui/src/lib/components/po-link/samples/sample-po-link-basic/sample-po-link-basic.component.ts b/projects/ui/src/lib/components/po-link/samples/sample-po-link-basic/sample-po-link-basic.component.ts index f3f21b06bd..32b3673181 100644 --- a/projects/ui/src/lib/components/po-link/samples/sample-po-link-basic/sample-po-link-basic.component.ts +++ b/projects/ui/src/lib/components/po-link/samples/sample-po-link-basic/sample-po-link-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-link-basic', templateUrl: './sample-po-link-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLinkBasicComponent {} diff --git a/projects/ui/src/lib/components/po-link/samples/sample-po-link-heroes/sample-po-link-heroes.component.ts b/projects/ui/src/lib/components/po-link/samples/sample-po-link-heroes/sample-po-link-heroes.component.ts index 2638953e09..96f7126f84 100644 --- a/projects/ui/src/lib/components/po-link/samples/sample-po-link-heroes/sample-po-link-heroes.component.ts +++ b/projects/ui/src/lib/components/po-link/samples/sample-po-link-heroes/sample-po-link-heroes.component.ts @@ -1,10 +1,11 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoTableColumn, PoModalComponent } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-link-heroes', templateUrl: './sample-po-link-heroes.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLinkHeroesComponent { diff --git a/projects/ui/src/lib/components/po-link/samples/sample-po-link-labs/sample-po-link-labs.component.ts b/projects/ui/src/lib/components/po-link/samples/sample-po-link-labs/sample-po-link-labs.component.ts index 9a11315dbd..2c5db5beef 100644 --- a/projects/ui/src/lib/components/po-link/samples/sample-po-link-labs/sample-po-link-labs.component.ts +++ b/projects/ui/src/lib/components/po-link/samples/sample-po-link-labs/sample-po-link-labs.component.ts @@ -1,8 +1,9 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-link-labs', templateUrl: './sample-po-link-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLinkLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-list-view/po-list-view.component.spec.ts b/projects/ui/src/lib/components/po-list-view/po-list-view.component.spec.ts index 89afbef439..d73e250c15 100644 --- a/projects/ui/src/lib/components/po-list-view/po-list-view.component.spec.ts +++ b/projects/ui/src/lib/components/po-list-view/po-list-view.component.spec.ts @@ -1,6 +1,8 @@ import { provideNgReflectAttributes } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { Observable } from 'rxjs'; @@ -26,7 +28,7 @@ describe('PoListViewComponent:', () => { await TestBed.configureTestingModule({ declarations: [PoListViewComponent], imports: [PoButtonModule, PoPopupModule, PoModalModule, PoWidgetModule], - providers: [provideNgReflectAttributes(), provideRouter([])] + providers: [provideLocationMocks(), provideNgReflectAttributes(), provideRouter([])] }).compileComponents(); fixture = TestBed.createComponent(PoListViewComponent); @@ -768,6 +770,7 @@ describe('PoListViewComponent:', () => { const getStyleSpy = spyOn(window, 'getComputedStyle'); ['none', 'normal', '""', "''", ''].forEach(content => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion getStyleSpy.and.returnValue({ content } as unknown as CSSStyleDeclaration); expect(component['isIconGlyphEmpty'](el)).withContext(`content=${content}`).toBeTrue(); }); @@ -775,6 +778,7 @@ describe('PoListViewComponent:', () => { it('isIconGlyphEmpty: should return false when `::before` has a glyph content', () => { const el = document.createElement('i'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(window, 'getComputedStyle').and.returnValue({ content: '"\\e900"' } as CSSStyleDeclaration); expect(component['isIconGlyphEmpty'](el)).toBeFalse(); @@ -786,6 +790,7 @@ describe('PoListViewComponent:', () => { root.appendChild(avatarContainer); Object.defineProperty(component['elementRef'], 'nativeElement', { get: () => root, configurable: true }); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(window, 'getComputedStyle').and.returnValue({ content: 'none' } as CSSStyleDeclaration); const setStyleSpy = spyOn(component['renderer'], 'setStyle'); @@ -802,6 +807,7 @@ describe('PoListViewComponent:', () => { root.appendChild(avatarContainer); Object.defineProperty(component['elementRef'], 'nativeElement', { get: () => root, configurable: true }); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(window, 'getComputedStyle').and.returnValue({ content: '"\\e900"' } as CSSStyleDeclaration); const removeStyleSpy = spyOn(component['renderer'], 'removeStyle'); @@ -1317,6 +1323,7 @@ describe('PoListViewComponent:', () => { const selectSpy = spyOn(component, 'selectListItem'); spyOn(component.itemClick, 'emit'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion expect(() => component['onItemClick'](testItem, null as any)).not.toThrow(); expect(selectSpy).toHaveBeenCalledWith(testItem); expect(component.itemClick.emit).toHaveBeenCalled(); diff --git a/projects/ui/src/lib/components/po-list-view/po-list-view.component.ts b/projects/ui/src/lib/components/po-list-view/po-list-view.component.ts index fa6783d667..a5ec430e4a 100644 --- a/projects/ui/src/lib/components/po-list-view/po-list-view.component.ts +++ b/projects/ui/src/lib/components/po-list-view/po-list-view.component.ts @@ -11,7 +11,8 @@ import { IterableDiffers, Renderer2, TemplateRef, - ViewChild + ViewChild, + ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; @@ -55,6 +56,7 @@ import { PoListViewDetailTemplateDirective } from './po-list-view-detail-templat @Component({ selector: 'po-list-view', templateUrl: './po-list-view.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoListViewComponent diff --git a/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-basic/sample-po-list-view-basic.component.ts b/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-basic/sample-po-list-view-basic.component.ts index f5e6cfc5ce..27ee5925a6 100644 --- a/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-basic/sample-po-list-view-basic.component.ts +++ b/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-basic/sample-po-list-view-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-list-view-basic', templateUrl: './sample-po-list-view-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoListViewBasicComponent {} diff --git a/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-hiring-processes/sample-po-list-view-hiring-processes.component.ts b/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-hiring-processes/sample-po-list-view-hiring-processes.component.ts index 19adbae535..f744dad956 100644 --- a/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-hiring-processes/sample-po-list-view-hiring-processes.component.ts +++ b/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-hiring-processes/sample-po-list-view-hiring-processes.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoListViewAction, @@ -15,6 +15,7 @@ import { SamplePoListViewHiringProcessesService } from './sample-po-list-view-hi selector: 'sample-po-list-view-hiring-processes', templateUrl: 'sample-po-list-view-hiring-processes.component.html', providers: [SamplePoListViewHiringProcessesService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoListViewHiringProcessesComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-labs/sample-po-list-view-labs.component.ts b/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-labs/sample-po-list-view-labs.component.ts index eebd9a344d..419b292f65 100644 --- a/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-labs/sample-po-list-view-labs.component.ts +++ b/projects/ui/src/lib/components/po-list-view/samples/sample-po-list-view-labs/sample-po-list-view-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, @@ -13,6 +13,7 @@ import { @Component({ selector: 'sample-po-list-view-labs', templateUrl: './sample-po-list-view-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoListViewLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-listbox/po-item-list/po-item-list.component.spec.ts b/projects/ui/src/lib/components/po-listbox/po-item-list/po-item-list.component.spec.ts index 9fc3106ca8..ef03d2b167 100644 --- a/projects/ui/src/lib/components/po-listbox/po-item-list/po-item-list.component.spec.ts +++ b/projects/ui/src/lib/components/po-listbox/po-item-list/po-item-list.component.spec.ts @@ -1,6 +1,6 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; import { PoItemListComponent } from './po-item-list.component'; import { PoItemListFilterMode } from '../enums/po-item-list-filter-mode.enum'; @@ -15,8 +15,8 @@ describe('PoItemListComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [PoItemListComponent], - imports: [RouterTestingModule], - schemas: [NO_ERRORS_SCHEMA] + schemas: [NO_ERRORS_SCHEMA], + providers: [provideLocationMocks()] }).compileComponents(); }); diff --git a/projects/ui/src/lib/components/po-listbox/po-item-list/po-item-list.component.ts b/projects/ui/src/lib/components/po-listbox/po-item-list/po-item-list.component.ts index c988dd48a2..5acea7a72f 100644 --- a/projects/ui/src/lib/components/po-listbox/po-item-list/po-item-list.component.ts +++ b/projects/ui/src/lib/components/po-listbox/po-item-list/po-item-list.component.ts @@ -1,4 +1,12 @@ -import { Component, ElementRef, OnChanges, SimpleChanges, ViewChild, inject } from '@angular/core'; +import { + Component, + ElementRef, + OnChanges, + SimpleChanges, + ViewChild, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { PoFieldSize } from '../../../enums/po-field-size.enum'; @@ -9,6 +17,7 @@ import { PoItemListBaseComponent } from './po-item-list-base.component'; @Component({ selector: 'po-item-list', templateUrl: './po-item-list.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoItemListComponent extends PoItemListBaseComponent implements OnChanges { diff --git a/projects/ui/src/lib/components/po-listbox/po-listbox.component.spec.ts b/projects/ui/src/lib/components/po-listbox/po-listbox.component.spec.ts index 6fc5f04704..35d81f437e 100644 --- a/projects/ui/src/lib/components/po-listbox/po-listbox.component.spec.ts +++ b/projects/ui/src/lib/components/po-listbox/po-listbox.component.spec.ts @@ -462,6 +462,7 @@ describe('PoListBoxComponent', () => { component.openGroup(group, new MouseEvent('click')); expect(component.currentGroup).toBe(group); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion expect(component.currentItems).toEqual(group.subItems as Array); setTimeout(() => { @@ -497,6 +498,7 @@ describe('PoListBoxComponent', () => { component.openGroup(group1); expect(component.currentGroup).toEqual(group1); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion expect(component.currentItems).toEqual(group1.subItems as Array); expect((component as any).navigationStack.length).toBe(1); @@ -504,11 +506,13 @@ describe('PoListBoxComponent', () => { component.openGroup(group2); expect(component.currentGroup).toEqual(group2); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion expect(component.currentItems).toEqual(group2.subItems as Array); expect((component as any).navigationStack.length).toBe(2); component.goBack(new KeyboardEvent('keydown', { key: 'Enter' })); expect(component.currentGroup).toEqual(group1); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion expect(component.currentItems).toEqual(group1.subItems as Array); expect((component as any).navigationStack.length).toBe(1); diff --git a/projects/ui/src/lib/components/po-listbox/po-listbox.component.ts b/projects/ui/src/lib/components/po-listbox/po-listbox.component.ts index dbf0863f8c..5684022005 100644 --- a/projects/ui/src/lib/components/po-listbox/po-listbox.component.ts +++ b/projects/ui/src/lib/components/po-listbox/po-listbox.component.ts @@ -17,7 +17,8 @@ import { WritableSignal, effect, inject, - signal + signal, + ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; import { CdkListbox, CdkOption } from '@angular/cdk/listbox'; @@ -35,6 +36,7 @@ const PO_LISTBOX_ROOT_KEY = 'ROOT'; @Component({ selector: 'po-listbox', templateUrl: './po-listbox.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoListBoxComponent extends PoListBoxBaseComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy { diff --git a/projects/ui/src/lib/components/po-loading/po-loading-icon/po-loading-icon.component.spec.ts b/projects/ui/src/lib/components/po-loading/po-loading-icon/po-loading-icon.component.spec.ts index fa478b59a9..3816ad3aaf 100644 --- a/projects/ui/src/lib/components/po-loading/po-loading-icon/po-loading-icon.component.spec.ts +++ b/projects/ui/src/lib/components/po-loading/po-loading-icon/po-loading-icon.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { configureTestSuite, expectPropertiesValues } from '../../../util-test/util-expect.spec'; @@ -11,6 +11,7 @@ import { LoadingIconComponent } from '../interfaces/po-loading-icon-component'; @Component({ selector: 'po-custom-loading-icon', template: '
    Custom Loading
    ', + changeDetection: ChangeDetectionStrategy.Eager, standalone: true }) class CustomLoadingIconComponent implements LoadingIconComponent { diff --git a/projects/ui/src/lib/components/po-loading/po-loading-icon/po-loading-icon.component.ts b/projects/ui/src/lib/components/po-loading/po-loading-icon/po-loading-icon.component.ts index f360c81daa..aeed2f6059 100644 --- a/projects/ui/src/lib/components/po-loading/po-loading-icon/po-loading-icon.component.ts +++ b/projects/ui/src/lib/components/po-loading/po-loading-icon/po-loading-icon.component.ts @@ -8,7 +8,8 @@ import { Optional, Type, ViewChild, - ViewContainerRef + ViewContainerRef, + ChangeDetectionStrategy } from '@angular/core'; import { convertToBoolean, uuid } from '../../../utils/util'; @@ -27,6 +28,7 @@ import { LoadingIconComponent } from '../interfaces/po-loading-icon-component'; @Component({ selector: 'po-loading-icon', templateUrl: 'po-loading-icon.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoLoadingIconComponent implements AfterViewInit, OnDestroy { diff --git a/projects/ui/src/lib/components/po-loading/po-loading-overlay/po-loading-overlay.component.ts b/projects/ui/src/lib/components/po-loading/po-loading-overlay/po-loading-overlay.component.ts index 9dd79994a1..860b5cdfac 100644 --- a/projects/ui/src/lib/components/po-loading/po-loading-overlay/po-loading-overlay.component.ts +++ b/projects/ui/src/lib/components/po-loading/po-loading-overlay/po-loading-overlay.component.ts @@ -1,4 +1,4 @@ -import { Component, ChangeDetectorRef, inject } from '@angular/core'; +import { Component, ChangeDetectorRef, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoLanguageService } from './../../../services/po-language/po-language.service'; @@ -30,6 +30,7 @@ import { PoLoadingOverlayBaseComponent } from './po-loading-overlay-base.compone @Component({ selector: 'po-loading-overlay', templateUrl: 'po-loading-overlay.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoLoadingOverlayComponent extends PoLoadingOverlayBaseComponent { diff --git a/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-basic/sample-po-loading-overlay-basic.component.ts b/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-basic/sample-po-loading-overlay-basic.component.ts index 5b96d644fa..61c2294829 100644 --- a/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-basic/sample-po-loading-overlay-basic.component.ts +++ b/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-basic/sample-po-loading-overlay-basic.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-loading-overlay-basic', templateUrl: './sample-po-loading-overlay-basic.component.html', styleUrls: ['./sample-po-loading-overlay-basic.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLoadingOverlayBasicComponent {} diff --git a/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-connection-test/sample-po-loading-overlay-connection-test.component.ts b/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-connection-test/sample-po-loading-overlay-connection-test.component.ts index 9b123463b3..783901f4a4 100644 --- a/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-connection-test/sample-po-loading-overlay-connection-test.component.ts +++ b/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-connection-test/sample-po-loading-overlay-connection-test.component.ts @@ -1,10 +1,11 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-loading-overlay-connection-test', templateUrl: 'sample-po-loading-overlay-connection-test.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLoadingOverlayConnectionTestComponent { diff --git a/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-labs/sample-po-loading-overlay-labs.component.ts b/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-labs/sample-po-loading-overlay-labs.component.ts index 759a70edc2..cce852b16a 100644 --- a/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-labs/sample-po-loading-overlay-labs.component.ts +++ b/projects/ui/src/lib/components/po-loading/po-loading-overlay/samples/sample-po-loading-overlay-labs/sample-po-loading-overlay-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components' selector: 'sample-po-loading-overlay-labs', templateUrl: './sample-po-loading-overlay-labs.component.html', styleUrls: ['./sample-po-loading-overlay-labs.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoLoadingOverlayLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-loading/po-loading.component.ts b/projects/ui/src/lib/components/po-loading/po-loading.component.ts index d6e75ff7ff..80b079e47e 100644 --- a/projects/ui/src/lib/components/po-loading/po-loading.component.ts +++ b/projects/ui/src/lib/components/po-loading/po-loading.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoLoadingBaseComponent } from './po-loading-base.component'; @@ -10,6 +10,7 @@ import { PoLoadingBaseComponent } from './po-loading-base.component'; @Component({ selector: 'po-loading', templateUrl: 'po-loading.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoLoadingComponent extends PoLoadingBaseComponent {} diff --git a/projects/ui/src/lib/components/po-logo/po-logo.component.ts b/projects/ui/src/lib/components/po-logo/po-logo.component.ts index 43c08368a9..203a6bd03b 100644 --- a/projects/ui/src/lib/components/po-logo/po-logo.component.ts +++ b/projects/ui/src/lib/components/po-logo/po-logo.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; import { PoLanguageService } from '../../services/po-language/po-language.service'; import { isTypeof } from '../../utils/util'; @@ -23,6 +23,7 @@ const MAX_LENGHT: number = 125; @Component({ selector: 'po-logo', templateUrl: './po-logo.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoLogoComponent { diff --git a/projects/ui/src/lib/components/po-menu-panel/po-menu-panel-item/po-menu-panel-item.component.spec.ts b/projects/ui/src/lib/components/po-menu-panel/po-menu-panel-item/po-menu-panel-item.component.spec.ts index 336e7b2e57..26f132ee9d 100644 --- a/projects/ui/src/lib/components/po-menu-panel/po-menu-panel-item/po-menu-panel-item.component.spec.ts +++ b/projects/ui/src/lib/components/po-menu-panel/po-menu-panel-item/po-menu-panel-item.component.spec.ts @@ -1,5 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { Observable } from 'rxjs'; @@ -19,9 +20,9 @@ describe('PoMenuPanelItemComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([]), PoTooltipModule], + imports: [RouterModule.forRoot([]), PoTooltipModule], declarations: [PoMenuPanelItemComponent], - providers: [PoMenuPanelItemsService] + providers: [provideLocationMocks(), PoMenuPanelItemsService] }).compileComponents(); fixture = TestBed.createComponent(PoMenuPanelItemComponent); diff --git a/projects/ui/src/lib/components/po-menu-panel/po-menu-panel-item/po-menu-panel-item.component.ts b/projects/ui/src/lib/components/po-menu-panel/po-menu-panel-item/po-menu-panel-item.component.ts index 7fb65401ea..aa2ae2e7dd 100644 --- a/projects/ui/src/lib/components/po-menu-panel/po-menu-panel-item/po-menu-panel-item.component.ts +++ b/projects/ui/src/lib/components/po-menu-panel/po-menu-panel-item/po-menu-panel-item.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnDestroy, OnInit, inject } from '@angular/core'; +import { Component, Input, OnDestroy, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { Subscription } from 'rxjs'; @@ -15,6 +15,7 @@ import { PoMenuPanelItemsService } from '../services/po-menu-panel-items.service @Component({ selector: 'po-menu-panel-item', templateUrl: './po-menu-panel-item.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoMenuPanelItemComponent implements OnDestroy, OnInit { diff --git a/projects/ui/src/lib/components/po-menu-panel/po-menu-panel.component.spec.ts b/projects/ui/src/lib/components/po-menu-panel/po-menu-panel.component.spec.ts index 06d7fcb338..72ecc0a69e 100644 --- a/projects/ui/src/lib/components/po-menu-panel/po-menu-panel.component.spec.ts +++ b/projects/ui/src/lib/components/po-menu-panel/po-menu-panel.component.spec.ts @@ -1,7 +1,7 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { Router, Routes } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { Router, Routes, RouterModule } from '@angular/router'; import { Observable } from 'rxjs'; @@ -13,6 +13,7 @@ import { PoMenuPanelItemsService } from './services/po-menu-panel-items.service' @Component({ selector: 'app-menu-panel-search', template: 'Search', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SearchComponent {} @@ -20,6 +21,7 @@ export class SearchComponent {} @Component({ selector: 'app-menu-panel-home', template: 'Home', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class HomeComponent {} @@ -40,9 +42,9 @@ describe('PoMenuPanelComponent: ', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes(routes), PoTooltipModule], + imports: [RouterModule.forRoot(routes), PoTooltipModule], declarations: [PoMenuPanelComponent, PoMenuPanelItemComponent, HomeComponent, SearchComponent], - providers: [PoMenuPanelItemsService] + providers: [provideLocationMocks(), PoMenuPanelItemsService] }).compileComponents(); router = TestBed.inject(Router); diff --git a/projects/ui/src/lib/components/po-menu-panel/po-menu-panel.component.ts b/projects/ui/src/lib/components/po-menu-panel/po-menu-panel.component.ts index 0589e989fc..4fbf31cada 100644 --- a/projects/ui/src/lib/components/po-menu-panel/po-menu-panel.component.ts +++ b/projects/ui/src/lib/components/po-menu-panel/po-menu-panel.component.ts @@ -1,5 +1,5 @@ import { Location } from '@angular/common'; -import { Component, OnDestroy, OnInit, ViewContainerRef, inject } from '@angular/core'; +import { Component, OnDestroy, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { NavigationEnd, Router } from '@angular/router'; import { Subscription } from 'rxjs'; @@ -82,6 +82,7 @@ import { PoMenuPanelItemsService } from './services/po-menu-panel-items.service' @Component({ selector: 'po-menu-panel', templateUrl: './po-menu-panel.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoMenuPanelComponent extends PoMenuPanelBaseComponent implements OnDestroy, OnInit { diff --git a/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-basic/sample-po-menu-panel-basic.component.ts b/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-basic/sample-po-menu-panel-basic.component.ts index d9f10760d9..840b345d44 100644 --- a/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-basic/sample-po-menu-panel-basic.component.ts +++ b/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-basic/sample-po-menu-panel-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-menu-panel-basic', templateUrl: './sample-po-menu-panel-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMenuPanelBasicComponent {} diff --git a/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-customer/sample-po-menu-panel-customer.component.ts b/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-customer/sample-po-menu-panel-customer.component.ts index f6b916d34f..3af1c5ae09 100644 --- a/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-customer/sample-po-menu-panel-customer.component.ts +++ b/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-customer/sample-po-menu-panel-customer.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoMenuPanelItem } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-menu-panel-customer', templateUrl: './sample-po-menu-panel-customer.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMenuPanelCustomerComponent { diff --git a/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-labs/sample-po-menu-panel-labs.component.ts b/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-labs/sample-po-menu-panel-labs.component.ts index efb0d74775..b39a0cb0d4 100644 --- a/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-labs/sample-po-menu-panel-labs.component.ts +++ b/projects/ui/src/lib/components/po-menu-panel/samples/sample-po-menu-panel-labs/sample-po-menu-panel-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoMenuPanelItem, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-menu-panel-labs', templateUrl: './sample-po-menu-panel-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMenuPanelLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-menu/po-menu-base.component.spec.ts b/projects/ui/src/lib/components/po-menu/po-menu-base.component.spec.ts index 8ccf76fb80..9cfc7504da 100644 --- a/projects/ui/src/lib/components/po-menu/po-menu-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-menu/po-menu-base.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { of } from 'rxjs'; @@ -10,6 +10,7 @@ import { PoMenuFilter } from './po-menu-filter/po-menu-filter.interface'; @Component({ template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: true }) export class PoMenuComponent extends PoMenuBaseComponent { diff --git a/projects/ui/src/lib/components/po-menu/po-menu-filter/po-menu-filter.component.ts b/projects/ui/src/lib/components/po-menu/po-menu-filter/po-menu-filter.component.ts index ba1aed4f34..074de3fdaf 100644 --- a/projects/ui/src/lib/components/po-menu/po-menu-filter/po-menu-filter.component.ts +++ b/projects/ui/src/lib/components/po-menu/po-menu-filter/po-menu-filter.component.ts @@ -1,4 +1,13 @@ -import { Component, ElementRef, EventEmitter, Input, Output, ViewChild, inject } from '@angular/core'; +import { + Component, + ElementRef, + EventEmitter, + Input, + Output, + ViewChild, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { PoLanguageService } from '../../../services/po-language/po-language.service'; import { PoMenuFilterLiterals } from './po-menu-filter-literals.interface'; @@ -19,6 +28,7 @@ export const poMenuFilterLiteralsDefault = { @Component({ selector: 'po-menu-filter', templateUrl: './po-menu-filter.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoMenuFilterComponent { diff --git a/projects/ui/src/lib/components/po-menu/po-menu-item/po-menu-item.component.spec.ts b/projects/ui/src/lib/components/po-menu/po-menu-item/po-menu-item.component.spec.ts index 4316544e82..aa03936567 100644 --- a/projects/ui/src/lib/components/po-menu/po-menu-item/po-menu-item.component.spec.ts +++ b/projects/ui/src/lib/components/po-menu/po-menu-item/po-menu-item.component.spec.ts @@ -1,7 +1,7 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; -import { Routes } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { Routes, RouterModule } from '@angular/router'; import { Observable } from 'rxjs'; @@ -15,6 +15,7 @@ import { PoMenuItemComponent } from './po-menu-item.component'; @Component({ selector: 'app-menu-item-search', template: 'Search', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SearchComponent {} @@ -22,6 +23,7 @@ export class SearchComponent {} @Component({ selector: 'app-menu-item-home', template: 'Home', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class HomeComponent {} @@ -39,9 +41,9 @@ describe('PoMenuItemComponent:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes(routes), PoIconModule], + imports: [RouterModule.forRoot(routes), PoIconModule], declarations: [SearchComponent, HomeComponent, PoMenuItemComponent, PoBadgeComponent], - providers: [PoMenuItemsService] + providers: [provideLocationMocks(), PoMenuItemsService] }).compileComponents(); fixture = TestBed.createComponent(PoMenuItemComponent); diff --git a/projects/ui/src/lib/components/po-menu/po-menu-item/po-menu-item.component.ts b/projects/ui/src/lib/components/po-menu/po-menu-item/po-menu-item.component.ts index a3a3e55e33..ba3105936d 100644 --- a/projects/ui/src/lib/components/po-menu/po-menu-item/po-menu-item.component.ts +++ b/projects/ui/src/lib/components/po-menu/po-menu-item/po-menu-item.component.ts @@ -1,4 +1,14 @@ -import { Component, ElementRef, Input, OnDestroy, OnInit, TemplateRef, ViewChild, inject } from '@angular/core'; +import { + Component, + ElementRef, + Input, + OnDestroy, + OnInit, + TemplateRef, + ViewChild, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { Subscription } from 'rxjs'; @@ -20,6 +30,7 @@ const poMenuItemSubItemSize = 98; @Component({ selector: 'po-menu-item', templateUrl: './po-menu-item.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoMenuItemComponent implements OnDestroy, OnInit { diff --git a/projects/ui/src/lib/components/po-menu/po-menu.component.spec.ts b/projects/ui/src/lib/components/po-menu/po-menu.component.spec.ts index 96a1f06b3c..9dde38db32 100644 --- a/projects/ui/src/lib/components/po-menu/po-menu.component.spec.ts +++ b/projects/ui/src/lib/components/po-menu/po-menu.component.spec.ts @@ -1,9 +1,9 @@ import { Location } from '@angular/common'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; -import { Router, Routes, UrlSegment, UrlSegmentGroup, UrlTree } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { Router, Routes, UrlSegment, UrlSegmentGroup, UrlTree, RouterModule } from '@angular/router'; import { Observable, of } from 'rxjs'; @@ -13,7 +13,7 @@ import { PoCleanComponent } from './../po-field/po-clean/po-clean.component'; import { PoIconModule } from '../po-icon/po-icon.module'; import { PoLoadingModule } from '../po-loading/po-loading.module'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { PoBadgeComponent } from '../po-badge'; import { PoMenuFilterComponent } from './po-menu-filter/po-menu-filter.component'; import { PoMenuItemComponent } from './po-menu-item/po-menu-item.component'; @@ -24,6 +24,7 @@ import { PoMenuService } from './services/po-menu.service'; @Component({ selector: 'app-menu-search', template: 'Search', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SearchComponent {} @@ -31,6 +32,7 @@ export class SearchComponent {} @Component({ selector: 'app-menu-home', template: 'Home', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class HomeComponent {} @@ -63,11 +65,12 @@ describe('PoMenuComponent:', () => { SearchComponent, PoBadgeComponent ], - imports: [RouterTestingModule.withRoutes(routes), PoLoadingModule, PoIconModule], + imports: [RouterModule.forRoot(routes), PoLoadingModule, PoIconModule], providers: [ + provideLocationMocks(), PoMenuItemsService, PoMenuService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }).compileComponents(); diff --git a/projects/ui/src/lib/components/po-menu/po-menu.component.ts b/projects/ui/src/lib/components/po-menu/po-menu.component.ts index ad81d88694..18ee70c800 100644 --- a/projects/ui/src/lib/components/po-menu/po-menu.component.ts +++ b/projects/ui/src/lib/components/po-menu/po-menu.component.ts @@ -10,7 +10,8 @@ import { OnInit, Renderer2, SimpleChanges, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { NavigationCancel, NavigationEnd, Router } from '@angular/router'; @@ -121,6 +122,7 @@ const poMenuRootLevel = 1; selector: 'po-menu', templateUrl: './po-menu.component.html', providers: [PoMenuItemsService, PoMenuService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoMenuComponent diff --git a/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-basic/sample-po-menu-basic.component.ts b/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-basic/sample-po-menu-basic.component.ts index bf3215469d..2cfa51850a 100644 --- a/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-basic/sample-po-menu-basic.component.ts +++ b/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-basic/sample-po-menu-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-menu-basic', templateUrl: './sample-po-menu-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMenuBasicComponent {} diff --git a/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-human-resources/sample-po-menu-human-resources.component.ts b/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-human-resources/sample-po-menu-human-resources.component.ts index 0f692c35bb..42532b1820 100644 --- a/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-human-resources/sample-po-menu-human-resources.component.ts +++ b/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-human-resources/sample-po-menu-human-resources.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoMenuItem } from '@po-ui/ng-components'; @@ -9,6 +9,7 @@ import { SamplePoMenuHumanResourcesService } from './sample-po-menu-human-resour templateUrl: './sample-po-menu-human-resources.component.html', providers: [SamplePoMenuHumanResourcesService], styleUrls: ['./sample-po-menu-human-resources.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMenuHumanResourcesComponent { diff --git a/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-labs/sample-po-menu-labs.component.ts b/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-labs/sample-po-menu-labs.component.ts index d21ff166b9..d8133804a5 100644 --- a/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-labs/sample-po-menu-labs.component.ts +++ b/projects/ui/src/lib/components/po-menu/samples/sample-po-menu-labs/sample-po-menu-labs.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component, OnInit, ViewChild, inject } from '@angular/core'; +import { ChangeDetectorRef, Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoButtonGroupItem, @@ -12,6 +12,7 @@ import { selector: 'sample-po-menu-labs', templateUrl: './sample-po-menu-labs.component.html', styleUrls: ['./sample-po-menu-labs.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoMenuLabsComponent implements OnInit { @@ -193,15 +194,15 @@ export class SamplePoMenuLabsComponent implements OnInit { this.parentList = []; this.menuItems.forEach(item => { - this.parentList.push({ label: item.label, value: item['id'] }); + this.parentList.push({ label: item.label, value: item['id'] }); if (item.subItems) { item.subItems.forEach(secondItem => { - this.parentList.push({ label: `- ${secondItem.label}`, value: secondItem['id'] }); + this.parentList.push({ label: `- ${secondItem.label}`, value: secondItem['id'] }); if (secondItem.subItems) { secondItem.subItems.forEach(thirdItem => { - this.parentList.push({ label: `-- ${thirdItem.label}`, value: thirdItem['id'] }); + this.parentList.push({ label: `-- ${thirdItem.label}`, value: thirdItem['id'] }); }); } }); diff --git a/projects/ui/src/lib/components/po-menu/services/po-menu.service.spec.ts b/projects/ui/src/lib/components/po-menu/services/po-menu.service.spec.ts index bc31e7c99f..6dc1f11cec 100644 --- a/projects/ui/src/lib/components/po-menu/services/po-menu.service.spec.ts +++ b/projects/ui/src/lib/components/po-menu/services/po-menu.service.spec.ts @@ -1,5 +1,5 @@ import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; -import { HttpRequest, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { HttpRequest, provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { TestBed } from '@angular/core/testing'; import { PoMenuService } from './po-menu.service'; @@ -13,7 +13,7 @@ describe('PoMenuService:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [PoMenuService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [PoMenuService, provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting()] }); menuService = TestBed.inject(PoMenuService); diff --git a/projects/ui/src/lib/components/po-modal/po-modal-footer/po-modal-footer.component.ts b/projects/ui/src/lib/components/po-modal/po-modal-footer/po-modal-footer.component.ts index e0c83d1430..c5b8a13e90 100644 --- a/projects/ui/src/lib/components/po-modal/po-modal-footer/po-modal-footer.component.ts +++ b/projects/ui/src/lib/components/po-modal/po-modal-footer/po-modal-footer.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; /** * @description @@ -19,6 +19,7 @@ import { Component, Input } from '@angular/core'; @Component({ selector: 'po-modal-footer', templateUrl: './po-modal-footer.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoModalFooterComponent { diff --git a/projects/ui/src/lib/components/po-modal/po-modal.component.spec.ts b/projects/ui/src/lib/components/po-modal/po-modal.component.spec.ts index 16c3b4b4ed..fa53035b23 100644 --- a/projects/ui/src/lib/components/po-modal/po-modal.component.spec.ts +++ b/projects/ui/src/lib/components/po-modal/po-modal.component.spec.ts @@ -1,5 +1,5 @@ import { By } from '@angular/platform-browser'; -import { Component, DebugElement, ViewChild } from '@angular/core'; +import { Component, DebugElement, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, fakeAsync, flush, TestBed, tick } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; @@ -25,6 +25,7 @@ import { PoModalFooterComponent } from '.'; `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class ContentProjectionComponent { diff --git a/projects/ui/src/lib/components/po-modal/po-modal.component.ts b/projects/ui/src/lib/components/po-modal/po-modal.component.ts index b46bfef849..2ee3c9ee0e 100644 --- a/projects/ui/src/lib/components/po-modal/po-modal.component.ts +++ b/projects/ui/src/lib/components/po-modal/po-modal.component.ts @@ -1,4 +1,4 @@ -import { Component, ContentChild, ElementRef, ViewChild, inject } from '@angular/core'; +import { Component, ContentChild, ElementRef, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { uuid } from '../../utils/util'; import { PoModalBaseComponent } from './po-modal-base.component'; @@ -31,6 +31,7 @@ import { PoLanguageService } from '../../services/po-language/po-language.servic @Component({ selector: 'po-modal', templateUrl: './po-modal.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoModalComponent extends PoModalBaseComponent { diff --git a/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-basic/sample-po-modal-basic.component.ts b/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-basic/sample-po-modal-basic.component.ts index 82d62b7547..556151b230 100644 --- a/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-basic/sample-po-modal-basic.component.ts +++ b/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-basic/sample-po-modal-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-modal-basic', templateUrl: './sample-po-modal-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoModalBasicComponent {} diff --git a/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-fruits-salad/sample-po-modal-fruits-salad.component.ts b/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-fruits-salad/sample-po-modal-fruits-salad.component.ts index 05eac0fe71..df3d450366 100644 --- a/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-fruits-salad/sample-po-modal-fruits-salad.component.ts +++ b/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-fruits-salad/sample-po-modal-fruits-salad.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, inject } from '@angular/core'; +import { Component, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoCheckboxGroupOption, PoComboOption } from '@po-ui/ng-components'; @@ -10,6 +10,7 @@ import { PoModalComponent } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-modal-fruits-salad', templateUrl: './sample-po-modal-fruits-salad.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoModalFruitsSaladComponent { diff --git a/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-labs/sample-po-modal-labs.component.ts b/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-labs/sample-po-modal-labs.component.ts index 07b080ea88..7d849808d3 100644 --- a/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-labs/sample-po-modal-labs.component.ts +++ b/projects/ui/src/lib/components/po-modal/samples/sample-po-modal-labs/sample-po-modal-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, @@ -11,6 +11,7 @@ import { @Component({ selector: 'sample-po-modal-labs', templateUrl: './sample-po-modal-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoModalLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action-popup/po-navbar-action-popup.component.ts b/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action-popup/po-navbar-action-popup.component.ts index 5f94d3b794..6695d1dba1 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action-popup/po-navbar-action-popup.component.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action-popup/po-navbar-action-popup.component.ts @@ -1,10 +1,11 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; import { PoNavbarIconAction } from '../../interfaces/po-navbar-icon-action.interface'; @Component({ selector: 'po-navbar-action-popup', templateUrl: './po-navbar-action-popup.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoNavbarActionPopupComponent { diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action/po-navbar-action.component.spec.ts b/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action/po-navbar-action.component.spec.ts index c306a017ae..1bdc127a5c 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action/po-navbar-action.component.spec.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action/po-navbar-action.component.spec.ts @@ -4,7 +4,7 @@ import { RouterModule } from '@angular/router'; import { PoUtils as utils } from '../../../../utils/util'; import { PoNavbarActionComponent } from './po-navbar-action.component'; -import { PoTooltipModule } from 'projects/ui/src/lib/directives'; +import { PoTooltipModule } from '../../../../directives'; describe('PoNavbarActionComponent:', () => { let component: PoNavbarActionComponent; diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action/po-navbar-action.component.ts b/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action/po-navbar-action.component.ts index 0df4588f9d..c54f47d349 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action/po-navbar-action.component.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-action/po-navbar-action.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, TemplateRef, ViewContainerRef, inject } from '@angular/core'; +import { Component, Input, TemplateRef, inject, ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; import { isExternalLink, PoUtils } from '../../../../utils/util'; @@ -6,6 +6,7 @@ import { isExternalLink, PoUtils } from '../../../../utils/util'; @Component({ selector: 'po-navbar-action', templateUrl: './po-navbar-action.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoNavbarActionComponent { diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-actions.component.ts b/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-actions.component.ts index e1aa721393..d9c824b755 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-actions.component.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar-actions/po-navbar-actions.component.ts @@ -1,10 +1,11 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; import { PoNavbarIconAction } from '../interfaces/po-navbar-icon-action.interface'; @Component({ selector: 'po-navbar-actions', templateUrl: './po-navbar-actions.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoNavbarActionsComponent { diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation-icon/po-navbar-item-navigation-icon.component.spec.ts b/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation-icon/po-navbar-item-navigation-icon.component.spec.ts index 44ed1cd3af..924cfdb3a5 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation-icon/po-navbar-item-navigation-icon.component.spec.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation-icon/po-navbar-item-navigation-icon.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { configureTestSuite } from 'projects/ui/src/lib/util-test/util-expect.spec'; +import { configureTestSuite } from '../../../../util-test/util-expect.spec'; import { PoNavbarItemNavigationIconComponent } from './po-navbar-item-navigation-icon.component'; diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation-icon/po-navbar-item-navigation-icon.component.ts b/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation-icon/po-navbar-item-navigation-icon.component.ts index bd6d7c44b2..5df57be799 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation-icon/po-navbar-item-navigation-icon.component.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation-icon/po-navbar-item-navigation-icon.component.ts @@ -1,8 +1,9 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'po-navbar-item-navigation-icon', templateUrl: './po-navbar-item-navigation-icon.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoNavbarItemNavigationIconComponent { diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation.component.spec.ts b/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation.component.spec.ts index e70a211dc6..ebc035db83 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation.component.spec.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { configureTestSuite } from 'projects/ui/src/lib/util-test/util-expect.spec'; +import { configureTestSuite } from '../../../util-test/util-expect.spec'; import { PoNavbarItemNavigationComponent } from './po-navbar-item-navigation.component'; import { PoNavbarItemNavigationIconComponent } from './po-navbar-item-navigation-icon/po-navbar-item-navigation-icon.component'; diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation.component.ts b/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation.component.ts index 3db8a3b678..7d074b3983 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation.component.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar-item-navigation/po-navbar-item-navigation.component.ts @@ -1,8 +1,9 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'po-navbar-item-navigation', templateUrl: './po-navbar-item-navigation.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoNavbarItemNavigationComponent { diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar-items/po-navbar-item/po-navbar-item.component.ts b/projects/ui/src/lib/components/po-navbar/po-navbar-items/po-navbar-item/po-navbar-item.component.ts index adbb5d0ee1..390a10c943 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar-items/po-navbar-item/po-navbar-item.component.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar-items/po-navbar-item/po-navbar-item.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, EventEmitter, Output } from '@angular/core'; +import { Component, Input, EventEmitter, Output, ChangeDetectionStrategy } from '@angular/core'; import { PoNavbarItem } from '../../interfaces/po-navbar-item.interface'; @@ -7,6 +7,7 @@ import { isExternalLink } from '../../../../utils/util'; @Component({ selector: 'po-navbar-item', templateUrl: './po-navbar-item.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoNavbarItemComponent { diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar-items/po-navbar-items.component.ts b/projects/ui/src/lib/components/po-navbar/po-navbar-items/po-navbar-items.component.ts index e189ed2588..e64ecc3722 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar-items/po-navbar-items.component.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar-items/po-navbar-items.component.ts @@ -7,7 +7,8 @@ import { QueryList, ViewChild, ViewChildren, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { NavigationCancel, NavigationEnd, Router } from '@angular/router'; @@ -19,6 +20,7 @@ import { PoNavbarItemComponent } from './po-navbar-item/po-navbar-item.component @Component({ selector: 'po-navbar-items', templateUrl: './po-navbar-items.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoNavbarItemsComponent implements OnInit, OnDestroy { diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar-logo/po-navbar-logo.component.ts b/projects/ui/src/lib/components/po-navbar/po-navbar-logo/po-navbar-logo.component.ts index bb8feb7689..b4fedaf86b 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar-logo/po-navbar-logo.component.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar-logo/po-navbar-logo.component.ts @@ -1,8 +1,9 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'po-navbar-logo', templateUrl: './po-navbar-logo.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoNavbarLogoComponent { diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar.component.spec.ts b/projects/ui/src/lib/components/po-navbar/po-navbar.component.spec.ts index 858a3580d6..e5c80d0a7e 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar.component.spec.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar.component.spec.ts @@ -9,10 +9,9 @@ import { PoNavbarItemNavigationModule } from './po-navbar-item-navigation/po-nav import { PoMenuModule } from '../po-menu/po-menu.module'; import { PoNavbarLogoComponent } from './po-navbar-logo/po-navbar-logo.component'; import { PoNavbarComponent } from './po-navbar.component'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { changeBrowserInnerWidth } from 'projects/templates/src/lib/util-test/util-expect.spec'; +import { changeBrowserInnerWidth } from '../../../../../templates/src/lib/util-test/util-expect.spec'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoNavbarComponent:', () => { let component: PoNavbarComponent; @@ -22,14 +21,13 @@ describe('PoNavbarComponent:', () => { await TestBed.configureTestingModule({ declarations: [PoNavbarComponent, PoNavbarLogoComponent], imports: [ - BrowserAnimationsModule, PoNavbarActionsModule, PoNavbarItemsModule, PoNavbarItemNavigationModule, PoMenuModule, RouterModule.forRoot([], {}) ], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting()] }).compileComponents(); fixture = TestBed.createComponent(PoNavbarComponent); @@ -294,24 +292,39 @@ describe('PoNavbarComponent:', () => { expect(component['allNavbarItemsWidth'].call(fakeThis)).toBe(35); }); - it(`animate: should call 'buildTransitionAnimation' with offset if has elements`, () => { + it(`animate: should call element.animate with negative offset`, () => { const offset = 400; - spyOn(component, 'buildTransitionAnimation').and.callThrough(); + spyOn(component.navbarItems.navbarItemsContainer.nativeElement, 'animate').and.returnValue({ cancel: () => {} }); component['animate'](offset); - expect(component['buildTransitionAnimation']).toHaveBeenCalledWith(offset); + expect(component.navbarItems.navbarItemsContainer.nativeElement.animate).toHaveBeenCalledWith( + [{ transform: 'translateX(0px)' }, { transform: 'translateX(-400px)' }], + { duration: 250, easing: 'ease', fill: 'forwards' } + ); }); - it(`buildTransitionAnimation: should call builder`, () => { - const offset = 400; + it(`animate: should cancel previous animation before starting new one`, () => { + const cancelSpy = jasmine.createSpy('cancel'); + component['currentAnimation'] = { cancel: cancelSpy } as any; + spyOn(component.navbarItems.navbarItemsContainer.nativeElement, 'animate').and.returnValue({ cancel: () => {} }); + + component['animate'](200); + + expect(cancelSpy).toHaveBeenCalled(); + }); - spyOn(component['builder'], 'build').and.callThrough(); + it(`animate: should track previousAnimatedOffset for smooth transitions`, () => { + spyOn(component.navbarItems.navbarItemsContainer.nativeElement, 'animate').and.returnValue({ cancel: () => {} }); - component['buildTransitionAnimation'](offset); + component['animate'](400); + component['animate'](0); - expect(component['builder'].build).toHaveBeenCalled(); + expect(component.navbarItems.navbarItemsContainer.nativeElement.animate).toHaveBeenCalledWith( + [{ transform: 'translateX(-400px)' }, { transform: 'translateX(0px)' }], + { duration: 250, easing: 'ease', fill: 'forwards' } + ); }); describe('changeNavbarMenuItems', () => { diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar.component.ts b/projects/ui/src/lib/components/po-navbar/po-navbar.component.ts index 3c97b73eb1..26714a39a6 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar.component.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar.component.ts @@ -7,9 +7,9 @@ import { OnInit, Renderer2, ViewChild, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; -import { animate, AnimationBuilder, AnimationFactory, AnimationPlayer, keyframes, style } from '@angular/animations'; import { delay, filter, finalize } from 'rxjs/operators'; import { Subscription } from 'rxjs'; @@ -27,7 +27,6 @@ import { PoNavbarItemsComponent } from './po-navbar-items/po-navbar-items.compon const poNavbarNavigationWidth = 88; const poNavbarMenuMedia = 768; const poNavbarMatchMedia = `(max-width: ${poNavbarMenuMedia}px)`; -const poNavbarTiming = '250ms ease'; /** * @deprecated v23.x.x use `po-header` @@ -37,11 +36,11 @@ const poNavbarTiming = '250ms ease'; @Component({ selector: 'po-navbar', templateUrl: './po-navbar.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoNavbarComponent extends PoNavbarBaseComponent implements AfterViewInit, OnDestroy, OnInit { private readonly renderer = inject(Renderer2); - private readonly builder = inject(AnimationBuilder); private readonly changeDetector = inject(ChangeDetectorRef); private readonly menuGlobalService = inject(PoMenuGlobalService); @@ -60,7 +59,8 @@ export class PoNavbarComponent extends PoNavbarBaseComponent implements AfterVie private readonly id = uuid(); private mediaQuery: any; private offset: number = 0; - private player: AnimationPlayer; + private currentAnimation: Animation; + private previousAnimatedOffset: number = 0; private readonly menuItems: Array; private previousMenuComponentId; private previousMenusItems = []; @@ -178,14 +178,18 @@ export class PoNavbarComponent extends PoNavbarBaseComponent implements AfterVie } private animate(offset: number) { - const animation: AnimationFactory = this.buildTransitionAnimation(offset); + const element = this.navbarItems.navbarItemsContainer.nativeElement; - this.player = animation.create(this.navbarItems.navbarItemsContainer.nativeElement); - this.player.play(); - } + if (this.currentAnimation) { + this.currentAnimation.cancel(); + } + + this.currentAnimation = element.animate( + [{ transform: `translateX(${-this.previousAnimatedOffset}px)` }, { transform: `translateX(${-offset}px)` }], + { duration: 250, easing: 'ease', fill: 'forwards' } + ); - private buildTransitionAnimation(offset: number) { - return this.builder.build([animate(poNavbarTiming, keyframes([style({ transform: `translateX(${-offset}px)` })]))]); + this.previousAnimatedOffset = offset; } private changeNavbarMenuItems(isCollapsedMedia: any, navbarItems: Array, label: string) { diff --git a/projects/ui/src/lib/components/po-navbar/po-navbar.module.ts b/projects/ui/src/lib/components/po-navbar/po-navbar.module.ts index dfe526a857..a41da5e5c6 100644 --- a/projects/ui/src/lib/components/po-navbar/po-navbar.module.ts +++ b/projects/ui/src/lib/components/po-navbar/po-navbar.module.ts @@ -19,44 +19,6 @@ import { PoNavbarComponent } from './po-navbar.component'; * > Esse componente está **depreciado** e será removido na `v23.x.x`. Recomendamos utilizar o componente * [po-header](https://po-ui.io/documentation/po-header), que oferece compatibilidade com todas as funcionalidades do * `po-navbar`, além de maior flexibilidade, usabilidade e acessibilidade. - * > - * > Para o correto funcionamento do componente `po-navbar`, deve ser importado o módulo `BrowserAnimationsModule` no - * módulo principal da sua aplicação. - * - * Módulo da aplicação: - * ``` - * import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - * import { PoModule } from '@po-ui/ng-components'; - * ... - * - * @NgModule({ - * imports: [ - * BrowserModule, - * BrowserAnimationsModule, - * ... - * PoModule - * ], - * declarations: [ - * AppComponent, - * ... - * ], - * providers: [], - * bootstrap: [AppComponent] - * }) - * export class AppModule { } - * ``` - * - * Em aplicações Standalone, utilize a seguinte configuração para o bootstrap: - * - * ``` - * import { bootstrapApplication } from '@angular/platform-browser'; - * import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - * import { AppComponent } from './app.component'; - * - * bootstrapApplication(AppComponent, { - * providers: [importProvidersFrom(BrowserAnimationsModule)] - * }).catch(err => console.error(err)); - * ``` */ @NgModule({ imports: [ diff --git a/projects/ui/src/lib/components/po-overlay/po-overlay.component.ts b/projects/ui/src/lib/components/po-overlay/po-overlay.component.ts index ff55394c33..7e42af99f0 100644 --- a/projects/ui/src/lib/components/po-overlay/po-overlay.component.ts +++ b/projects/ui/src/lib/components/po-overlay/po-overlay.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoOverlayBaseComponent } from './po-overlay-base.component'; @Component({ selector: 'po-overlay', templateUrl: './po-overlay.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoOverlayComponent extends PoOverlayBaseComponent {} diff --git a/projects/ui/src/lib/components/po-page/po-page-content/po-page-content.component.spec.ts b/projects/ui/src/lib/components/po-page/po-page-content/po-page-content.component.spec.ts index 9defd1ad77..b24052f8ec 100644 --- a/projects/ui/src/lib/components/po-page/po-page-content/po-page-content.component.spec.ts +++ b/projects/ui/src/lib/components/po-page/po-page-content/po-page-content.component.spec.ts @@ -93,5 +93,53 @@ describe('PoPageContentComponent:', () => { expect(component.height).toBe('90%'); })); + + it('should set height in pixels when calculated height is positive without .po-page', fakeAsync(() => { + spyOn(fixture.nativeElement, 'getBoundingClientRect').and.returnValue({ + top: 100, + bottom: 200, + left: 0, + right: 0, + width: 0, + height: 0 + }); + + component.recalculateHeaderSize(); + tick(100); + + const expectedHeight = window.innerHeight - 100; + expect(expectedHeight).toBeGreaterThan(0); + expect(component.height).toBe(`${expectedHeight}px`); + })); + + it('should fallback to 90% when calculated height is zero or negative with .po-page ancestor', fakeAsync(() => { + const poPage = document.createElement('div'); + poPage.classList.add('po-page'); + poPage.appendChild(fixture.nativeElement); + document.body.appendChild(poPage); + + // Sem po-page-header, contentTop vem do topo do .po-page. Forçamos um top + // maior que a altura da janela para que newHeight <= 0 e caia no fallback, + // cobrindo o ramo '90%' do ternário no caminho com .po-page. + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + spyOn(poPage, 'getBoundingClientRect').and.returnValue({ + top: window.innerHeight + 100, + bottom: window.innerHeight + 200, + left: 0, + right: 0, + width: 0, + height: 0, + x: 0, + y: 0, + toJSON: () => {} + } as DOMRect); + + component.recalculateHeaderSize(); + tick(100); + + expect(component.height).toBe('90%'); + + document.body.removeChild(poPage); + })); }); }); diff --git a/projects/ui/src/lib/components/po-page/po-page-content/po-page-content.component.ts b/projects/ui/src/lib/components/po-page/po-page-content/po-page-content.component.ts index 50a8edf867..666554d64f 100644 --- a/projects/ui/src/lib/components/po-page/po-page-content/po-page-content.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-content/po-page-content.component.ts @@ -1,12 +1,13 @@ import { AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, Component, ElementRef, NgZone, OnDestroy, Renderer2, - inject, - ChangeDetectorRef + inject } from '@angular/core'; import { PoPageContentBaseComponent } from './po-page-content-base.component'; @@ -19,6 +20,7 @@ import { PoPageContentBaseComponent } from './po-page-content-base.component'; @Component({ selector: 'po-page-content', templateUrl: './po-page-content.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageContentComponent extends PoPageContentBaseComponent implements AfterViewInit, OnDestroy { diff --git a/projects/ui/src/lib/components/po-page/po-page-default/po-page-default.component.spec.ts b/projects/ui/src/lib/components/po-page/po-page-default/po-page-default.component.spec.ts index 483e535a42..2300cfbe22 100644 --- a/projects/ui/src/lib/components/po-page/po-page-default/po-page-default.component.spec.ts +++ b/projects/ui/src/lib/components/po-page/po-page-default/po-page-default.component.spec.ts @@ -1,8 +1,8 @@ import { CommonModule } from '@angular/common'; -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { Router } from '@angular/router'; +import { provideLocationMocks } from '@angular/common/testing'; +import { Router, RouterModule } from '@angular/router'; import { changeBrowserInnerWidth } from '../../../util-test/util-expect.spec'; @@ -28,6 +28,7 @@ eventResize.initEvent('resize', false, true); @Component({ template: ` `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class MobileComponent { @@ -61,7 +62,7 @@ describe('PoPageDefaultComponent mobile', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [CommonModule, RouterTestingModule.withRoutes([]), PoBreadcrumbModule, PoButtonModule, PoDropdownModule], + imports: [CommonModule, RouterModule.forRoot([]), PoBreadcrumbModule, PoButtonModule, PoDropdownModule], declarations: [ MobileComponent, PoPageDefaultComponent, @@ -69,7 +70,7 @@ describe('PoPageDefaultComponent mobile', () => { PoPageContentComponent, PoPageHeaderComponent ], - providers: [{ provide: Router, useValue: routerStub }] + providers: [provideLocationMocks(), { provide: Router, useValue: routerStub }] }).compileComponents(); fixture = TestBed.createComponent(PoPageDefaultComponent); @@ -140,6 +141,7 @@ describe('PoPageDefaultComponent mobile', () => { @Component({ template: ` `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class DesktopComponent { @@ -161,7 +163,7 @@ describe('PoPageDefaultComponent desktop', () => { await TestBed.configureTestingModule({ imports: [ CommonModule, - RouterTestingModule.withRoutes([]), + RouterModule.forRoot([]), PoBreadcrumbModule, PoButtonModule, PoDropdownModule, @@ -173,7 +175,8 @@ describe('PoPageDefaultComponent desktop', () => { PoPageComponent, PoPageContentComponent, PoPageHeaderComponent - ] + ], + providers: [provideLocationMocks()] }).compileComponents(); fixture = TestBed.createComponent(PoPageDefaultComponent); @@ -682,9 +685,9 @@ describe('PoPageDefaultComponent i18n fallback', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [CommonModule, RouterTestingModule.withRoutes([]), PoBreadcrumbModule, PoButtonModule, PoDropdownModule], + imports: [CommonModule, RouterModule.forRoot([]), PoBreadcrumbModule, PoButtonModule, PoDropdownModule], declarations: [PoPageDefaultComponent, PoPageComponent, PoPageContentComponent, PoPageHeaderComponent], - providers: [{ provide: PoLanguageService, useValue: { getShortLanguage: () => 'fr' } }] + providers: [provideLocationMocks(), { provide: PoLanguageService, useValue: { getShortLanguage: () => 'fr' } }] }).compileComponents(); fixture = TestBed.createComponent(PoPageDefaultComponent); diff --git a/projects/ui/src/lib/components/po-page/po-page-default/po-page-default.component.ts b/projects/ui/src/lib/components/po-page/po-page-default/po-page-default.component.ts index eccc9fb89e..b5b06433ad 100644 --- a/projects/ui/src/lib/components/po-page/po-page-default/po-page-default.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-default/po-page-default.component.ts @@ -1,4 +1,13 @@ -import { AfterContentInit, Component, inject, OnChanges, OnDestroy, Renderer2, SimpleChange } from '@angular/core'; +import { + AfterContentInit, + Component, + inject, + OnChanges, + OnDestroy, + Renderer2, + SimpleChange, + ChangeDetectionStrategy +} from '@angular/core'; import { Router } from '@angular/router'; import { PoLanguageService } from './../../../services/po-language/po-language.service'; @@ -39,6 +48,7 @@ import { backNavigationAriaLabels, PoPageDefaultBaseComponent } from './po-page- @Component({ selector: 'po-page-default', templateUrl: './po-page-default.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageDefaultComponent diff --git a/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-basic/sample-po-page-default-basic.component.ts b/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-basic/sample-po-page-default-basic.component.ts index 142cbb2f3a..a4cc8edbdb 100644 --- a/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-basic/sample-po-page-default-basic.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-basic/sample-po-page-default-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-default-basic', templateUrl: './sample-po-page-default-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDefaultBasicComponent {} diff --git a/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-dashboard/sample-po-page-default-dashboard.component.ts b/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-dashboard/sample-po-page-default-dashboard.component.ts index aa19fc9036..96535e32c1 100644 --- a/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-dashboard/sample-po-page-default-dashboard.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-dashboard/sample-po-page-default-dashboard.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, OnInit, inject } from '@angular/core'; +import { Component, ViewChild, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { @@ -18,6 +18,7 @@ import { SampleDashboardService } from './sample-po-page-default-dashboard.servi templateUrl: './sample-po-page-default-dashboard.component.html', styleUrls: ['./sample-po-page-default-dashboard.component.css'], providers: [SampleDashboardService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDefaultDashboardComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-labs/sample-po-page-default-labs.component.ts b/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-labs/sample-po-page-default-labs.component.ts index 2c71225fab..32cd641cc7 100644 --- a/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-labs/sample-po-page-default-labs.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-default/samples/sample-po-page-default-labs/sample-po-page-default-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoBreadcrumb, @@ -20,6 +20,7 @@ interface EditableAction extends PoPageAction { @Component({ selector: 'sample-po-page-default-labs', templateUrl: './sample-po-page-default-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDefaultLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-page/po-page-detail/po-page-detail.component.spec.ts b/projects/ui/src/lib/components/po-page/po-page-detail/po-page-detail.component.spec.ts index c35bb78065..a8dd7d51b1 100644 --- a/projects/ui/src/lib/components/po-page/po-page-detail/po-page-detail.component.spec.ts +++ b/projects/ui/src/lib/components/po-page/po-page-detail/po-page-detail.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; @@ -17,6 +17,7 @@ import { PoPageHeaderComponent } from '../po-page-header/po-page-header.componen template: ` `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class ContainerComponent { diff --git a/projects/ui/src/lib/components/po-page/po-page-detail/po-page-detail.component.ts b/projects/ui/src/lib/components/po-page/po-page-detail/po-page-detail.component.ts index 93b52a3186..0b9d43980e 100644 --- a/projects/ui/src/lib/components/po-page/po-page-detail/po-page-detail.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-detail/po-page-detail.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoPageDetailBaseComponent } from './po-page-detail-base.component'; @@ -25,6 +25,7 @@ import { PoPageDetailBaseComponent } from './po-page-detail-base.component'; @Component({ selector: 'po-page-detail', templateUrl: './po-page-detail.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageDetailComponent extends PoPageDetailBaseComponent { diff --git a/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-basic/sample-po-page-detail-basic.component.ts b/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-basic/sample-po-page-detail-basic.component.ts index b4fd857a7d..e650a57435 100644 --- a/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-basic/sample-po-page-detail-basic.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-basic/sample-po-page-detail-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-detail-basic', templateUrl: './sample-po-page-detail-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDetailBasicComponent {} diff --git a/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-labs/sample-po-page-detail-labs.component.ts b/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-labs/sample-po-page-detail-labs.component.ts index 0be8673aea..08aa83b8c7 100644 --- a/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-labs/sample-po-page-detail-labs.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-labs/sample-po-page-detail-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoBreadcrumb, PoBreadcrumbItem, PoPageDetailLiterals, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-page-detail-labs', templateUrl: './sample-po-page-detail-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDetailLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-user/sample-po-page-detail-user.component.ts b/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-user/sample-po-page-detail-user.component.ts index 25151dc0aa..0081f741f8 100644 --- a/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-user/sample-po-page-detail-user.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-detail/samples/sample-po-page-detail-user/sample-po-page-detail-user.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; import { PoBreadcrumb } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoBreadcrumb } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-page-detail-user', templateUrl: './sample-po-page-detail-user.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageDetailUserComponent { diff --git a/projects/ui/src/lib/components/po-page/po-page-edit/po-page-edit.component.spec.ts b/projects/ui/src/lib/components/po-page/po-page-edit/po-page-edit.component.spec.ts index 18aa831eab..702b76b541 100644 --- a/projects/ui/src/lib/components/po-page/po-page-edit/po-page-edit.component.spec.ts +++ b/projects/ui/src/lib/components/po-page/po-page-edit/po-page-edit.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; @@ -17,6 +17,7 @@ import { PoPageHeaderComponent } from '../po-page-header/po-page-header.componen template: ` `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class ContainerComponent { diff --git a/projects/ui/src/lib/components/po-page/po-page-edit/po-page-edit.component.ts b/projects/ui/src/lib/components/po-page/po-page-edit/po-page-edit.component.ts index e3124cf587..4f6547895e 100644 --- a/projects/ui/src/lib/components/po-page/po-page-edit/po-page-edit.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-edit/po-page-edit.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoPageEditBaseComponent } from './po-page-edit-base.component'; @@ -25,6 +25,7 @@ import { PoPageEditBaseComponent } from './po-page-edit-base.component'; @Component({ selector: 'po-page-edit', templateUrl: './po-page-edit.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageEditComponent extends PoPageEditBaseComponent { diff --git a/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-basic/sample-po-page-edit-basic.component.ts b/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-basic/sample-po-page-edit-basic.component.ts index fe3e4c86fe..1e39651beb 100644 --- a/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-basic/sample-po-page-edit-basic.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-basic/sample-po-page-edit-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-edit-basic', templateUrl: './sample-po-page-edit-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageEditBasicComponent {} diff --git a/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-labs/sample-po-page-edit-labs.component.ts b/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-labs/sample-po-page-edit-labs.component.ts index facb11c0da..35dad6746e 100644 --- a/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-labs/sample-po-page-edit-labs.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-labs/sample-po-page-edit-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoBreadcrumb, PoBreadcrumbItem, PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @@ -7,6 +7,7 @@ import { PoPageEditLiterals } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-page-edit-labs', templateUrl: './sample-po-page-edit-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageEditLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-user/sample-po-page-edit-user.component.ts b/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-user/sample-po-page-edit-user.component.ts index e43edee766..d96f7a4287 100644 --- a/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-user/sample-po-page-edit-user.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-edit/samples/sample-po-page-edit-user/sample-po-page-edit-user.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { Router } from '@angular/router'; @@ -9,6 +9,7 @@ import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-page-edit-user', templateUrl: './sample-po-page-edit-user.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageEditUserComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-page/po-page-header/po-page-header.component.spec.ts b/projects/ui/src/lib/components/po-page/po-page-header/po-page-header.component.spec.ts index 143f73b8eb..4b1f72e295 100644 --- a/projects/ui/src/lib/components/po-page/po-page-header/po-page-header.component.spec.ts +++ b/projects/ui/src/lib/components/po-page/po-page-header/po-page-header.component.spec.ts @@ -1,15 +1,17 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { HttpClient, HttpHandler } from '@angular/common/http'; -import { Routes } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import { RouterModule, Routes } from '@angular/router'; +import { provideLocationMocks } from '@angular/common/testing'; import { PoBreadcrumbModule } from '../../po-breadcrumb/po-breadcrumb.module'; import { PoHelperModule } from '../../po-helper/po-helper.module'; import { PoPageHeaderComponent } from './po-page-header.component'; @Component({ + selector: 'app-guides-header-test', template: 'Guides', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class GuidesComponent {} @@ -23,9 +25,9 @@ describe('PoPageHeaderComponent:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [PoBreadcrumbModule, PoHelperModule, RouterTestingModule.withRoutes(routes)], + imports: [PoBreadcrumbModule, PoHelperModule, RouterModule.forRoot(routes)], declarations: [PoPageHeaderComponent, GuidesComponent], - providers: [HttpClient, HttpHandler] + providers: [HttpClient, HttpHandler, provideLocationMocks()] }).compileComponents(); fixture = TestBed.createComponent(PoPageHeaderComponent); diff --git a/projects/ui/src/lib/components/po-page/po-page-header/po-page-header.component.ts b/projects/ui/src/lib/components/po-page/po-page-header/po-page-header.component.ts index 854e108d42..fe21741e14 100644 --- a/projects/ui/src/lib/components/po-page/po-page-header/po-page-header.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-header/po-page-header.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoPageHeaderBaseComponent } from './po-page-header-base.component'; @@ -9,6 +9,7 @@ import { PoPageHeaderBaseComponent } from './po-page-header-base.component'; @Component({ selector: 'po-page-header', templateUrl: './po-page-header.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageHeaderComponent extends PoPageHeaderBaseComponent {} diff --git a/projects/ui/src/lib/components/po-page/po-page-list/po-page-list.component.spec.ts b/projects/ui/src/lib/components/po-page/po-page-list/po-page-list.component.spec.ts index e90fb3a9c7..66fb708ccb 100644 --- a/projects/ui/src/lib/components/po-page/po-page-list/po-page-list.component.spec.ts +++ b/projects/ui/src/lib/components/po-page/po-page-list/po-page-list.component.spec.ts @@ -1,8 +1,8 @@ import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing'; -import { Component } from '@angular/core'; +import { provideLocationMocks } from '@angular/common/testing'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import { Router, RouterModule } from '@angular/router'; import { changeBrowserInnerWidth } from '../../../util-test/util-expect.spec'; @@ -37,6 +37,7 @@ eventSubmit.initEvent('submit', true, false); @Component({ template: ` `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class MobileComponent { @@ -67,7 +68,7 @@ describe('PoPageListComponent - Mobile:', () => { await TestBed.configureTestingModule({ imports: [ FormsModule, - RouterTestingModule.withRoutes([]), + RouterModule.forRoot([]), PoBreadcrumbModule, PoButtonModule, PoDisclaimerGroupModule, @@ -80,7 +81,7 @@ describe('PoPageListComponent - Mobile:', () => { PoPageHeaderComponent, PoPageContentComponent ], - providers: [{ provide: Router, useValue: routerStub }] + providers: [provideLocationMocks(), { provide: Router, useValue: routerStub }] }).compileComponents(); fixture = TestBed.createComponent(PoPageListComponent); @@ -122,6 +123,7 @@ describe('PoPageListComponent - Mobile:', () => { @Component({ template: ` `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class DesktopComponent { @@ -156,7 +158,7 @@ describe('PoPageListComponent - Desktop:', () => { imports: [ FormsModule, ReactiveFormsModule, - RouterTestingModule.withRoutes([]), + RouterModule.forRoot([]), PoBreadcrumbModule, PoButtonModule, PoDisclaimerGroupModule, @@ -169,7 +171,7 @@ describe('PoPageListComponent - Desktop:', () => { PoPageHeaderComponent, PoPageContentComponent ], - providers: [{ provide: Router, useValue: routerStub }] + providers: [provideLocationMocks(), { provide: Router, useValue: routerStub }] }).compileComponents(); fixture = TestBed.createComponent(PoPageListComponent); diff --git a/projects/ui/src/lib/components/po-page/po-page-list/po-page-list.component.ts b/projects/ui/src/lib/components/po-page/po-page-list/po-page-list.component.ts index 20fa5c3cc5..b28c2309c2 100644 --- a/projects/ui/src/lib/components/po-page/po-page-list/po-page-list.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-list/po-page-list.component.ts @@ -10,7 +10,8 @@ import { SimpleChange, ViewChild, ViewContainerRef, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; @@ -47,6 +48,7 @@ import { PoPageListBaseComponent } from './po-page-list-base.component'; @Component({ selector: 'po-page-list', templateUrl: './po-page-list.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageListComponent diff --git a/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-basic/sample-po-page-list-basic.component.ts b/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-basic/sample-po-page-list-basic.component.ts index bdd88f1b99..1d350babea 100644 --- a/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-basic/sample-po-page-list-basic.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-basic/sample-po-page-list-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-list-basic', templateUrl: './sample-po-page-list-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageListBasicComponent {} diff --git a/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-hiring-processes/sample-po-page-list-hiring-processes.component.ts b/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-hiring-processes/sample-po-page-list-hiring-processes.component.ts index e82f319779..092ea49779 100644 --- a/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-hiring-processes/sample-po-page-list-hiring-processes.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-hiring-processes/sample-po-page-list-hiring-processes.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; import { PoBreadcrumb } from '@po-ui/ng-components'; @@ -17,6 +17,7 @@ import { SamplePoPageListHiringProcessesService } from './sample-po-page-list-hi selector: 'sample-po-page-list-hiring-processes', templateUrl: './sample-po-page-list-hiring-processes.component.html', providers: [SamplePoPageListHiringProcessesService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageListHiringProcessesComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-labs/sample-po-page-list-labs.component.ts b/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-labs/sample-po-page-list-labs.component.ts index 26771dc5f9..69eb62ac0d 100644 --- a/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-labs/sample-po-page-list-labs.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-list/samples/sample-po-page-list-labs/sample-po-page-list-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoBreadcrumb, @@ -13,6 +13,7 @@ import { PoNotificationService, PoPageAction, PoPageFilter, PoPageListLiterals } @Component({ selector: 'sample-po-page-list-labs', templateUrl: './sample-po-page-list-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageListLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide-base.component.ts b/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide-base.component.ts index 8b0dd6117d..94651bf9a0 100644 --- a/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide-base.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide-base.component.ts @@ -15,45 +15,6 @@ import { PoPageSlideSize } from './po-page-slide-size.type'; * através do botão que encontra-se no cabeçalho do mesmo ou através do método * `#close()`. * - * > Para o correto funcionamento do componente `po-page-slide`, deve ser - * > importado o módulo `BrowserAnimationsModule` no módulo principal da sua - * > aplicação. - * - * Módulo da aplicação: - * ``` - * import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - * import { PoModule } from '@po-ui/ng-components'; - * ... - * - * @NgModule({ - * imports: [ - * BrowserModule, - * BrowserAnimationsModule, - * ... - * PoModule - * ], - * declarations: [ - * AppComponent, - * ... - * ], - * providers: [], - * bootstrap: [AppComponent] - * }) - * export class AppModule { } - * ``` - * - * Em aplicações Standalone, utilize a seguinte configuração para o bootstrap: - * - * ``` - * import { bootstrapApplication } from '@angular/platform-browser'; - * import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - * import { AppComponent } from './app.component'; - * - * bootstrapApplication(AppComponent, { - * providers: [importProvidersFrom(BrowserAnimationsModule)] - * }).catch(err => console.error(err)); - * ``` - * * Caso utilize componentes de field dentro do page-slide, recomenda-se o uso do [Grid System](https://po-ui.io/guides/grid-system). * * No rodapé é possível utilizar o componente [`PoPageSlideFooter`](/documentation/po-page-slide-footer) para customização do template. diff --git a/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide-footer/po-page-slide-footer.component.ts b/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide-footer/po-page-slide-footer.component.ts index f8b1f7a9ff..f5498d0e77 100644 --- a/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide-footer/po-page-slide-footer.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide-footer/po-page-slide-footer.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; /** * @description @@ -19,6 +19,7 @@ import { Component, Input } from '@angular/core'; @Component({ selector: 'po-page-slide-footer', templateUrl: './po-page-slide-footer.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageSlideFooterComponent { diff --git a/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.html b/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.html index 9a6b9472af..de1f620dfc 100644 --- a/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.html +++ b/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.html @@ -1,5 +1,11 @@ @if (!hidden) { -
    +
    @if (size !== 'full') {
    } @@ -9,7 +15,6 @@ aria-modal="true" [attr.aria-labelledby]="title ? titleId : null" [attr.aria-label]="title ? null : defaultDialogLabel" - [@slide]="slideParams" [ngStyle]="{ 'width': flexibleWidth ? '' : size === 'auto' ? 'auto' : '' }" >
    diff --git a/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.spec.ts b/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.spec.ts index 4f08fdd08d..cf841e5117 100644 --- a/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.spec.ts +++ b/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.spec.ts @@ -1,8 +1,7 @@ -import { Component, DebugElement, ElementRef, ViewChild } from '@angular/core'; +import { Component, DebugElement, ElementRef, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, fakeAsync, flush, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { PoActiveOverlayService } from '../../../services/po-active-overlay'; import { PoFieldModule } from '../../po-field'; @@ -18,6 +17,7 @@ import { PoPageSlideComponent } from './po-page-slide.component'; `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class TestComponent { @@ -40,7 +40,7 @@ describe('PoPageSlideComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [FormsModule, NoopAnimationsModule, PoFieldModule], + imports: [FormsModule, PoFieldModule], declarations: [PoPageSlideComponent, TestComponent], providers: [PoActiveOverlayService] }).compileComponents(); @@ -371,17 +371,145 @@ describe('PoPageSlideComponent', () => { }); }); - describe('animation params:', () => { - it('fadeParams: should use the fallback duration when `duration` is empty', () => { - component.duration = ''; + describe('Animation methods:', () => { + it('animateEnter: should animate overlay opacity and container translateX', () => { + const rootElement = document.createElement('div'); + const container = document.createElement('div'); + container.classList.add('po-page-slide-container'); + rootElement.appendChild(container); + + const animationComplete = jasmine.createSpy('animationComplete'); + const rootAnimateSpy = spyOn(rootElement, 'animate').and.returnValue({} as any); + const cancelSpy = jasmine.createSpy('cancel'); + const containerAnimation: any = { cancel: cancelSpy }; + const containerAnimateSpy = spyOn(container, 'animate').and.returnValue(containerAnimation); + + component.animateEnter({ target: rootElement, animationComplete }); + + expect(rootAnimateSpy).toHaveBeenCalledWith( + [{ opacity: 0 }, { opacity: 1 }], + jasmine.objectContaining({ easing: 'linear', fill: 'forwards' }) + ); + expect(containerAnimateSpy).toHaveBeenCalledWith( + [{ transform: 'translateX(50px)' }, { transform: 'none' }], + jasmine.objectContaining({ fill: 'forwards' }) + ); + + containerAnimation.onfinish(); + + expect(container.style.transform).toBe('none'); + expect(cancelSpy).toHaveBeenCalled(); + expect(animationComplete).toHaveBeenCalled(); + }); + + it('animateLeave: should animate overlay opacity to 0 and container translateX out', () => { + const rootElement = document.createElement('div'); + const container = document.createElement('div'); + container.classList.add('po-page-slide-container'); + rootElement.appendChild(container); + + const animationComplete = jasmine.createSpy('animationComplete'); + spyOn(rootElement, 'animate').and.returnValue({} as any); + const containerAnimation: any = {}; + spyOn(container, 'animate').and.returnValue(containerAnimation); + + component.animateLeave({ target: rootElement, animationComplete }); + + containerAnimation.onfinish(); + expect(animationComplete).toHaveBeenCalled(); + }); + + it('animateEnter: should call animationComplete immediately if container not found', () => { + const rootElement = document.createElement('div'); + const animationComplete = jasmine.createSpy('animationComplete'); + spyOn(rootElement, 'animate').and.returnValue({} as any); + + component.animateEnter({ target: rootElement, animationComplete }); - expect(component.fadeParams.params.duration).toBe('70ms'); + expect(animationComplete).toHaveBeenCalled(); }); - it('slideParams: should use the fallback timing when `timing` is empty', () => { - component.timing = ''; + it('animateEnter: should use fallback duration 70 when parseDuration returns 0', () => { + const rootElement = document.createElement('div'); + const container = document.createElement('div'); + container.classList.add('po-page-slide-container'); + rootElement.appendChild(container); + + const animationComplete = jasmine.createSpy('animationComplete'); + const containerAnimation: any = {}; + const rootAnimateSpy = spyOn(rootElement, 'animate').and.returnValue({} as any); + spyOn(container, 'animate').and.returnValue(containerAnimation); + + // parseDuration retorna 0 para string '0ms', ativando o fallback || 70 + component.duration = '0ms'; + component.animateEnter({ target: rootElement, animationComplete }); + + expect(rootAnimateSpy).toHaveBeenCalledWith([{ opacity: 0 }, { opacity: 1 }], { + duration: 70, + easing: 'linear', + fill: 'forwards' + }); + }); + + it('parseDuration: should parse ms value', () => { + expect(component['parseDuration']('200ms')).toBe(200); + }); + + it('parseDuration: should parse s value', () => { + expect(component['parseDuration']('1.5s')).toBe(1500); + }); + + it('parseDuration: should return default for invalid value', () => { + expect(component['parseDuration']('')).toBe(70); + expect(component['parseDuration']('invalid')).toBe(70); + }); - expect(component.slideParams.params.timing).toBe('700ms cubic-bezier(0.35, 0, 0.1, 1)'); + it('parseTiming: should parse duration and easing', () => { + const result = component['parseTiming']('700ms cubic-bezier(0.35, 0, 0.1, 1)'); + expect(result.duration).toBe(700); + expect(result.easing).toBe('cubic-bezier(0.35, 0, 0.1, 1)'); }); + + it('parseTiming: should return default for empty value', () => { + const result = component['parseTiming'](''); + expect(result.duration).toBe(700); + expect(result.easing).toBe('cubic-bezier(0.35, 0, 0.1, 1)'); + }); + + it('parseTiming: should parse seconds value', () => { + const result = component['parseTiming']('1.5s ease-out'); + expect(result.duration).toBe(1500); + expect(result.easing).toBe('ease-out'); + }); + + it('parseTiming: should return default for invalid value', () => { + const result = component['parseTiming']('invalid'); + expect(result.duration).toBe(700); + expect(result.easing).toBe('cubic-bezier(0.35, 0, 0.1, 1)'); + }); + + it('parseDuration: should return default for null value', () => { + expect(component['parseDuration'](null)).toBe(70); + }); + + it('parseTiming: should return default for null value', () => { + const result = component['parseTiming'](null); + expect(result.duration).toBe(700); + expect(result.easing).toBe('cubic-bezier(0.35, 0, 0.1, 1)'); + }); + + it('animateLeave: should use setTimeout when container is not found', fakeAsync(() => { + const rootElement = document.createElement('div'); + const animationComplete = jasmine.createSpy('animationComplete'); + spyOn(rootElement, 'animate').and.returnValue({} as any); + + component.animateLeave({ target: rootElement, animationComplete }); + + expect(animationComplete).not.toHaveBeenCalled(); + + tick(150); + + expect(animationComplete).toHaveBeenCalled(); + })); }); }); diff --git a/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.ts b/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.ts index db3fd51092..c0394280bd 100644 --- a/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-slide/po-page-slide.component.ts @@ -1,5 +1,12 @@ -import { animate, animateChild, group, query, style, transition, trigger } from '@angular/animations'; -import { Component, ContentChild, ElementRef, ViewChild, inject } from '@angular/core'; +import { + AnimationCallbackEvent, + Component, + ContentChild, + ElementRef, + ViewChild, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { ReplaySubject } from 'rxjs'; import { delay, take } from 'rxjs/operators'; @@ -54,22 +61,7 @@ export const poPageSlideLiteralsDefault = { selector: 'po-page-slide', templateUrl: './po-page-slide.component.html', providers: [], - animations: [ - trigger('fade', [ - transition(':enter', [ - style({ opacity: 0 }), - group([animate(`{{duration}}`, style({ opacity: 1 })), query('@slide', animateChild())]) - ]), - transition(':leave', group([query('@slide', animateChild()), animate('150ms', style({ opacity: 0 }))])) - ]), - trigger('slide', [ - transition(':enter', [ - style({ transform: 'translateX(50px)' }), - animate(`{{timing }}`, style({ transform: 'none' })) - ]), - transition(':leave', [animate('150ms', style({ transform: 'translateX(50px)' }))]) - ]) - ], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageSlideComponent extends PoPageSlideBaseComponent { @@ -148,6 +140,88 @@ export class PoPageSlideComponent extends PoPageSlideBaseComponent { } } + animateEnter(event: AnimationCallbackEvent): void { + const rootElement = event.target as HTMLElement; + const container = rootElement.querySelector('.po-page-slide-container'); + + const fadeDuration = this.parseDuration(this.duration) || 70; + const { duration: slideDuration, easing: slideEasing } = this.parseTiming(this.timing); + + // Animate overlay fade in + rootElement.animate([{ opacity: 0 }, { opacity: 1 }], { + duration: fadeDuration, + easing: 'linear', + fill: 'forwards' + }); + + // Animate container slide in (in parallel) + if (container) { + const slideAnimation = container.animate([{ transform: 'translateX(50px)' }, { transform: 'none' }], { + duration: slideDuration, + easing: slideEasing, + fill: 'forwards' + }); + + slideAnimation.onfinish = () => { + (container as HTMLElement).style.transform = 'none'; + slideAnimation.cancel?.(); + event.animationComplete(); + }; + } else { + event.animationComplete(); + } + } + + animateLeave(event: AnimationCallbackEvent): void { + const rootElement = event.target as HTMLElement; + const container = rootElement.querySelector('.po-page-slide-container'); + + const leaveDuration = 150; + + // Animate overlay fade out and slide out in parallel + rootElement.animate([{ opacity: 1 }, { opacity: 0 }], { + duration: leaveDuration, + easing: 'linear', + fill: 'forwards' + }); + + if (container) { + const slideAnimation = container.animate([{ transform: 'none' }, { transform: 'translateX(50px)' }], { + duration: leaveDuration, + easing: 'linear', + fill: 'forwards' + }); + + slideAnimation.onfinish = () => event.animationComplete(); + } else { + setTimeout(() => event.animationComplete(), leaveDuration); + } + } + + private parseDuration(value: string): number { + if (!value) { + return 70; + } + const match = /^(\d+(?:\.\d+)?)(ms|s)$/.exec(value); + if (!match) { + return 70; + } + return match[2] === 's' ? Number.parseFloat(match[1]) * 1000 : Number.parseFloat(match[1]); + } + + private parseTiming(value: string): { duration: number; easing: string } { + if (!value) { + return { duration: 700, easing: 'cubic-bezier(0.35, 0, 0.1, 1)' }; + } + const durationMatch = /^(\d+(?:\.\d+)?)(ms|s)\s+(.+)$/.exec(value); + if (!durationMatch) { + return { duration: 700, easing: 'cubic-bezier(0.35, 0, 0.1, 1)' }; + } + const duration = + durationMatch[2] === 's' ? Number.parseFloat(durationMatch[1]) * 1000 : Number.parseFloat(durationMatch[1]); + return { duration, easing: durationMatch[3] }; + } + private setTimeFromCSS(): void { const rootStyles = getComputedStyle(document.documentElement); this.duration = rootStyles.getPropertyValue('--transition-duration').trim(); @@ -205,18 +279,4 @@ export class PoPageSlideComponent extends PoPageSlideBaseComponent { document.removeEventListener('focus', this.focusEvent, true); this.loadingCompleted.complete(); } - - get fadeParams() { - return { - value: true, - params: { duration: this.duration || '70ms' } - }; - } - - get slideParams() { - return { - value: true, - params: { timing: this.timing || '700ms cubic-bezier(0.35, 0, 0.1, 1)' } - }; - } } diff --git a/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-basic/sample-po-page-slide-basic.component.ts b/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-basic/sample-po-page-slide-basic.component.ts index e13a488d44..0f8cc84273 100644 --- a/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-basic/sample-po-page-slide-basic.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-basic/sample-po-page-slide-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-page-slide-basic', templateUrl: './sample-po-page-slide-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageSlideBasicComponent {} diff --git a/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-configuration/sample-po-page-slide-configuration.component.ts b/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-configuration/sample-po-page-slide-configuration.component.ts index d831a5744c..f64cfb2a27 100644 --- a/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-configuration/sample-po-page-slide-configuration.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-configuration/sample-po-page-slide-configuration.component.ts @@ -1,9 +1,10 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'sample-po-page-slide-configuration', templateUrl: './sample-po-page-slide-configuration.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageSlideConfigurationComponent { diff --git a/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-labs/sample-po-page-slide-labs.component.ts b/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-labs/sample-po-page-slide-labs.component.ts index b9aa44959a..b5da8af4ff 100644 --- a/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-labs/sample-po-page-slide-labs.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page-slide/samples/sample-po-page-slide-labs/sample-po-page-slide-labs.component.ts @@ -1,9 +1,10 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoPageSlideComponent, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-page-slide-labs', templateUrl: './sample-po-page-slide-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPageSlideLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-page/po-page.component.ts b/projects/ui/src/lib/components/po-page/po-page.component.ts index bbb00e0544..f0ba3343aa 100644 --- a/projects/ui/src/lib/components/po-page/po-page.component.ts +++ b/projects/ui/src/lib/components/po-page/po-page.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoPageBaseComponent } from './po-page-base.component'; @@ -10,6 +10,7 @@ import { PoPageBaseComponent } from './po-page-base.component'; @Component({ selector: 'po-page', templateUrl: './po-page.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPageComponent extends PoPageBaseComponent {} diff --git a/projects/ui/src/lib/components/po-popover/po-popover-base.component.ts b/projects/ui/src/lib/components/po-popover/po-popover-base.component.ts index 7c7fd83dc4..b6293cd87e 100644 --- a/projects/ui/src/lib/components/po-popover/po-popover-base.component.ts +++ b/projects/ui/src/lib/components/po-popover/po-popover-base.component.ts @@ -1,4 +1,4 @@ -import { ElementRef, EventEmitter, Input, Output, input, Component } from '@angular/core'; +import { ElementRef, EventEmitter, Input, Output, input, Component, ChangeDetectionStrategy } from '@angular/core'; import { convertToBoolean } from '../../utils/util'; import { PO_CONTROL_POSITIONS } from './../../services/po-control-position/po-control-position.constants'; @@ -29,6 +29,7 @@ const PO_POPOVER_TRIGGERS = ['click', 'hover', 'function']; @Component({ selector: 'po-popover-base', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPopoverBaseComponent { diff --git a/projects/ui/src/lib/components/po-popover/po-popover.component.spec.ts b/projects/ui/src/lib/components/po-popover/po-popover.component.spec.ts index 31e76d5c56..613ac3929c 100644 --- a/projects/ui/src/lib/components/po-popover/po-popover.component.spec.ts +++ b/projects/ui/src/lib/components/po-popover/po-popover.component.spec.ts @@ -190,11 +190,23 @@ describe('PoPopoverComponent:', () => { spyOn(fakeEvent, 'togglePopup').and.callFake(() => {}); + // Captura o callback registrado para 'click' no document ao invés de disparar + // um evento global em `document`, que acionaria listeners vazados de outras + // instâncias/testes e tornaria o teste intermitente. + let clickCallback: (event: MouseEvent) => void; + spyOn(fakeEvent.renderer, 'listen').and.callFake((target: any, eventName: string, callback: any) => { + if (target === 'document' && eventName === 'click') { + clickCallback = callback; + } + return () => {}; + }); + component.setRendererListenInit.call(fakeEvent); eventClick.initEvent('click', false, true); - document.dispatchEvent(eventClick); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + clickCallback(eventClick as unknown as MouseEvent); expect(fakeEvent.togglePopup).toHaveBeenCalled(); }); diff --git a/projects/ui/src/lib/components/po-popover/po-popover.component.ts b/projects/ui/src/lib/components/po-popover/po-popover.component.ts index 0dde980783..dafe4324a1 100644 --- a/projects/ui/src/lib/components/po-popover/po-popover.component.ts +++ b/projects/ui/src/lib/components/po-popover/po-popover.component.ts @@ -8,7 +8,8 @@ import { OnDestroy, Renderer2, SimpleChanges, - ViewChild + ViewChild, + ChangeDetectionStrategy } from '@angular/core'; import { PoControlPositionService } from './../../services/po-control-position/po-control-position.service'; @@ -39,6 +40,7 @@ import { PoPopoverBaseComponent } from './po-popover-base.component'; selector: 'po-popover', templateUrl: './po-popover.component.html', providers: [PoControlPositionService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPopoverComponent extends PoPopoverBaseComponent implements AfterViewInit, OnDestroy, OnChanges { diff --git a/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-basic/sample-po-popover-basic.component.ts b/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-basic/sample-po-popover-basic.component.ts index ea89ab729a..79074a5f67 100644 --- a/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-basic/sample-po-popover-basic.component.ts +++ b/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-basic/sample-po-popover-basic.component.ts @@ -1,10 +1,11 @@ -import { Component, ElementRef, ViewChild } from '@angular/core'; +import { Component, ElementRef, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoButtonComponent } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-popover-basic', templateUrl: './sample-po-popover-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPopoverBasicComponent { diff --git a/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-credit-card/sample-po-popover-credit-card.component.ts b/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-credit-card/sample-po-popover-credit-card.component.ts index 752a466a93..d1efe6cbc3 100644 --- a/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-credit-card/sample-po-popover-credit-card.component.ts +++ b/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-credit-card/sample-po-popover-credit-card.component.ts @@ -1,8 +1,9 @@ -import { Component, ElementRef, ViewChild } from '@angular/core'; +import { Component, ElementRef, ViewChild, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-popover-credit-card', templateUrl: './sample-po-popover-credit-card.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPopoverCreditCardComponent { diff --git a/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-labs/sample-po-popover-labs.component.ts b/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-labs/sample-po-popover-labs.component.ts index 7733808505..008872b49e 100644 --- a/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-labs/sample-po-popover-labs.component.ts +++ b/projects/ui/src/lib/components/po-popover/samples/sample-po-popover-labs/sample-po-popover-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, ElementRef, ViewChild } from '@angular/core'; +import { Component, ElementRef, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-popover-labs', templateUrl: './sample-po-popover-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPopoverLabsComponent { diff --git a/projects/ui/src/lib/components/po-popup/po-popup.component.spec.ts b/projects/ui/src/lib/components/po-popup/po-popup.component.spec.ts index 73cb45a4d9..e67fd1435c 100644 --- a/projects/ui/src/lib/components/po-popup/po-popup.component.spec.ts +++ b/projects/ui/src/lib/components/po-popup/po-popup.component.spec.ts @@ -1,5 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { of } from 'rxjs'; import { configureTestSuite, expectPropertiesValues } from './../../util-test/util-expect.spec'; @@ -23,9 +24,9 @@ describe('PoPopupComponent:', () => { configureTestSuite(() => { TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([])], + imports: [RouterModule.forRoot([])], declarations: [PoPopupComponent], - providers: [PoControlPositionService] + providers: [provideLocationMocks(), PoControlPositionService] }); }); @@ -847,12 +848,14 @@ describe('PoPopupComponent:', () => { it('clampHeightToViewport: should remove dynamic maxHeight from the listbox scroller when content fits', () => { const popupEl = document.createElement('div'); Object.defineProperty(popupEl, 'offsetHeight', { value: 1, configurable: true }); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(popupEl, 'getBoundingClientRect').and.returnValue({ top: 0, bottom: 1 } as DOMRect); const scrollEl = document.createElement('ul'); component.popupRef = { nativeElement: popupEl } as any; const targetEl = document.createElement('button'); // target no topo: spaceBelow ~= innerHeight (cabe qualquer altura mínima); não abre para cima + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(targetEl, 'getBoundingClientRect').and.returnValue({ top: 0, bottom: 0 } as DOMRect); component.target = targetEl; @@ -874,6 +877,7 @@ describe('PoPopupComponent:', () => { component.popupRef = { nativeElement: popupEl } as any; const targetEl = document.createElement('button'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(targetEl, 'getBoundingClientRect').and.returnValue({ top: 266 } as DOMRect); component.target = targetEl; @@ -897,6 +901,7 @@ describe('PoPopupComponent:', () => { component.popupRef = { nativeElement: popupEl } as any; const targetEl = document.createElement('button'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(targetEl, 'getBoundingClientRect').and.returnValue({ top: 266 } as DOMRect); component.target = targetEl; @@ -919,6 +924,7 @@ describe('PoPopupComponent:', () => { component.popupRef = { nativeElement: popupEl } as any; const targetEl = document.createElement('button'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(targetEl, 'getBoundingClientRect').and.returnValue({ top: 400 } as DOMRect); component.target = targetEl; @@ -934,12 +940,14 @@ describe('PoPopupComponent:', () => { it(`clampHeightToViewport: should anchor the popup by its bottom edge when opening up`, () => { const popupEl = document.createElement('div'); Object.defineProperty(popupEl, 'offsetHeight', { value: 300, configurable: true }); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(popupEl, 'getBoundingClientRect').and.returnValue({ top: 110, bottom: 410 } as DOMRect); const scrollEl = document.createElement('ul'); Object.defineProperty(scrollEl, 'offsetHeight', { value: 300, configurable: true }); component.popupRef = { nativeElement: popupEl } as any; const targetEl = document.createElement('button'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(targetEl, 'getBoundingClientRect').and.returnValue({ top: 518, bottom: 562 } as DOMRect); component.target = targetEl; @@ -968,6 +976,7 @@ describe('PoPopupComponent:', () => { const targetTop = window.innerHeight - 40; const targetBottom = window.innerHeight - 4; const targetEl = document.createElement('button'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(targetEl, 'getBoundingClientRect').and.returnValue({ top: targetTop, bottom: targetBottom } as DOMRect); component.target = targetEl; @@ -991,6 +1000,7 @@ describe('PoPopupComponent:', () => { const targetEl = document.createElement('button'); // target no topo: cabe abaixo (spaceBelow ~= innerHeight) => não abre para cima + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(targetEl, 'getBoundingClientRect').and.returnValue({ top: 0, bottom: 0 } as DOMRect); component.target = targetEl; @@ -1042,6 +1052,7 @@ describe('PoPopupComponent:', () => { component.popupRef = { nativeElement: popupEl } as any; const targetEl = document.createElement('button'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(targetEl, 'getBoundingClientRect').and.returnValue({ top: 10 } as DOMRect); component.target = targetEl; diff --git a/projects/ui/src/lib/components/po-popup/po-popup.component.ts b/projects/ui/src/lib/components/po-popup/po-popup.component.ts index 55d4cc0d0f..3b15411d2d 100644 --- a/projects/ui/src/lib/components/po-popup/po-popup.component.ts +++ b/projects/ui/src/lib/components/po-popup/po-popup.component.ts @@ -1,4 +1,13 @@ -import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, Renderer2, ViewChild, inject } from '@angular/core'; +import { + AfterViewInit, + ChangeDetectorRef, + Component, + ElementRef, + Renderer2, + ViewChild, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { Router } from '@angular/router'; import { PoControlPositionService } from '../../services/po-control-position/po-control-position.service'; @@ -58,6 +67,7 @@ const PO_POPUP_ARROW_TO_POSITION: Record = { selector: 'po-popup', templateUrl: './po-popup.component.html', providers: [PoControlPositionService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoPopupComponent extends PoPopupBaseComponent implements AfterViewInit { diff --git a/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-basic/sample-po-popup-basic.component.ts b/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-basic/sample-po-popup-basic.component.ts index d2740a342c..8058dff9ed 100644 --- a/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-basic/sample-po-popup-basic.component.ts +++ b/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-basic/sample-po-popup-basic.component.ts @@ -1,8 +1,17 @@ -import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, ViewChild, inject } from '@angular/core'; +import { + AfterViewInit, + ChangeDetectorRef, + Component, + ElementRef, + ViewChild, + inject, + ChangeDetectionStrategy +} from '@angular/core'; @Component({ selector: 'sample-po-popup-basic', templateUrl: './sample-po-popup-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPopupBasicComponent implements AfterViewInit { diff --git a/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-email/sample-po-popup-email.component.ts b/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-email/sample-po-popup-email.component.ts index 30cc64b2bb..48765d9b60 100644 --- a/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-email/sample-po-popup-email.component.ts +++ b/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-email/sample-po-popup-email.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { Component, ElementRef, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { PoModalAction, PoModalComponent, PoPopupAction } from '@po-ui/ng-components'; @@ -7,6 +7,7 @@ import { PoModalAction, PoModalComponent, PoPopupAction } from '@po-ui/ng-compon selector: 'sample-po-popup-email', templateUrl: './sample-po-popup-email.component.html', styleUrls: ['./sample-po-popup-email.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPopupEmailComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-labs/sample-po-popup-labs.component.ts b/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-labs/sample-po-popup-labs.component.ts index 4c7c2cf7ca..8045a10e22 100644 --- a/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-labs/sample-po-popup-labs.component.ts +++ b/projects/ui/src/lib/components/po-popup/samples/sample-po-popup-labs/sample-po-popup-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, ElementRef, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, @@ -12,6 +12,7 @@ import { selector: 'sample-po-popup-labs', templateUrl: './sample-po-popup-labs.component.html', styleUrls: ['./sample-po-popup-labs.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoPopupLabsComponent implements OnInit { @@ -124,7 +125,7 @@ export class SamplePoPopupLabsComponent implements OnInit { label: undefined, visible: null, parent: undefined - } as any; + }; } private getActionNode(items: Array, value: string): PoPopupAction | undefined { diff --git a/projects/ui/src/lib/components/po-progress/po-progress-base.component.spec.ts b/projects/ui/src/lib/components/po-progress/po-progress-base.component.spec.ts index 63a8b6ee07..89e40aa9fe 100644 --- a/projects/ui/src/lib/components/po-progress/po-progress-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-progress/po-progress-base.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { PoThemeA11yEnum } from '../../services'; @@ -9,6 +9,7 @@ import { PoProgressBaseComponent } from './po-progress-base.component'; @Component({ template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class TestHostComponent extends PoProgressBaseComponent {} diff --git a/projects/ui/src/lib/components/po-progress/po-progress.component.spec.ts b/projects/ui/src/lib/components/po-progress/po-progress.component.spec.ts index 7f291abbcb..1410752105 100644 --- a/projects/ui/src/lib/components/po-progress/po-progress.component.spec.ts +++ b/projects/ui/src/lib/components/po-progress/po-progress.component.spec.ts @@ -696,6 +696,7 @@ describe('PoProgressComponent:', () => { describe('measureAndSetParentSize:', () => { it('should set parentSize based on element dimensions', () => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(window, 'getComputedStyle').and.returnValue({ height: '150px', width: '200px', @@ -718,6 +719,7 @@ describe('PoProgressComponent:', () => { }); it('should subtract padding from dimensions', () => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(window, 'getComputedStyle').and.returnValue({ height: '200px', width: '200px', diff --git a/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-basic/sample-po-progress-basic.component.ts b/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-basic/sample-po-progress-basic.component.ts index 9f39583243..51671af04e 100644 --- a/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-basic/sample-po-progress-basic.component.ts +++ b/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-basic/sample-po-progress-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-progress-basic', templateUrl: './sample-po-progress-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoProgressBasicComponent {} diff --git a/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-circle/sample-po-progress-circle.component.ts b/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-circle/sample-po-progress-circle.component.ts index a1ee29526e..82fa0dc1a1 100644 --- a/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-circle/sample-po-progress-circle.component.ts +++ b/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-circle/sample-po-progress-circle.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-progress-circle', templateUrl: './sample-po-progress-circle.component.html', styleUrls: ['./sample-po-progress-circle.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoProgressCircleComponent { diff --git a/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-labs/sample-po-progress-labs.component.ts b/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-labs/sample-po-progress-labs.component.ts index f0e72fad79..640c4e6aea 100644 --- a/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-labs/sample-po-progress-labs.component.ts +++ b/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-labs/sample-po-progress-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; import { @@ -15,6 +15,7 @@ import { selector: 'sample-po-progress-labs', templateUrl: './sample-po-progress-labs.component.html', styleUrls: ['./sample-po-progress-labs.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoProgressLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-publication/sample-po-progress-publication.component.ts b/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-publication/sample-po-progress-publication.component.ts index f5878258cd..c8a3722a9d 100644 --- a/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-publication/sample-po-progress-publication.component.ts +++ b/projects/ui/src/lib/components/po-progress/samples/sample-po-progress-publication/sample-po-progress-publication.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-progress-publication', templateUrl: './sample-po-progress-publication.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoProgressPublicationComponent { diff --git a/projects/ui/src/lib/components/po-search/po-search.component.spec.ts b/projects/ui/src/lib/components/po-search/po-search.component.spec.ts index 2aca17e8ba..cb5a23d34d 100644 --- a/projects/ui/src/lib/components/po-search/po-search.component.spec.ts +++ b/projects/ui/src/lib/components/po-search/po-search.component.spec.ts @@ -600,14 +600,27 @@ describe('PoSearchComponent', () => { component['eventResizeListener'] = undefined; const spyRemoveListeners = spyOn(component, 'removeListeners'); + // Captura os callbacks registrados e os invoca diretamente, em vez de disparar + // eventos globais (document/window) que acionariam handlers vazados de outras + // instâncias e tornavam o teste intermitente (erro 'contains' de undefined). + const listeners: { [key: string]: (event?: any) => void } = {}; + spyOn(component['renderer'], 'listen').and.callFake((target: any, eventName: string, callback: any) => { + listeners[`${target}:${eventName}`] = callback; + return () => {}; + }); + spyOn(component, 'clickedOutsideInput'); + spyOn(component, 'adjustContainerPosition'); + component['initializeListeners'](); - document.dispatchEvent(eventClick); - window.dispatchEvent(new Event('resize')); + // Exercita os callbacks de forma determinística. + listeners['document:click']?.(eventClick); + listeners['window:resize']?.(); expect(spyRemoveListeners).toHaveBeenCalled(); expect(component['clickoutListener']).toBeDefined(); expect(component['eventResizeListener']).toBeDefined(); + expect(component.clickedOutsideInput).toHaveBeenCalled(); }); it('should hide the listbox when was click out of the input', () => { @@ -1131,8 +1144,10 @@ describe('PoSearchComponent', () => { describe('locateCounter ViewChild setter', () => { let observeSpy: jasmine.Spy; + let originalResizeObserver: typeof ResizeObserver; beforeEach(() => { + originalResizeObserver = window.ResizeObserver; observeSpy = jasmine.createSpy('observe'); (window as any).ResizeObserver = function (callback) { callback(); @@ -1140,6 +1155,10 @@ describe('PoSearchComponent', () => { }; }); + afterEach(() => { + (window as any).ResizeObserver = originalResizeObserver; + }); + it('should set _locateCounter, create ResizeObserver and observe the element', () => { const element = document.createElement('span'); const elementRef = new ElementRef(element); diff --git a/projects/ui/src/lib/components/po-search/po-search.module.ts b/projects/ui/src/lib/components/po-search/po-search.module.ts index 03281a7e4b..5c57ee3183 100644 --- a/projects/ui/src/lib/components/po-search/po-search.module.ts +++ b/projects/ui/src/lib/components/po-search/po-search.module.ts @@ -1,6 +1,6 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { PoCleanModule } from '../po-field'; +import { PoCleanModule } from '../po-field/po-clean/po-clean.module'; import { PoIconModule } from '../po-icon'; import { PoLoadingModule } from '../po-loading'; import { PoSearchComponent } from './po-search.component'; diff --git a/projects/ui/src/lib/components/po-search/samples/sample-po-search-basic/sample-po-search-basic.component.ts b/projects/ui/src/lib/components/po-search/samples/sample-po-search-basic/sample-po-search-basic.component.ts index 2b3fcb0b41..e05ad86788 100644 --- a/projects/ui/src/lib/components/po-search/samples/sample-po-search-basic/sample-po-search-basic.component.ts +++ b/projects/ui/src/lib/components/po-search/samples/sample-po-search-basic/sample-po-search-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-search-basic', templateUrl: './sample-po-search-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSearchBasicComponent {} diff --git a/projects/ui/src/lib/components/po-search/samples/sample-po-search-execute/sample-po-search-execute.component.ts b/projects/ui/src/lib/components/po-search/samples/sample-po-search-execute/sample-po-search-execute.component.ts index 8bf435a57d..93c3adc5be 100644 --- a/projects/ui/src/lib/components/po-search/samples/sample-po-search-execute/sample-po-search-execute.component.ts +++ b/projects/ui/src/lib/components/po-search/samples/sample-po-search-execute/sample-po-search-execute.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoModalComponent, PoSearchFilterMode } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoModalComponent, PoSearchFilterMode } from '@po-ui/ng-components'; selector: 'sample-po-search-execute', templateUrl: './sample-po-search-execute.component.html', styleUrls: ['./sample-po-search-execute.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSearchExecuteComponent { diff --git a/projects/ui/src/lib/components/po-search/samples/sample-po-search-fields-locate/sample-po-search-fields-locate.component.ts b/projects/ui/src/lib/components/po-search/samples/sample-po-search-fields-locate/sample-po-search-fields-locate.component.ts index e954ac2337..b2c06dee0f 100644 --- a/projects/ui/src/lib/components/po-search/samples/sample-po-search-fields-locate/sample-po-search-fields-locate.component.ts +++ b/projects/ui/src/lib/components/po-search/samples/sample-po-search-fields-locate/sample-po-search-fields-locate.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ViewChild, inject } from '@angular/core'; +import { AfterViewInit, Component, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { PoEmailComponent, @@ -14,6 +14,7 @@ import { @Component({ selector: 'sample-po-search-fields-locate', templateUrl: './sample-po-search-fields-locate.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSearchFieldsLocateComponent implements AfterViewInit { diff --git a/projects/ui/src/lib/components/po-search/samples/sample-po-search-filter-select/sample-po-search-filter-select.component.ts b/projects/ui/src/lib/components/po-search/samples/sample-po-search-filter-select/sample-po-search-filter-select.component.ts index 15bc7954d4..ba81d7c2a4 100644 --- a/projects/ui/src/lib/components/po-search/samples/sample-po-search-filter-select/sample-po-search-filter-select.component.ts +++ b/projects/ui/src/lib/components/po-search/samples/sample-po-search-filter-select/sample-po-search-filter-select.component.ts @@ -1,8 +1,9 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-search-filter-select', templateUrl: './sample-po-search-filter-select.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSearchFilterSelectComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-search/samples/sample-po-search-find-people/sample-po-search-find-people.component.ts b/projects/ui/src/lib/components/po-search/samples/sample-po-search-find-people/sample-po-search-find-people.component.ts index 69cbc35b40..a5cd59a087 100644 --- a/projects/ui/src/lib/components/po-search/samples/sample-po-search-find-people/sample-po-search-find-people.component.ts +++ b/projects/ui/src/lib/components/po-search/samples/sample-po-search-find-people/sample-po-search-find-people.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { SamplePoSearchFindPeopleService } from './sample-po-search-find-people.service'; @Component({ @@ -6,6 +6,7 @@ import { SamplePoSearchFindPeopleService } from './sample-po-search-find-people. templateUrl: './sample-po-search-find-people.component.html', styleUrls: ['./sample-po-search-find-people.component.css'], providers: [SamplePoSearchFindPeopleService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSearchFindPeopleComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-search/samples/sample-po-search-labs/sample-po-search-labs.component.ts b/projects/ui/src/lib/components/po-search/samples/sample-po-search-labs/sample-po-search-labs.component.ts index e1c021d5d1..bc5e70b197 100644 --- a/projects/ui/src/lib/components/po-search/samples/sample-po-search-labs/sample-po-search-labs.component.ts +++ b/projects/ui/src/lib/components/po-search/samples/sample-po-search-labs/sample-po-search-labs.component.ts @@ -1,5 +1,5 @@ import { HttpClient } from '@angular/common/http'; -import { Component, OnChanges, OnInit, SimpleChanges, ViewChild, inject } from '@angular/core'; +import { Component, OnChanges, OnInit, SimpleChanges, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption, @@ -13,6 +13,7 @@ import { PoSearchLocateSummary } from '@po-ui/ng-components/lib/components/po-se selector: 'sample-po-search-labs', templateUrl: './sample-po-search-labs.component.html', styleUrls: ['./sample-po-search-labs.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSearchLabsComponent implements OnInit, OnChanges { diff --git a/projects/ui/src/lib/components/po-search/samples/sample-po-search-listbox/sample-po-search-listbox.component.ts b/projects/ui/src/lib/components/po-search/samples/sample-po-search-listbox/sample-po-search-listbox.component.ts index 2cdb0421a1..ccd11ef6ef 100644 --- a/projects/ui/src/lib/components/po-search/samples/sample-po-search-listbox/sample-po-search-listbox.component.ts +++ b/projects/ui/src/lib/components/po-search/samples/sample-po-search-listbox/sample-po-search-listbox.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { SamplePoSearchListboxService } from './sample-po-search-listbox.service'; @Component({ selector: 'sample-po-search-listbox', templateUrl: './sample-po-search-listbox.component.html', providers: [SamplePoSearchListboxService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSearchListboxComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-skeleton/po-skeleton-base.component.spec.ts b/projects/ui/src/lib/components/po-skeleton/po-skeleton-base.component.spec.ts index e8d9ef4b11..172a154a69 100644 --- a/projects/ui/src/lib/components/po-skeleton/po-skeleton-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-skeleton/po-skeleton-base.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { PoSkeletonBaseComponent } from './po-skeleton-base.component'; @@ -10,6 +10,7 @@ import { PoSkeletonVariant } from './enums/po-skeleton-variant.enum'; @Component({ selector: 'po-test-skeleton', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class TestSkeletonComponent extends PoSkeletonBaseComponent {} diff --git a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-article/sample-po-skeleton-article.component.ts b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-article/sample-po-skeleton-article.component.ts index 9a9c1b79e9..a87a13361c 100644 --- a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-article/sample-po-skeleton-article.component.ts +++ b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-article/sample-po-skeleton-article.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-skeleton-article', templateUrl: './sample-po-skeleton-article.component.html', styleUrls: ['./sample-po-skeleton-article.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSkeletonArticleComponent {} diff --git a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-basic/sample-po-skeleton-basic.component.ts b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-basic/sample-po-skeleton-basic.component.ts index af8bff26ba..eb3162d379 100644 --- a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-basic/sample-po-skeleton-basic.component.ts +++ b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-basic/sample-po-skeleton-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-skeleton-basic', templateUrl: './sample-po-skeleton-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSkeletonBasicComponent {} diff --git a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-credit-card/sample-po-skeleton-credit-card.component.ts b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-credit-card/sample-po-skeleton-credit-card.component.ts index 0b1f31af7a..b0cdda411d 100644 --- a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-credit-card/sample-po-skeleton-credit-card.component.ts +++ b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-credit-card/sample-po-skeleton-credit-card.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-skeleton-credit-card', templateUrl: './sample-po-skeleton-credit-card.component.html', styleUrls: ['./sample-po-skeleton-credit-card.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSkeletonCreditCardComponent {} diff --git a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-labs/sample-po-skeleton-labs.component.ts b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-labs/sample-po-skeleton-labs.component.ts index 532de694b6..e7cded37b8 100644 --- a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-labs/sample-po-skeleton-labs.component.ts +++ b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-labs/sample-po-skeleton-labs.component.ts @@ -1,8 +1,9 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-skeleton-labs', templateUrl: './sample-po-skeleton-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSkeletonLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-social-post/sample-po-skeleton-social-post.component.ts b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-social-post/sample-po-skeleton-social-post.component.ts index ddfd5bf28f..f71caa3533 100644 --- a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-social-post/sample-po-skeleton-social-post.component.ts +++ b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-social-post/sample-po-skeleton-social-post.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-skeleton-social-post', templateUrl: './sample-po-skeleton-social-post.component.html', styleUrls: ['./sample-po-skeleton-social-post.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSkeletonSocialPostComponent {} diff --git a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-user-profile/sample-po-skeleton-user-profile.component.ts b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-user-profile/sample-po-skeleton-user-profile.component.ts index 8b277e26e9..c8ff3cef9c 100644 --- a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-user-profile/sample-po-skeleton-user-profile.component.ts +++ b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-user-profile/sample-po-skeleton-user-profile.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-skeleton-user-profile', templateUrl: './sample-po-skeleton-user-profile.component.html', styleUrls: ['./sample-po-skeleton-user-profile.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSkeletonUserProfileComponent {} diff --git a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-widget-card/sample-po-skeleton-widget-card.component.ts b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-widget-card/sample-po-skeleton-widget-card.component.ts index ba250e61f4..f8e87c4197 100644 --- a/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-widget-card/sample-po-skeleton-widget-card.component.ts +++ b/projects/ui/src/lib/components/po-skeleton/samples/sample-po-skeleton-widget-card/sample-po-skeleton-widget-card.component.ts @@ -1,9 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-skeleton-widget-card', templateUrl: './sample-po-skeleton-widget-card.component.html', styleUrls: ['./sample-po-skeleton-widget-card.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSkeletonWidgetCardComponent {} diff --git a/projects/ui/src/lib/components/po-slide/po-slide-circles/po-slide-circles.component.ts b/projects/ui/src/lib/components/po-slide/po-slide-circles/po-slide-circles.component.ts index 8e3da5ccb0..55408f8dbd 100644 --- a/projects/ui/src/lib/components/po-slide/po-slide-circles/po-slide-circles.component.ts +++ b/projects/ui/src/lib/components/po-slide/po-slide-circles/po-slide-circles.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from '@angular/core'; /** * @docsPrivate @@ -10,6 +10,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector: 'po-slide-circles', templateUrl: './po-slide-circles.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoSlideCirclesComponent { diff --git a/projects/ui/src/lib/components/po-slide/po-slide-control/po-slide-control.component.ts b/projects/ui/src/lib/components/po-slide/po-slide-control/po-slide-control.component.ts index ae91f0dab3..b6ab23db64 100644 --- a/projects/ui/src/lib/components/po-slide/po-slide-control/po-slide-control.component.ts +++ b/projects/ui/src/lib/components/po-slide/po-slide-control/po-slide-control.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from '@angular/core'; /** * @docsPrivate @@ -10,6 +10,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector: 'po-slide-control', templateUrl: './po-slide-control.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoSlideControlComponent { diff --git a/projects/ui/src/lib/components/po-slide/po-slide-item/po-slide-item.component.spec.ts b/projects/ui/src/lib/components/po-slide/po-slide-item/po-slide-item.component.spec.ts index 00e481113b..29d9e8c890 100644 --- a/projects/ui/src/lib/components/po-slide/po-slide-item/po-slide-item.component.spec.ts +++ b/projects/ui/src/lib/components/po-slide/po-slide-item/po-slide-item.component.spec.ts @@ -1,6 +1,7 @@ import { provideNgReflectAttributes } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { PoSlideItemComponent } from './po-slide-item.component'; @@ -11,9 +12,9 @@ describe('PoSlideItemComponent:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([])], + imports: [RouterModule.forRoot([])], declarations: [PoSlideItemComponent], - providers: [provideNgReflectAttributes()] + providers: [provideLocationMocks(), provideNgReflectAttributes()] }).compileComponents(); fixture = TestBed.createComponent(PoSlideItemComponent); diff --git a/projects/ui/src/lib/components/po-slide/po-slide-item/po-slide-item.component.ts b/projects/ui/src/lib/components/po-slide/po-slide-item/po-slide-item.component.ts index ea03368f10..639cfa8cab 100644 --- a/projects/ui/src/lib/components/po-slide/po-slide-item/po-slide-item.component.ts +++ b/projects/ui/src/lib/components/po-slide/po-slide-item/po-slide-item.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, Input, ViewChild } from '@angular/core'; +import { Component, ElementRef, Input, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { isIEOrEdge } from '../../../utils/util'; @@ -14,6 +14,7 @@ import { PoSlideContentTemplateDirective } from '../directives/po-slide-content- @Component({ selector: 'po-slide-item', templateUrl: './po-slide-item.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoSlideItemComponent { diff --git a/projects/ui/src/lib/components/po-slide/po-slide.component.spec.ts b/projects/ui/src/lib/components/po-slide/po-slide.component.spec.ts index 24cb998dc4..95236718be 100644 --- a/projects/ui/src/lib/components/po-slide/po-slide.component.spec.ts +++ b/projects/ui/src/lib/components/po-slide/po-slide.component.spec.ts @@ -1,7 +1,7 @@ import { SimpleChange } from '@angular/core'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { PoSlideCirclesComponent } from './po-slide-circles/po-slide-circles.component'; import { PoSlideComponent } from './po-slide.component'; @@ -16,8 +16,9 @@ describe('PoSlideComponent:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([]), BrowserAnimationsModule], - declarations: [PoSlideCirclesComponent, PoSlideComponent, PoSlideControlComponent, PoSlideItemComponent] + imports: [RouterModule.forRoot([])], + declarations: [PoSlideCirclesComponent, PoSlideComponent, PoSlideControlComponent, PoSlideItemComponent], + providers: [provideLocationMocks()] }).compileComponents(); fixture = TestBed.createComponent(PoSlideComponent); @@ -323,36 +324,53 @@ describe('PoSlideComponent:', () => { expect(component['setHeight']).toHaveBeenCalledWith(slideHeight); }); - it(`animate: should call 'buildTransitionAnimation' with offset if has elements`, () => { + it(`animate: should call element.animate with offset if has elements`, () => { const offset = 400; spyOnProperty(component, 'hasElements').and.returnValue(true); - spyOn(component, 'buildTransitionAnimation').and.callThrough(); + spyOn(component['slide'].nativeElement, 'animate').and.returnValue({ cancel: () => {} }); component['animate'](offset); - expect(component['buildTransitionAnimation']).toHaveBeenCalledWith(offset); + expect(component['slide'].nativeElement.animate).toHaveBeenCalledWith( + [{ transform: 'translateX(-0px)' }, { transform: 'translateX(-400px)' }], + { duration: 250, easing: 'ease', fill: 'forwards' } + ); }); - it(`animate: shouldn't call 'buildTransitionAnimation' with offset if doesn't have elements`, () => { + it(`animate: shouldn't call element.animate if doesn't have elements`, () => { const offset = 400; spyOnProperty(component, 'hasElements').and.returnValue(false); - spyOn(component, 'buildTransitionAnimation'); + spyOn(component['slide'].nativeElement, 'animate'); component['animate'](offset); - expect(component['buildTransitionAnimation']).not.toHaveBeenCalled(); + expect(component['slide'].nativeElement.animate).not.toHaveBeenCalled(); }); - it(`buildTransitionAnimation: should call builder`, () => { - const offset = 400; + it(`animate: should cancel previous animation before starting new one`, () => { + spyOnProperty(component, 'hasElements').and.returnValue(true); + const cancelSpy = jasmine.createSpy('cancel'); + component['currentAnimation'] = { cancel: cancelSpy } as any; + spyOn(component['slide'].nativeElement, 'animate').and.returnValue({ cancel: () => {} }); + + component['animate'](200); + + expect(cancelSpy).toHaveBeenCalled(); + }); - spyOn(component['builder'], 'build').and.callThrough(); + it(`animate: should track previousOffset for smooth transitions`, () => { + spyOnProperty(component, 'hasElements').and.returnValue(true); + spyOn(component['slide'].nativeElement, 'animate').and.returnValue({ cancel: () => {} }); - component['buildTransitionAnimation'](offset); + component['animate'](400); + component['animate'](0); - expect(component['builder'].build).toHaveBeenCalled(); + expect(component['slide'].nativeElement.animate).toHaveBeenCalledWith( + [{ transform: 'translateX(-400px)' }, { transform: 'translateX(-0px)' }], + { duration: 250, easing: 'ease', fill: 'forwards' } + ); }); it(`createArrayForTemplate: should update 'slideItems' with array of any.`, () => { @@ -581,10 +599,12 @@ describe('PoSlideComponent:', () => { component.slides = [{ alt: '1' }, { alt: '2' }, { alt: '3' }, { alt: '4' }]; fixture.detectChanges(); - const interval = 1000; spyOn(component, 'next'); + spyOnProperty(component, 'hasElements').and.returnValue(true); + spyOnProperty(component, 'hasSlides').and.returnValue(true); - component.interval = interval; + component.interval = 1000; + component['startInterval'](); tick(2000); component['cancelInterval'](); @@ -598,6 +618,9 @@ describe('PoSlideComponent:', () => { component.slides = [{ alt: '1' }, { alt: '2' }, { alt: '3' }, { alt: '4' }]; fixture.detectChanges(); + // Simular que o elemento tem dimensões visíveis no DOM + Object.defineProperty(component['slide'].nativeElement, 'offsetWidth', { value: 800, configurable: true }); + expect(component['hasElements']).toBe(true); }); diff --git a/projects/ui/src/lib/components/po-slide/po-slide.component.ts b/projects/ui/src/lib/components/po-slide/po-slide.component.ts index 90d2df7bfe..09302cd530 100644 --- a/projects/ui/src/lib/components/po-slide/po-slide.component.ts +++ b/projects/ui/src/lib/components/po-slide/po-slide.component.ts @@ -11,11 +11,9 @@ import { OnDestroy, OnInit, SimpleChanges, - inject + ChangeDetectionStrategy } from '@angular/core'; -import { animate, AnimationBuilder, AnimationFactory, AnimationPlayer, keyframes, style } from '@angular/animations'; - import { Subscription, Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; @@ -27,7 +25,6 @@ import { PoSlideItemComponent } from './po-slide-item/po-slide-item.component'; const poSlideDefaultHeight = 336; const poSlideIntervalMin = 1000; const poSlideMinHeight = 192; -const poSlideTiming = '250ms ease'; /** * @docsExtends PoSlideBaseComponent @@ -61,11 +58,10 @@ const poSlideTiming = '250ms ease'; @Component({ selector: 'po-slide', templateUrl: './po-slide.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoSlideComponent extends PoSlideBaseComponent implements OnInit, DoCheck, OnChanges, OnDestroy { - private readonly builder = inject(AnimationBuilder); - @ContentChild(PoSlideContentTemplateDirective, { static: true }) slideContentTemplate: PoSlideContentTemplateDirective; @@ -79,7 +75,8 @@ export class PoSlideComponent extends PoSlideBaseComponent implements OnInit, Do slideItemWidth: number; private isLoaded: boolean = false; - private player: AnimationPlayer; + private currentAnimation: Animation; + private previousOffset: number = 0; private setInterval: any; private readonly resize$ = new Subject(); private resizeSubscription: Subscription; @@ -255,15 +252,19 @@ export class PoSlideComponent extends PoSlideBaseComponent implements OnInit, Do private animate(offset: number) { if (this.hasElements) { - const animation: AnimationFactory = this.buildTransitionAnimation(offset); + const element = this.slide.nativeElement; - this.player = animation.create(this.slide.nativeElement); - this.player.play(); - } - } + if (this.currentAnimation) { + this.currentAnimation.cancel(); + } + + this.currentAnimation = element.animate( + [{ transform: `translateX(-${this.previousOffset}px)` }, { transform: `translateX(-${offset}px)` }], + { duration: 250, easing: 'ease', fill: 'forwards' } + ); - private buildTransitionAnimation(offset: number) { - return this.builder.build([animate(poSlideTiming, keyframes([style({ transform: `translateX(-${offset}px)` })]))]); + this.previousOffset = offset; + } } private createArrayForTemplate(slides: Array) { diff --git a/projects/ui/src/lib/components/po-slide/po-slide.module.ts b/projects/ui/src/lib/components/po-slide/po-slide.module.ts index 544e7283f2..ef19a231eb 100644 --- a/projects/ui/src/lib/components/po-slide/po-slide.module.ts +++ b/projects/ui/src/lib/components/po-slide/po-slide.module.ts @@ -16,43 +16,6 @@ import { PoSlideItemComponent } from './po-slide-item/po-slide-item.component'; * * Módulo do componente `po-slide`. * - * > Para o correto funcionamento do componente `po-slide`, deve ser importado o módulo `BrowserAnimationsModule` no - * > módulo principal da sua aplicação. - * - * Módulo da aplicação: - * ``` - * import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - * import { PoModule } from '@po-ui/ng-components'; - * ... - * - * @NgModule({ - * imports: [ - * BrowserModule, - * BrowserAnimationsModule, - * ... - * PoModule - * ], - * declarations: [ - * AppComponent, - * ... - * ], - * providers: [], - * bootstrap: [AppComponent] - * }) - * export class AppModule { } - * ``` - * - * Em aplicações Standalone, utilize a seguinte configuração para o bootstrap: - * - * ``` - * import { bootstrapApplication } from '@angular/platform-browser'; - * import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - * import { AppComponent } from './app.component'; - * - * bootstrapApplication(AppComponent, { - * providers: [importProvidersFrom(BrowserAnimationsModule)] - * }).catch(err => console.error(err)); - * ``` */ @NgModule({ imports: [CommonModule, RouterModule, PoContainerModule, PoIconModule], diff --git a/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-basic/sample-po-slide-basic.component.ts b/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-basic/sample-po-slide-basic.component.ts index ce4967446a..3703b59331 100644 --- a/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-basic/sample-po-slide-basic.component.ts +++ b/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-basic/sample-po-slide-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-slide-basic', templateUrl: './sample-po-slide-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSlideBasicComponent {} diff --git a/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-external-controls/sample-po-slide-external-controls.component.ts b/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-external-controls/sample-po-slide-external-controls.component.ts index 9ce35b79f2..d7bd09dfcd 100644 --- a/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-external-controls/sample-po-slide-external-controls.component.ts +++ b/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-external-controls/sample-po-slide-external-controls.component.ts @@ -1,10 +1,11 @@ -import { Component, OnChanges, ViewChild } from '@angular/core'; +import { Component, OnChanges, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoSlideComponent } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-slide-external-controls', templateUrl: './sample-po-slide-external-controls.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSlideExternalControlsComponent { diff --git a/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-labs/sample-po-slide-labs.component.ts b/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-labs/sample-po-slide-labs.component.ts index f4cca9458a..f562b3c064 100644 --- a/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-labs/sample-po-slide-labs.component.ts +++ b/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-labs/sample-po-slide-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService, PoSlideItem } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-slide-labs', templateUrl: './sample-po-slide-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSlideLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-landscapes/sample-po-slide-landscapes.component.ts b/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-landscapes/sample-po-slide-landscapes.component.ts index 57383d1882..51aa92f4ec 100644 --- a/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-landscapes/sample-po-slide-landscapes.component.ts +++ b/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-landscapes/sample-po-slide-landscapes.component.ts @@ -1,10 +1,11 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoModalComponent, PoSlideItem } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-slide-landscapes', templateUrl: './sample-po-slide-landscapes.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSlideLandscapesComponent { diff --git a/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-useful-articles/sample-po-slide-useful-articles.component.ts b/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-useful-articles/sample-po-slide-useful-articles.component.ts index 1411e88507..7a5b9d7876 100644 --- a/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-useful-articles/sample-po-slide-useful-articles.component.ts +++ b/projects/ui/src/lib/components/po-slide/samples/sample-po-slide-useful-articles/sample-po-slide-useful-articles.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-slide-useful-articles', templateUrl: './sample-po-slide-useful-articles.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoSlideUsefulArticlesComponent { diff --git a/projects/ui/src/lib/components/po-stepper/po-step/po-step.component.ts b/projects/ui/src/lib/components/po-stepper/po-step/po-step.component.ts index 411a14d882..1862d06923 100644 --- a/projects/ui/src/lib/components/po-stepper/po-step/po-step.component.ts +++ b/projects/ui/src/lib/components/po-stepper/po-step/po-step.component.ts @@ -1,4 +1,12 @@ -import { AfterContentInit, Component, ElementRef, Input, TemplateRef, inject } from '@angular/core'; +import { + AfterContentInit, + Component, + ElementRef, + Input, + TemplateRef, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { Observable } from 'rxjs'; import { uuid } from '../../../utils/util'; @@ -45,6 +53,7 @@ import { PoStepperStatus } from '../enums/po-stepper-status.enum'; @Component({ selector: 'po-step', templateUrl: 'po-step.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoStepComponent implements AfterContentInit { diff --git a/projects/ui/src/lib/components/po-stepper/po-stepper-circle/po-stepper-circle.component.ts b/projects/ui/src/lib/components/po-stepper/po-stepper-circle/po-stepper-circle.component.ts index fb5068305a..b1dd7ac796 100644 --- a/projects/ui/src/lib/components/po-stepper/po-stepper-circle/po-stepper-circle.component.ts +++ b/projects/ui/src/lib/components/po-stepper/po-stepper-circle/po-stepper-circle.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, TemplateRef } from '@angular/core'; +import { Component, Input, TemplateRef, ChangeDetectionStrategy } from '@angular/core'; import { PoStepperStatus } from '../enums/po-stepper-status.enum'; @@ -15,6 +15,7 @@ const poLargeStepSize = 48; @Component({ selector: 'po-stepper-circle', templateUrl: './po-stepper-circle.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoStepperCircleComponent { diff --git a/projects/ui/src/lib/components/po-stepper/po-stepper-label/po-stepper-label.component.ts b/projects/ui/src/lib/components/po-stepper/po-stepper-label/po-stepper-label.component.ts index 23621489e3..d9961804e0 100644 --- a/projects/ui/src/lib/components/po-stepper/po-stepper-label/po-stepper-label.component.ts +++ b/projects/ui/src/lib/components/po-stepper/po-stepper-label/po-stepper-label.component.ts @@ -9,7 +9,8 @@ import { Renderer2, SimpleChanges, ViewChild, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; /** @@ -22,6 +23,7 @@ import { @Component({ selector: 'po-stepper-label', templateUrl: './po-stepper-label.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoStepperLabelComponent implements AfterViewInit, OnChanges { diff --git a/projects/ui/src/lib/components/po-stepper/po-stepper-step/po-stepper-step.component.ts b/projects/ui/src/lib/components/po-stepper/po-stepper-step/po-stepper-step.component.ts index 65e2d00476..df57f36f8e 100644 --- a/projects/ui/src/lib/components/po-stepper/po-stepper-step/po-stepper-step.component.ts +++ b/projects/ui/src/lib/components/po-stepper/po-stepper-step/po-stepper-step.component.ts @@ -1,4 +1,13 @@ -import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, TemplateRef } from '@angular/core'; +import { + Component, + EventEmitter, + Input, + OnChanges, + Output, + SimpleChanges, + TemplateRef, + ChangeDetectionStrategy +} from '@angular/core'; import { getShortBrowserLanguage, convertToBoolean, isTypeof } from './../../../utils/util'; import { poLocaleDefault } from './../../../services/po-language/po-language.constant'; @@ -23,6 +32,7 @@ const poStepLiteralsDefault = { @Component({ selector: 'po-stepper-step', templateUrl: 'po-stepper-step.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoStepperStepComponent implements OnChanges { diff --git a/projects/ui/src/lib/components/po-stepper/po-stepper.component.html b/projects/ui/src/lib/components/po-stepper/po-stepper.component.html index 4b7c84f327..ae945796b7 100644 --- a/projects/ui/src/lib/components/po-stepper/po-stepper.component.html +++ b/projects/ui/src/lib/components/po-stepper/po-stepper.component.html @@ -1,17 +1,18 @@
    - + @for (step of stepList; track step.id; let index = $index) {
    -
    + @if (index > 0) { +
    + } -
    + @if (index < stepList.length - 1) { +
    + }
    -
    + }
    -
    - -
    + @if (usePoSteps) { +
    + +
    + }
    diff --git a/projects/ui/src/lib/components/po-stepper/po-stepper.component.spec.ts b/projects/ui/src/lib/components/po-stepper/po-stepper.component.spec.ts index e3a18edd88..5cbcebfc54 100644 --- a/projects/ui/src/lib/components/po-stepper/po-stepper.component.spec.ts +++ b/projects/ui/src/lib/components/po-stepper/po-stepper.component.spec.ts @@ -409,6 +409,7 @@ describe('PoStepperComponent:', () => { const step = { status: 'default' } as PoStepComponent; const previousStep = { status: 'active' } as PoStepperItem; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(component, 'getPreviousPoSteps').and.returnValue(previousStep as unknown as PoStepComponent); spyOn(component, 'getPreviousSteps').and.returnValue(previousStep); @@ -421,6 +422,7 @@ describe('PoStepperComponent:', () => { const step = { status: 'disabled' } as PoStepComponent; const previousStep = { status: 'default' } as PoStepperItem; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(component, 'getPreviousPoSteps').and.returnValue(previousStep as unknown as PoStepComponent); spyOn(component, 'getPreviousSteps').and.returnValue(previousStep); diff --git a/projects/ui/src/lib/components/po-stepper/po-stepper.component.ts b/projects/ui/src/lib/components/po-stepper/po-stepper.component.ts index 03932757a2..58574c9f0a 100644 --- a/projects/ui/src/lib/components/po-stepper/po-stepper.component.ts +++ b/projects/ui/src/lib/components/po-stepper/po-stepper.component.ts @@ -1,4 +1,12 @@ -import { AfterContentInit, ChangeDetectorRef, Component, ContentChildren, QueryList, inject } from '@angular/core'; +import { + AfterContentInit, + ChangeDetectorRef, + Component, + ContentChildren, + QueryList, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { Observable, of, throwError } from 'rxjs'; import { take, tap, catchError, map, mergeMap } from 'rxjs/operators'; @@ -43,6 +51,7 @@ import { PoStepperItem } from './po-stepper-item.interface'; @Component({ selector: 'po-stepper', templateUrl: './po-stepper.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoStepperComponent extends PoStepperBaseComponent implements AfterContentInit { @@ -242,10 +251,6 @@ export class PoStepperComponent extends PoStepperBaseComponent implements AfterC }); } - trackByFn(step: PoStepComponent) { - return step.id; - } - private activeFirstStep() { const hasStepActive = this.poSteps.some(poStep => poStep.status === PoStepperStatus.Active); diff --git a/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-active/sample-po-stepper-active.component.ts b/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-active/sample-po-stepper-active.component.ts index 7524d39ab2..a2e143eef6 100644 --- a/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-active/sample-po-stepper-active.component.ts +++ b/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-active/sample-po-stepper-active.component.ts @@ -1,4 +1,13 @@ -import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild, inject } from '@angular/core'; +import { + AfterViewInit, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit, + ViewChild, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { NgForm } from '@angular/forms'; import { Subscription } from 'rxjs'; import { PoSelectOption, PoStepperComponent } from '@po-ui/ng-components'; @@ -7,6 +16,7 @@ import { SamplePoStepperActiveService } from './sample-po-stepper-active.service @Component({ selector: 'sample-po-stepper-active', templateUrl: './sample-po-stepper-active.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoStepperActiveComponent implements OnInit, AfterViewInit, OnDestroy { diff --git a/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-basic/sample-po-stepper-basic.component.ts b/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-basic/sample-po-stepper-basic.component.ts index 243f721068..bbc5be642e 100644 --- a/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-basic/sample-po-stepper-basic.component.ts +++ b/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-basic/sample-po-stepper-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-stepper-basic', templateUrl: './sample-po-stepper-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoStepperBasicComponent {} diff --git a/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-labs/sample-po-stepper-labs.component.ts b/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-labs/sample-po-stepper-labs.component.ts index 1a1aa1635b..4044e751d2 100644 --- a/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-labs/sample-po-stepper-labs.component.ts +++ b/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-labs/sample-po-stepper-labs.component.ts @@ -1,10 +1,11 @@ -import { ChangeDetectorRef, Component, OnInit, inject } from '@angular/core'; +import { ChangeDetectorRef, Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoDynamicFormField, PoStepperItem } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-stepper-labs', templateUrl: './sample-po-stepper-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoStepperLabsComponent implements OnInit { @@ -12,7 +13,7 @@ export class SamplePoStepperLabsComponent implements OnInit { event: any; properties: any = {}; - stepItem: PoStepperItem = {}; + stepItem: PoStepperItem = {}; steps: Array = []; readonly propertiesFields: Array = [ diff --git a/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-sales/sample-po-stepper-sales.component.ts b/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-sales/sample-po-stepper-sales.component.ts index 2bcdab83fa..b182bdac19 100644 --- a/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-sales/sample-po-stepper-sales.component.ts +++ b/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-sales/sample-po-stepper-sales.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoModalComponent, PoStepComponent, PoStepperComponent } from '@po-ui/ng-components'; @@ -9,6 +9,7 @@ import { delay, finalize, map, tap } from 'rxjs/operators'; selector: 'sample-po-stepper-sales', templateUrl: './sample-po-stepper-sales.component.html', styleUrls: ['./sample-po-stepper-sales.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoStepperSalesComponent { diff --git a/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-steps/sample-po-stepper-steps.component.ts b/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-steps/sample-po-stepper-steps.component.ts index e824e47fe6..13e9c16300 100644 --- a/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-steps/sample-po-stepper-steps.component.ts +++ b/projects/ui/src/lib/components/po-stepper/samples/sample-po-stepper-steps/sample-po-stepper-steps.component.ts @@ -1,9 +1,10 @@ -import { AfterViewInit, ChangeDetectorRef, Component, inject } from '@angular/core'; +import { AfterViewInit, ChangeDetectorRef, Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoStepperItem, PoStepperStatus } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-stepper-steps', templateUrl: './sample-po-stepper-steps.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoStepperStepsComponent implements AfterViewInit { diff --git a/projects/ui/src/lib/components/po-table/po-table-base.component.spec.ts b/projects/ui/src/lib/components/po-table/po-table-base.component.spec.ts index 6240c82ac5..67088527fa 100644 --- a/projects/ui/src/lib/components/po-table/po-table-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-table/po-table-base.component.spec.ts @@ -6,7 +6,7 @@ import { PoLanguageService } from '../../services/po-language/po-language.servic import { expectPropertiesValues, expectSettersMethod } from '../../util-test/util-expect.spec'; import { PoUtils as utilsFunctions } from '../../utils/util'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { Observable, of } from 'rxjs'; @@ -40,7 +40,7 @@ describe('PoTableBaseComponent:', () => { PoTableService, PoLanguageService, PoDateService, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }).compileComponents(); diff --git a/projects/ui/src/lib/components/po-table/po-table-column-frozen/po-table-column-frozen.directive.spec.ts b/projects/ui/src/lib/components/po-table/po-table-column-frozen/po-table-column-frozen.directive.spec.ts index e2f7fbe5af..a20519d178 100644 --- a/projects/ui/src/lib/components/po-table/po-table-column-frozen/po-table-column-frozen.directive.spec.ts +++ b/projects/ui/src/lib/components/po-table/po-table-column-frozen/po-table-column-frozen.directive.spec.ts @@ -1,5 +1,5 @@ import { TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing'; -import { Component, DebugElement, ElementRef, SimpleChanges } from '@angular/core'; +import { Component, DebugElement, ElementRef, SimpleChanges, ChangeDetectionStrategy } from '@angular/core'; import { By } from '@angular/platform-browser'; import { PoTableColumnFrozenDirective } from './po-table-column-frozen.directive'; @@ -10,6 +10,7 @@ import { PoTableColumnFrozenDirective } from './po-table-column-frozen.directive
    `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class TestHostComponent { diff --git a/projects/ui/src/lib/components/po-table/po-table-column-icon/po-table-column-icon.component.html b/projects/ui/src/lib/components/po-table/po-table-column-icon/po-table-column-icon.component.html index 003daa589d..32098361ec 100644 --- a/projects/ui/src/lib/components/po-table/po-table-column-icon/po-table-column-icon.component.html +++ b/projects/ui/src/lib/components/po-table/po-table-column-icon/po-table-column-icon.component.html @@ -1,10 +1,11 @@ - - +@for (column of icons; track $index) { + + +} diff --git a/projects/ui/src/lib/components/po-table/po-table-column-link/po-table-column-link.component.spec.ts b/projects/ui/src/lib/components/po-table/po-table-column-link/po-table-column-link.component.spec.ts index 22cfb9ea46..93639cbbf6 100644 --- a/projects/ui/src/lib/components/po-table/po-table-column-link/po-table-column-link.component.spec.ts +++ b/projects/ui/src/lib/components/po-table/po-table-column-link/po-table-column-link.component.spec.ts @@ -1,5 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { PoTableColumnLinkComponent } from './po-table-column-link.component'; import { PoTableModule } from '../po-table.module'; @@ -12,7 +13,8 @@ describe('PoTableColumnLinkComponent:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([]), PoTableModule, PoTooltipModule] + imports: [RouterModule.forRoot([]), PoTableModule, PoTooltipModule], + providers: [provideLocationMocks()] }).compileComponents(); fixture = TestBed.createComponent(PoTableColumnLinkComponent); diff --git a/projects/ui/src/lib/components/po-table/po-table-column-manager/po-table-column-manager.component.spec.ts b/projects/ui/src/lib/components/po-table/po-table-column-manager/po-table-column-manager.component.spec.ts index 7bfff79e69..49db643e7c 100644 --- a/projects/ui/src/lib/components/po-table/po-table-column-manager/po-table-column-manager.component.spec.ts +++ b/projects/ui/src/lib/components/po-table/po-table-column-manager/po-table-column-manager.component.spec.ts @@ -757,7 +757,7 @@ describe('PoTableColumnManagerComponent:', () => { it(`should return 'column.label' if it has 'column.label'`, () => { const fakeColumn = { property: 'name', label: 'Name' }; - expect(component['getColumnTitleLabel'](fakeColumn)).toBe(fakeColumn.label); + expect(component['getColumnTitleLabel'](fakeColumn)).toBe(fakeColumn.label); }); it(`should call 'capitalizeFirstLetter' to set 'getColumnTitleLabel' if 'column.label' is undefined`, () => { diff --git a/projects/ui/src/lib/components/po-table/po-table-column-manager/po-table-column-manager.component.ts b/projects/ui/src/lib/components/po-table/po-table-column-manager/po-table-column-manager.component.ts index bc507de28c..7a316e0fbf 100644 --- a/projects/ui/src/lib/components/po-table/po-table-column-manager/po-table-column-manager.component.ts +++ b/projects/ui/src/lib/components/po-table/po-table-column-manager/po-table-column-manager.component.ts @@ -10,7 +10,8 @@ import { SimpleChange, SimpleChanges, ViewChild, - output + output, + ChangeDetectionStrategy } from '@angular/core'; import { PoFieldSize } from '../../../enums/po-field-size.enum'; @@ -48,6 +49,7 @@ type Direction = 'up' | 'down'; @Component({ selector: 'po-table-column-manager', templateUrl: './po-table-column-manager.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoTableColumnManagerComponent implements OnChanges, OnDestroy { diff --git a/projects/ui/src/lib/components/po-table/po-table-detail/po-table-detail.component.ts b/projects/ui/src/lib/components/po-table/po-table-detail/po-table-detail.component.ts index 5efe310aba..5445338b06 100644 --- a/projects/ui/src/lib/components/po-table/po-table-detail/po-table-detail.component.ts +++ b/projects/ui/src/lib/components/po-table/po-table-detail/po-table-detail.component.ts @@ -1,5 +1,5 @@ import { DecimalPipe } from '@angular/common'; -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from '@angular/core'; import { getDefaultSizeFn, isTypeof, validateSizeFn, PoUtils } from '../../../utils/util'; @@ -17,6 +17,7 @@ import { PoTableDetail } from './po-table-detail.interface'; @Component({ selector: 'po-table-detail', templateUrl: './po-table-detail.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoTableDetailComponent { diff --git a/projects/ui/src/lib/components/po-table/po-table-list-manager/po-table-list-manager.component.ts b/projects/ui/src/lib/components/po-table/po-table-list-manager/po-table-list-manager.component.ts index 7e2f9db0e3..0209f01c4c 100644 --- a/projects/ui/src/lib/components/po-table/po-table-list-manager/po-table-list-manager.component.ts +++ b/projects/ui/src/lib/components/po-table/po-table-list-manager/po-table-list-manager.component.ts @@ -1,4 +1,12 @@ -import { ChangeDetectorRef, Component, EventEmitter, Inject, Input, Optional, Output, forwardRef } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + EventEmitter, + Input, + Output, + forwardRef, + ChangeDetectionStrategy +} from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { PoFieldSize } from '../../../enums/po-field-size.enum'; @@ -47,6 +55,7 @@ type Direction = 'up' | 'down'; multi: true } ], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoTableListManagerComponent extends PoCheckboxGroupComponent { diff --git a/projects/ui/src/lib/components/po-table/po-table-show-subtitle/po-table-show-subtitle.component.ts b/projects/ui/src/lib/components/po-table/po-table-show-subtitle/po-table-show-subtitle.component.ts index cfe375c4e3..9c2297fd33 100644 --- a/projects/ui/src/lib/components/po-table/po-table-show-subtitle/po-table-show-subtitle.component.ts +++ b/projects/ui/src/lib/components/po-table/po-table-show-subtitle/po-table-show-subtitle.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; import { PoTableSubtitleColumn } from '../po-table-subtitle-footer/po-table-subtitle-column.interface'; @@ -12,6 +12,7 @@ import { PoTableSubtitleColumn } from '../po-table-subtitle-footer/po-table-subt @Component({ selector: 'po-table-show-subtitle', templateUrl: './po-table-show-subtitle.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoTableShowSubtitleComponent { diff --git a/projects/ui/src/lib/components/po-table/po-table-subtitle-footer/po-table-subtitle-footer.component.ts b/projects/ui/src/lib/components/po-table/po-table-subtitle-footer/po-table-subtitle-footer.component.ts index cb7a117886..f6aa94ee60 100644 --- a/projects/ui/src/lib/components/po-table/po-table-subtitle-footer/po-table-subtitle-footer.component.ts +++ b/projects/ui/src/lib/components/po-table/po-table-subtitle-footer/po-table-subtitle-footer.component.ts @@ -1,4 +1,13 @@ -import { AfterViewInit, Component, DoCheck, ElementRef, Input, OnDestroy, Renderer2 } from '@angular/core'; +import { + AfterViewInit, + Component, + DoCheck, + ElementRef, + Input, + OnDestroy, + Renderer2, + ChangeDetectionStrategy +} from '@angular/core'; import { PoTableSubtitleColumn } from './po-table-subtitle-column.interface'; @@ -12,6 +21,7 @@ import { PoTableSubtitleColumn } from './po-table-subtitle-column.interface'; @Component({ selector: 'po-table-subtitle-footer', templateUrl: './po-table-subtitle-footer.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoTableSubtitleFooterComponent implements AfterViewInit, DoCheck, OnDestroy { diff --git a/projects/ui/src/lib/components/po-table/po-table.component.html b/projects/ui/src/lib/components/po-table/po-table.component.html index 570ddfdb94..cd85d59e15 100644 --- a/projects/ui/src/lib/components/po-table/po-table.component.html +++ b/projects/ui/src/lib/components/po-table/po-table.component.html @@ -269,7 +269,7 @@ [ngClass]="{ 'po-table-header-sorted': sort && - JSON.stringify(sortedColumn?.property) === JSON.stringify(column) && + JSON.stringify($safeNavigationMigration(sortedColumn?.property)) === JSON.stringify(column) && (sortedColumn.ascending || !sortedColumn.ascending) }" [ngStyle]="{ @@ -309,7 +309,7 @@ [ngClass]="{ 'po-table-header-sorted': sort && - JSON.stringify(sortedColumn?.property) === JSON.stringify(column) && + JSON.stringify($safeNavigationMigration(sortedColumn?.property)) === JSON.stringify(column) && (sortedColumn.ascending || !sortedColumn.ascending) }" [ngStyle]="{ @@ -430,7 +430,10 @@ @case ('cellTemplate') { @@ -634,7 +637,7 @@ [ngClass]="{ 'po-table-header-sorted': sort && - JSON.stringify(sortedColumn?.property) === JSON.stringify(column) && + JSON.stringify($safeNavigationMigration(sortedColumn?.property)) === JSON.stringify(column) && (sortedColumn.ascending || !sortedColumn.ascending) }" [ngStyle]="{ 'width': !hasItems ? '100%' : applyFixedColumns() ? column.width : 'auto' }" @@ -672,7 +675,7 @@ [ngClass]="{ 'po-table-header-sorted': sort && - JSON.stringify(sortedColumn?.property) === JSON.stringify(column) && + JSON.stringify($safeNavigationMigration(sortedColumn?.property)) === JSON.stringify(column) && (sortedColumn.ascending || !sortedColumn.ascending) }" [ngStyle]="{ 'width': !hasItems ? '100%' : applyFixedColumns() ? column.width : 'auto' }" @@ -793,7 +796,10 @@ @case ('cellTemplate') { @@ -954,21 +960,31 @@ @if (sort && column.sortable !== false) { - @if (JSON.stringify(sortedColumn?.property) !== JSON.stringify(column)) { + @if (JSON.stringify($safeNavigationMigration(sortedColumn?.property)) !== JSON.stringify(column)) { } - @if (JSON.stringify(sortedColumn?.property) === JSON.stringify(column) && sortedColumn.ascending) { + @if ( + JSON.stringify($safeNavigationMigration(sortedColumn?.property)) === JSON.stringify(column) && + sortedColumn.ascending + ) { } - @if (JSON.stringify(sortedColumn?.property) === JSON.stringify(column) && !sortedColumn.ascending) { + @if ( + JSON.stringify($safeNavigationMigration(sortedColumn?.property)) === JSON.stringify(column) && + !sortedColumn.ascending + ) { } diff --git a/projects/ui/src/lib/components/po-table/po-table.component.spec.ts b/projects/ui/src/lib/components/po-table/po-table.component.spec.ts index 7e3a28fa3c..8a675ecbe2 100644 --- a/projects/ui/src/lib/components/po-table/po-table.component.spec.ts +++ b/projects/ui/src/lib/components/po-table/po-table.component.spec.ts @@ -1,10 +1,10 @@ import { DecimalPipe } from '@angular/common'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { Component, ElementRef, TemplateRef, ViewChild } from '@angular/core'; +import { Component, ElementRef, TemplateRef, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; import { By } from '@angular/platform-browser'; -import { Routes } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import { Routes, RouterModule } from '@angular/router'; import { of, throwError } from 'rxjs'; import { PoControlPositionService } from '../../services/po-control-position/po-control-position.service'; @@ -13,8 +13,7 @@ import { PoUtils as utilsFunctions } from '../../utils/util'; import { PoColorPaletteService } from './../../services/po-color-palette/po-color-palette.service'; import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { PoFieldSize } from '../../enums/po-field-size.enum'; import { PoTableRowTemplateArrowDirection } from './enums/po-table-row-template-arrow-direction.enum'; import { PoTableColumnSpacing } from './enums/po-table-spacing.enum'; @@ -31,6 +30,7 @@ import { PoSearchAiResponseType } from '../po-field/po-search-ai/interfaces/po-s @Component({ selector: 'app-table-search', template: 'Search', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SearchComponent {} @@ -38,6 +38,7 @@ export class SearchComponent {} @Component({ selector: 'app-table-test-menu', template: 'Home', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class TestMenuComponent {} @@ -223,7 +224,7 @@ describe('PoTableComponent:', () => { debounceResize: () => true, checkInfiniteScroll: () => {}, applyFixedColumns: () => {}, - initializeVisibleElement() { + initializeVisibleElement: function () { if (this.tableWrapperElement?.nativeElement.offsetWidth && !this.visibleElement) { this.debounceResize(); this.checkInfiniteScroll(); @@ -242,8 +243,9 @@ describe('PoTableComponent:', () => { await TestBed.configureTestingModule({ declarations: [TestMenuComponent, SearchComponent], - imports: [RouterTestingModule.withRoutes(routes), PoTableModule, NoopAnimationsModule], + imports: [RouterModule.forRoot(routes), PoTableModule], providers: [ + provideLocationMocks(), PoControlPositionService, PoDateService, DecimalPipe, @@ -251,7 +253,7 @@ describe('PoTableComponent:', () => { { provide: PoTableService, useValue: poTableService }, { provide: CdkVirtualScrollViewport, useValue: mockViewPort }, { provide: changeDetector, useValue: changeDetector }, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }).compileComponents(); @@ -3978,4 +3980,35 @@ describe('PoTableComponent:', () => { expect(component.searchAiComponent.search).toHaveBeenCalled(); }); }); + + describe('initializeVisibleElement:', () => { + it('should call debounceResize, checkInfiniteScroll and set visibleElement when wrapper has width and element is not visible', () => { + // Exercita o método REAL do componente de forma determinística, sem depender + // do offsetWidth calculado pelo layout do headless (que oscila e tornava a + // cobertura deste trecho intermitente). + component['tableWrapperElement'] = { nativeElement: { offsetWidth: 100 } } as any; + component['visibleElement'] = false; + spyOn(component, 'debounceResize'); + spyOn(component, 'checkInfiniteScroll'); + + component['initializeVisibleElement'](); + + expect(component['debounceResize']).toHaveBeenCalled(); + expect(component['checkInfiniteScroll']).toHaveBeenCalled(); + expect(component['visibleElement']).toBeTrue(); + }); + + it('should not do anything when wrapper width is 0', () => { + component['tableWrapperElement'] = { nativeElement: { offsetWidth: 0 } } as any; + component['visibleElement'] = false; + spyOn(component, 'debounceResize'); + spyOn(component, 'checkInfiniteScroll'); + + component['initializeVisibleElement'](); + + expect(component['debounceResize']).not.toHaveBeenCalled(); + expect(component['checkInfiniteScroll']).not.toHaveBeenCalled(); + expect(component['visibleElement']).toBeFalse(); + }); + }); }); diff --git a/projects/ui/src/lib/components/po-table/po-table.component.ts b/projects/ui/src/lib/components/po-table/po-table.component.ts index d5b13e64a1..fd5d17b14b 100644 --- a/projects/ui/src/lib/components/po-table/po-table.component.ts +++ b/projects/ui/src/lib/components/po-table/po-table.component.ts @@ -18,7 +18,8 @@ import { TemplateRef, ViewChild, ViewChildren, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { Observable, Subscription } from 'rxjs'; @@ -99,7 +100,7 @@ import { PoFieldSize } from '../../enums/po-field-size.enum'; * * * - * + * * * * @@ -108,6 +109,7 @@ import { PoFieldSize } from '../../enums/po-field-size.enum'; selector: 'po-table', templateUrl: './po-table.component.html', providers: [PoDateService, PoTableService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoTableComponent extends PoTableBaseComponent implements AfterViewInit, DoCheck, OnDestroy, OnInit { diff --git a/projects/ui/src/lib/components/po-table/samples/sample-po-table-airfare/sample-po-table-airfare.component.ts b/projects/ui/src/lib/components/po-table/samples/sample-po-table-airfare/sample-po-table-airfare.component.ts index 8c9abce50b..0933d99901 100644 --- a/projects/ui/src/lib/components/po-table/samples/sample-po-table-airfare/sample-po-table-airfare.component.ts +++ b/projects/ui/src/lib/components/po-table/samples/sample-po-table-airfare/sample-po-table-airfare.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, ViewChild, OnInit } from '@angular/core'; +import { AfterViewInit, Component, ViewChild, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoDialogService, @@ -15,6 +15,7 @@ import { SamplePoTableAirfareService } from './sample-po-table-airfare.service'; selector: 'sample-po-table-airfare', templateUrl: './sample-po-table-airfare.component.html', providers: [SamplePoTableAirfareService, PoDialogService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTableAirfareComponent implements AfterViewInit, OnInit { diff --git a/projects/ui/src/lib/components/po-table/samples/sample-po-table-basic/sample-po-table-basic.component.ts b/projects/ui/src/lib/components/po-table/samples/sample-po-table-basic/sample-po-table-basic.component.ts index 36ee213959..e8341e5383 100644 --- a/projects/ui/src/lib/components/po-table/samples/sample-po-table-basic/sample-po-table-basic.component.ts +++ b/projects/ui/src/lib/components/po-table/samples/sample-po-table-basic/sample-po-table-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-table-basic', templateUrl: './sample-po-table-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTableBasicComponent {} diff --git a/projects/ui/src/lib/components/po-table/samples/sample-po-table-components/sample-po-table-components.component.ts b/projects/ui/src/lib/components/po-table/samples/sample-po-table-components/sample-po-table-components.component.ts index c09d5b2bb4..e689e23a2a 100644 --- a/projects/ui/src/lib/components/po-table/samples/sample-po-table-components/sample-po-table-components.component.ts +++ b/projects/ui/src/lib/components/po-table/samples/sample-po-table-components/sample-po-table-components.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, OnInit } from '@angular/core'; +import { Component, ViewChild, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { Router } from '@angular/router'; import { PoModalComponent, PoTableColumn, PoTableColumnLabel, PoTableColumnSort } from '@po-ui/ng-components'; @@ -11,6 +11,7 @@ import { SamplePoTableComponentsService } from './sample-po-table-components.ser templateUrl: './sample-po-table-components.component.html', styleUrls: ['./sample-po-table-components.component.css'], providers: [SamplePoTableComponentsService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTableComponentsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-table/samples/sample-po-table-draggable/sample-po-table-draggable.component.ts b/projects/ui/src/lib/components/po-table/samples/sample-po-table-draggable/sample-po-table-draggable.component.ts index 5c1df1f765..8ea0df7232 100644 --- a/projects/ui/src/lib/components/po-table/samples/sample-po-table-draggable/sample-po-table-draggable.component.ts +++ b/projects/ui/src/lib/components/po-table/samples/sample-po-table-draggable/sample-po-table-draggable.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-table-draggable', templateUrl: './sample-po-table-draggable.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTableDraggableComponent {} diff --git a/projects/ui/src/lib/components/po-table/samples/sample-po-table-heroes/sample-po-table-heroes.component.ts b/projects/ui/src/lib/components/po-table/samples/sample-po-table-heroes/sample-po-table-heroes.component.ts index beb20f89e0..2216be3af1 100644 --- a/projects/ui/src/lib/components/po-table/samples/sample-po-table-heroes/sample-po-table-heroes.component.ts +++ b/projects/ui/src/lib/components/po-table/samples/sample-po-table-heroes/sample-po-table-heroes.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, OnInit } from '@angular/core'; +import { Component, ViewChild, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoTableColumn, PoTableComponent } from '@po-ui/ng-components'; import { SamplePoTableHeroesService } from './sample-po-table-heroes.service'; @@ -7,6 +7,7 @@ import { SamplePoTableHeroesService } from './sample-po-table-heroes.service'; selector: 'sample-po-table-heroes', templateUrl: './sample-po-table-heroes.component.html', providers: [SamplePoTableHeroesService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTableHeroesComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-table/samples/sample-po-table-labs/sample-po-table-labs.component.ts b/projects/ui/src/lib/components/po-table/samples/sample-po-table-labs/sample-po-table-labs.component.ts index 8201b85c47..d2ee09d06f 100644 --- a/projects/ui/src/lib/components/po-table/samples/sample-po-table-labs/sample-po-table-labs.component.ts +++ b/projects/ui/src/lib/components/po-table/samples/sample-po-table-labs/sample-po-table-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, @@ -17,6 +17,7 @@ import { SamplePoTableLabsService } from './sample-po-table-labs.service'; selector: 'sample-po-table-labs', templateUrl: './sample-po-table-labs.component.html', providers: [SamplePoTableLabsService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTableLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-table/samples/sample-po-table-transport/sample-po-table-transport.component.ts b/projects/ui/src/lib/components/po-table/samples/sample-po-table-transport/sample-po-table-transport.component.ts index 7f5d6dee62..b4d6b1346d 100644 --- a/projects/ui/src/lib/components/po-table/samples/sample-po-table-transport/sample-po-table-transport.component.ts +++ b/projects/ui/src/lib/components/po-table/samples/sample-po-table-transport/sample-po-table-transport.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoSelectOption } from '@po-ui/ng-components'; @@ -10,6 +10,7 @@ import { SamplePoTableTransportService } from './sample-po-table-transport.servi selector: 'sample-po-table-transport', templateUrl: 'sample-po-table-transport.component.html', providers: [SamplePoTableTransportService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTableTransportComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-table/samples/sample-po-table-with-api/sample-po-table-with-api.component.ts b/projects/ui/src/lib/components/po-table/samples/sample-po-table-with-api/sample-po-table-with-api.component.ts index 8fa2a6c835..22786da8f1 100644 --- a/projects/ui/src/lib/components/po-table/samples/sample-po-table-with-api/sample-po-table-with-api.component.ts +++ b/projects/ui/src/lib/components/po-table/samples/sample-po-table-with-api/sample-po-table-with-api.component.ts @@ -1,9 +1,10 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoDisclaimerGroupRemoveAction, PoDisclaimer, PoTableComponent, PoTableColumn } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-table-with-api', templateUrl: './sample-po-table-with-api.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTableWithApiComponent { diff --git a/projects/ui/src/lib/components/po-table/services/po-table.service.spec.ts b/projects/ui/src/lib/components/po-table/services/po-table.service.spec.ts index 1233584769..af342d9b39 100644 --- a/projects/ui/src/lib/components/po-table/services/po-table.service.spec.ts +++ b/projects/ui/src/lib/components/po-table/services/po-table.service.spec.ts @@ -3,7 +3,7 @@ import { provideHttpClientTesting } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; import { PoTableService } from './po-table.service'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; describe('PoTableService', () => { let service: PoTableService; @@ -11,7 +11,7 @@ describe('PoTableService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting(), PoTableService] + providers: [provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting(), PoTableService] }); service = TestBed.inject(PoTableService); }); diff --git a/projects/ui/src/lib/components/po-tabs/po-tab-button/po-tab-button.component.ts b/projects/ui/src/lib/components/po-tabs/po-tab-button/po-tab-button.component.ts index ebfdffa0a0..c3cda503ef 100644 --- a/projects/ui/src/lib/components/po-tabs/po-tab-button/po-tab-button.component.ts +++ b/projects/ui/src/lib/components/po-tabs/po-tab-button/po-tab-button.component.ts @@ -9,7 +9,8 @@ import { Output, SimpleChanges, ViewChild, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { convertToBoolean } from '../../../utils/util'; @@ -24,6 +25,7 @@ import { convertToBoolean } from '../../../utils/util'; @Component({ selector: 'po-tab-button', templateUrl: './po-tab-button.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoTabButtonComponent implements OnChanges, AfterViewInit { diff --git a/projects/ui/src/lib/components/po-tabs/po-tab-dropdown/po-tab-dropdown.component.spec.ts b/projects/ui/src/lib/components/po-tabs/po-tab-dropdown/po-tab-dropdown.component.spec.ts index 2612563427..e6fae280f5 100644 --- a/projects/ui/src/lib/components/po-tabs/po-tab-dropdown/po-tab-dropdown.component.spec.ts +++ b/projects/ui/src/lib/components/po-tabs/po-tab-dropdown/po-tab-dropdown.component.spec.ts @@ -1,6 +1,7 @@ import { ElementRef } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { configureTestSuite } from './../../../util-test/util-expect.spec'; @@ -48,9 +49,9 @@ describe('PoTabDropdownComponent:', () => { configureTestSuite(() => { TestBed.configureTestingModule({ - imports: [PoPopoverModule, RouterTestingModule.withRoutes([])], + imports: [PoPopoverModule, RouterModule.forRoot([])], declarations: [PoTabDropdownComponent], - providers: [{ provide: ElementRef, useValue: buttonElementRefMock }] + providers: [provideLocationMocks(), { provide: ElementRef, useValue: buttonElementRefMock }] }); }); diff --git a/projects/ui/src/lib/components/po-tabs/po-tab-dropdown/po-tab-dropdown.component.ts b/projects/ui/src/lib/components/po-tabs/po-tab-dropdown/po-tab-dropdown.component.ts index 227f6b3f93..f5a21f5554 100644 --- a/projects/ui/src/lib/components/po-tabs/po-tab-dropdown/po-tab-dropdown.component.ts +++ b/projects/ui/src/lib/components/po-tabs/po-tab-dropdown/po-tab-dropdown.component.ts @@ -7,7 +7,8 @@ import { Input, Output, ViewChild, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { PoButtonComponent } from '../../po-button/po-button.component'; @@ -25,6 +26,7 @@ import { PoTabComponent } from '../po-tab/po-tab.component'; @Component({ selector: 'po-tab-dropdown', templateUrl: './po-tab-dropdown.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoTabDropdownComponent implements AfterViewInit { diff --git a/projects/ui/src/lib/components/po-tabs/po-tab/po-tab.base.component.spec.ts b/projects/ui/src/lib/components/po-tabs/po-tab/po-tab.base.component.spec.ts index b7fac3becb..cf0bd65cbc 100644 --- a/projects/ui/src/lib/components/po-tabs/po-tab/po-tab.base.component.spec.ts +++ b/projects/ui/src/lib/components/po-tabs/po-tab/po-tab.base.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { expectPropertiesValues } from '../../../util-test/util-expect.spec'; @@ -7,6 +7,7 @@ import { PoTabBaseComponent } from './po-tab-base.component'; @Component({ template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: true }) class PoTabComponent extends PoTabBaseComponent { diff --git a/projects/ui/src/lib/components/po-tabs/po-tab/po-tab.component.ts b/projects/ui/src/lib/components/po-tabs/po-tab/po-tab.component.ts index f12e0fddb6..558170e75b 100644 --- a/projects/ui/src/lib/components/po-tabs/po-tab/po-tab.component.ts +++ b/projects/ui/src/lib/components/po-tabs/po-tab/po-tab.component.ts @@ -1,4 +1,12 @@ -import { AfterContentInit, Component, ElementRef, OnChanges, SimpleChanges, inject } from '@angular/core'; +import { + AfterContentInit, + Component, + ElementRef, + OnChanges, + SimpleChanges, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { PoTabBaseComponent } from './po-tab-base.component'; import { PoTabsService } from '../po-tabs.service'; @@ -9,6 +17,7 @@ import { PoTabsService } from '../po-tabs.service'; @Component({ selector: 'po-tab', templateUrl: './po-tab.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoTabComponent extends PoTabBaseComponent implements AfterContentInit, OnChanges { diff --git a/projects/ui/src/lib/components/po-tabs/po-tabs.component.ts b/projects/ui/src/lib/components/po-tabs/po-tabs.component.ts index 5b1e3f96eb..d16f488a25 100644 --- a/projects/ui/src/lib/components/po-tabs/po-tabs.component.ts +++ b/projects/ui/src/lib/components/po-tabs/po-tabs.component.ts @@ -10,7 +10,8 @@ import { QueryList, ViewChild, ViewChildren, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { PoLanguageService } from '../../services/po-language/po-language.service'; @@ -89,6 +90,7 @@ const poTabsMaxNumberOfTabs = 5; @Component({ selector: 'po-tabs', templateUrl: './po-tabs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoTabsComponent extends PoTabsBaseComponent implements OnInit, AfterViewInit, OnDestroy, AfterContentInit { diff --git a/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-basic/sample-po-tabs-basic.component.ts b/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-basic/sample-po-tabs-basic.component.ts index b83be82df5..5d31759dae 100644 --- a/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-basic/sample-po-tabs-basic.component.ts +++ b/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-basic/sample-po-tabs-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-tabs-basic', templateUrl: './sample-po-tabs-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTabsBasicComponent {} diff --git a/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-business-conf/sample-po-tabs-business-conf.component.ts b/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-business-conf/sample-po-tabs-business-conf.component.ts index 1f5a87d366..ca014b6fca 100644 --- a/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-business-conf/sample-po-tabs-business-conf.component.ts +++ b/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-business-conf/sample-po-tabs-business-conf.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService, PoTabsComponent } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-tabs-business-conf', templateUrl: './sample-po-tabs-business-conf.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTabsBusinessConfComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-labs/sample-po-tabs-labs.component.ts b/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-labs/sample-po-tabs-labs.component.ts index 1fae06e7d1..3eab081d07 100644 --- a/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-labs/sample-po-tabs-labs.component.ts +++ b/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-labs/sample-po-tabs-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, inject } from '@angular/core'; +import { Component, OnInit, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoDynamicFormField, @@ -11,6 +11,7 @@ import { @Component({ selector: 'sample-po-tabs-labs', templateUrl: './sample-po-tabs-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTabsLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-travel/sample-po-tabs-travel.component.ts b/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-travel/sample-po-tabs-travel.component.ts index 468c0d17d5..ad16f3c521 100644 --- a/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-travel/sample-po-tabs-travel.component.ts +++ b/projects/ui/src/lib/components/po-tabs/samples/sample-po-tabs-travel/sample-po-tabs-travel.component.ts @@ -1,10 +1,11 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService, PoRadioGroupOption, PoSelectOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-tabs-travel', templateUrl: './sample-po-tabs-travel.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTabsTravelComponent { diff --git a/projects/ui/src/lib/components/po-tag/po-tag.component.spec.ts b/projects/ui/src/lib/components/po-tag/po-tag.component.spec.ts index a4083c28e1..d0c5a36052 100644 --- a/projects/ui/src/lib/components/po-tag/po-tag.component.spec.ts +++ b/projects/ui/src/lib/components/po-tag/po-tag.component.spec.ts @@ -1,4 +1,4 @@ -import { Component, provideNgReflectAttributes } from '@angular/core'; +import { Component, provideNgReflectAttributes, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, fakeAsync, flush, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; @@ -16,6 +16,7 @@ import { PoTagLiterals } from './po-tag.literals'; @Component({ template: ` `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class PoTagClickableComponent { @@ -376,6 +377,7 @@ describe('PoTagComponent:', () => { }); function mockGetComputedStyle(backgroundColor: string) { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(window, 'getComputedStyle').and.returnValue({ backgroundColor: backgroundColor, getPropertyValue: (token: string) => { diff --git a/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-bank-account/sample-po-tag-bank-account.component.ts b/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-bank-account/sample-po-tag-bank-account.component.ts index 2183d7df14..d8b643c088 100644 --- a/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-bank-account/sample-po-tag-bank-account.component.ts +++ b/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-bank-account/sample-po-tag-bank-account.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-tag-bank-account', templateUrl: './sample-po-tag-bank-account.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTagBankAccountComponent { diff --git a/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-basic/sample-po-tag-basic.component.ts b/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-basic/sample-po-tag-basic.component.ts index 15975cc364..e5ca8d5285 100644 --- a/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-basic/sample-po-tag-basic.component.ts +++ b/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-basic/sample-po-tag-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-tag-basic', templateUrl: './sample-po-tag-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTagBasicComponent {} diff --git a/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-caption-tag-colors/sample-po-tag-caption-tag-colors.component.ts b/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-caption-tag-colors/sample-po-tag-caption-tag-colors.component.ts index a21b321266..dc3a1b6c79 100644 --- a/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-caption-tag-colors/sample-po-tag-caption-tag-colors.component.ts +++ b/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-caption-tag-colors/sample-po-tag-caption-tag-colors.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-tag-caption-tag-colors', templateUrl: './sample-po-tag-caption-tag-colors.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTagCaptionTagColorsComponent { diff --git a/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-labs/sample-po-tag-labs.component.ts b/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-labs/sample-po-tag-labs.component.ts index a37775bff0..d7309b69ef 100644 --- a/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-labs/sample-po-tag-labs.component.ts +++ b/projects/ui/src/lib/components/po-tag/samples/sample-po-tag-labs/sample-po-tag-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoRadioGroupOption, @@ -12,6 +12,7 @@ import { selector: 'sample-po-tag-labs', templateUrl: './sample-po-tag-labs.component.html', styleUrls: ['./sample-po-tag-labs.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTagLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-timer/po-timer.component.spec.ts b/projects/ui/src/lib/components/po-timer/po-timer.component.spec.ts index 988ecdbcd1..a178d530ba 100644 --- a/projects/ui/src/lib/components/po-timer/po-timer.component.spec.ts +++ b/projects/ui/src/lib/components/po-timer/po-timer.component.spec.ts @@ -2372,7 +2372,7 @@ describe('PoTimerComponent:', () => { component['buildDisplayArrays'](); component['focusedDisplayIndex']['hour'] = 0; - expect(() => component['selectFocusedItem']('period' as any)).not.toThrow(); + expect(() => component['selectFocusedItem']('period')).not.toThrow(); }); }); diff --git a/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-alarm/sample-po-timer-alarm.component.ts b/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-alarm/sample-po-timer-alarm.component.ts index 27d8aa1c0a..eafd6cdc3b 100644 --- a/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-alarm/sample-po-timer-alarm.component.ts +++ b/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-alarm/sample-po-timer-alarm.component.ts @@ -1,10 +1,11 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-timer-alarm', templateUrl: './sample-po-timer-alarm.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTimerAlarmComponent { diff --git a/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-basic/sample-po-timer-basic.component.ts b/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-basic/sample-po-timer-basic.component.ts index aaae64e849..01e24cf217 100644 --- a/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-basic/sample-po-timer-basic.component.ts +++ b/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-basic/sample-po-timer-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-timer-basic', templateUrl: './sample-po-timer-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTimerBasicComponent {} diff --git a/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-labs/sample-po-timer-labs.component.ts b/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-labs/sample-po-timer-labs.component.ts index fd9093a5b5..465ca5243c 100644 --- a/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-labs/sample-po-timer-labs.component.ts +++ b/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-labs/sample-po-timer-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-timer-labs', templateUrl: './sample-po-timer-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTimerLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-shift/sample-po-timer-shift.component.ts b/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-shift/sample-po-timer-shift.component.ts index bfee83715c..eba2fdbd3e 100644 --- a/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-shift/sample-po-timer-shift.component.ts +++ b/projects/ui/src/lib/components/po-timer/samples/sample-po-timer-shift/sample-po-timer-shift.component.ts @@ -1,10 +1,11 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService, PoRadioGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-timer-shift', templateUrl: './sample-po-timer-shift.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTimerShiftComponent { diff --git a/projects/ui/src/lib/components/po-toaster/po-toaster.component.ts b/projects/ui/src/lib/components/po-toaster/po-toaster.component.ts index 8016dcd946..312d868e54 100644 --- a/projects/ui/src/lib/components/po-toaster/po-toaster.component.ts +++ b/projects/ui/src/lib/components/po-toaster/po-toaster.component.ts @@ -8,7 +8,8 @@ import { Renderer2, SimpleChanges, ViewChild, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { Subject } from 'rxjs'; @@ -41,6 +42,7 @@ const SPACE_BETWEEN_TOASTERS = 8; @Component({ selector: 'po-toaster', templateUrl: './po-toaster.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoToasterComponent extends PoToasterBaseComponent implements AfterViewInit, OnDestroy, OnChanges { diff --git a/projects/ui/src/lib/components/po-toaster/samples/sample-po-toaster-basic/sample-po-toaster-basic.component.ts b/projects/ui/src/lib/components/po-toaster/samples/sample-po-toaster-basic/sample-po-toaster-basic.component.ts index 876f0b4051..31fe1b65ec 100644 --- a/projects/ui/src/lib/components/po-toaster/samples/sample-po-toaster-basic/sample-po-toaster-basic.component.ts +++ b/projects/ui/src/lib/components/po-toaster/samples/sample-po-toaster-basic/sample-po-toaster-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-toaster-basic', templateUrl: './sample-po-toaster-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoToasterBasicComponent {} diff --git a/projects/ui/src/lib/components/po-toaster/samples/sample-po-toaster-labs/sample-po-toaster-labs.component.ts b/projects/ui/src/lib/components/po-toaster/samples/sample-po-toaster-labs/sample-po-toaster-labs.component.ts index 498bba224b..070128bc4b 100644 --- a/projects/ui/src/lib/components/po-toaster/samples/sample-po-toaster-labs/sample-po-toaster-labs.component.ts +++ b/projects/ui/src/lib/components/po-toaster/samples/sample-po-toaster-labs/sample-po-toaster-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoModalComponent, @@ -11,6 +11,7 @@ import { @Component({ selector: 'sample-po-toaster-labs', templateUrl: './sample-po-toaster-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoToasterLabsComponent { diff --git a/projects/ui/src/lib/components/po-toolbar/po-toolbar-actions/po-toolbar-actions.component.ts b/projects/ui/src/lib/components/po-toolbar/po-toolbar-actions/po-toolbar-actions.component.ts index a7236bb2e8..ac34740a0d 100644 --- a/projects/ui/src/lib/components/po-toolbar/po-toolbar-actions/po-toolbar-actions.component.ts +++ b/projects/ui/src/lib/components/po-toolbar/po-toolbar-actions/po-toolbar-actions.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, TemplateRef } from '@angular/core'; +import { Component, Input, TemplateRef, ChangeDetectionStrategy } from '@angular/core'; import { isTypeof } from '../../../utils/util'; @@ -18,6 +18,7 @@ const poToolbarActionsIconDefault = 'ICON_MORE'; @Component({ selector: 'po-toolbar-actions', templateUrl: './po-toolbar-actions.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoToolbarActionsComponent { diff --git a/projects/ui/src/lib/components/po-toolbar/po-toolbar-notification/po-toolbar-notification.component.spec.ts b/projects/ui/src/lib/components/po-toolbar/po-toolbar-notification/po-toolbar-notification.component.spec.ts index 10eeca420d..2a6b511454 100644 --- a/projects/ui/src/lib/components/po-toolbar/po-toolbar-notification/po-toolbar-notification.component.spec.ts +++ b/projects/ui/src/lib/components/po-toolbar/po-toolbar-notification/po-toolbar-notification.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { ChangeDetectorRef, ElementRef, NO_ERRORS_SCHEMA, Renderer2 } from '@angular/core'; -import { RouterTestingModule } from '@angular/router/testing'; import { configureTestSuite, expectPropertiesValues } from '../../../util-test/util-expect.spec'; @@ -25,10 +26,11 @@ describe('PoToolbarNotificationComponent: ', () => { }; TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([])], + imports: [RouterModule.forRoot([])], declarations: [PoToolbarNotificationComponent, PoPopupComponent], schemas: [NO_ERRORS_SCHEMA], providers: [ + provideLocationMocks(), { provide: ElementRef, useValue: { elementRef } }, { provide: Renderer2, useValue: renderer2 }, { provide: PoControlPositionService, useValue: poControlPositionService } diff --git a/projects/ui/src/lib/components/po-toolbar/po-toolbar-notification/po-toolbar-notification.component.ts b/projects/ui/src/lib/components/po-toolbar/po-toolbar-notification/po-toolbar-notification.component.ts index 38fbf0459a..666d8ce715 100644 --- a/projects/ui/src/lib/components/po-toolbar/po-toolbar-notification/po-toolbar-notification.component.ts +++ b/projects/ui/src/lib/components/po-toolbar/po-toolbar-notification/po-toolbar-notification.component.ts @@ -1,4 +1,13 @@ -import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, Input, ViewChild, inject } from '@angular/core'; +import { + AfterViewInit, + ChangeDetectorRef, + Component, + ElementRef, + Input, + ViewChild, + inject, + ChangeDetectionStrategy +} from '@angular/core'; import { PoControlPositionService } from '../../../services/po-control-position/po-control-position.service'; @@ -21,6 +30,7 @@ import { PoToolbarAction } from '../po-toolbar-action.interface'; selector: 'po-toolbar-notification', templateUrl: './po-toolbar-notification.component.html', providers: [PoControlPositionService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoToolbarNotificationComponent implements AfterViewInit { diff --git a/projects/ui/src/lib/components/po-toolbar/po-toolbar-profile/po-toolbar-profile.component.spec.ts b/projects/ui/src/lib/components/po-toolbar/po-toolbar-profile/po-toolbar-profile.component.spec.ts index be263eebc0..b0471c504d 100644 --- a/projects/ui/src/lib/components/po-toolbar/po-toolbar-profile/po-toolbar-profile.component.spec.ts +++ b/projects/ui/src/lib/components/po-toolbar/po-toolbar-profile/po-toolbar-profile.component.spec.ts @@ -1,6 +1,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { ElementRef, NO_ERRORS_SCHEMA, Renderer2 } from '@angular/core'; -import { RouterTestingModule } from '@angular/router/testing'; import { configureTestSuite } from './../../../util-test/util-expect.spec'; @@ -25,10 +26,11 @@ describe('PoToolbarProfileComponent:', () => { }; TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([])], + imports: [RouterModule.forRoot([])], declarations: [PoToolbarProfileComponent, PoPopupComponent], schemas: [NO_ERRORS_SCHEMA], providers: [ + provideLocationMocks(), { provide: ElementRef, useValue: elementRef }, { provide: Renderer2, useValue: renderer2 }, { provide: PoControlPositionService, useValue: poControlPositionService } diff --git a/projects/ui/src/lib/components/po-toolbar/po-toolbar-profile/po-toolbar-profile.component.ts b/projects/ui/src/lib/components/po-toolbar/po-toolbar-profile/po-toolbar-profile.component.ts index 36f9638feb..e15bde34ab 100644 --- a/projects/ui/src/lib/components/po-toolbar/po-toolbar-profile/po-toolbar-profile.component.ts +++ b/projects/ui/src/lib/components/po-toolbar/po-toolbar-profile/po-toolbar-profile.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; import { PoControlPositionService } from '../../../services/po-control-position/po-control-position.service'; @@ -18,6 +18,7 @@ import { PoToolbarAction } from '../po-toolbar-action.interface'; selector: 'po-toolbar-profile', templateUrl: './po-toolbar-profile.component.html', providers: [PoControlPositionService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoToolbarProfileComponent { diff --git a/projects/ui/src/lib/components/po-toolbar/po-toolbar.component.spec.ts b/projects/ui/src/lib/components/po-toolbar/po-toolbar.component.spec.ts index 16eaf6919d..bc84a79b18 100644 --- a/projects/ui/src/lib/components/po-toolbar/po-toolbar.component.spec.ts +++ b/projects/ui/src/lib/components/po-toolbar/po-toolbar.component.spec.ts @@ -1,5 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; +import { provideLocationMocks } from '@angular/common/testing'; +import { RouterModule } from '@angular/router'; import { configureTestSuite } from './../../util-test/util-expect.spec'; @@ -13,7 +14,8 @@ describe('PoToolbarComponent:', () => { configureTestSuite(() => { TestBed.configureTestingModule({ - imports: [RouterTestingModule.withRoutes([]), PoToolbarModule] + imports: [RouterModule.forRoot([]), PoToolbarModule], + providers: [provideLocationMocks()] }); }); diff --git a/projects/ui/src/lib/components/po-toolbar/po-toolbar.component.ts b/projects/ui/src/lib/components/po-toolbar/po-toolbar.component.ts index 1354266fed..bbe80da884 100644 --- a/projects/ui/src/lib/components/po-toolbar/po-toolbar.component.ts +++ b/projects/ui/src/lib/components/po-toolbar/po-toolbar.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewContainerRef, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { PoToolbarBaseComponent } from './po-toolbar-base.component'; @@ -26,6 +26,7 @@ import { PoToolbarBaseComponent } from './po-toolbar-base.component'; @Component({ selector: 'po-toolbar', templateUrl: './po-toolbar.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoToolbarComponent extends PoToolbarBaseComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-basic/sample-po-toolbar-basic.component.ts b/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-basic/sample-po-toolbar-basic.component.ts index e87e4add6a..52bf6f0a5b 100644 --- a/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-basic/sample-po-toolbar-basic.component.ts +++ b/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-basic/sample-po-toolbar-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-toolbar-basic', templateUrl: './sample-po-toolbar-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoToolbarBasicComponent {} diff --git a/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-labs/sample-po-toolbar-labs.component.ts b/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-labs/sample-po-toolbar-labs.component.ts index f2279e44e1..9ffca2a3a1 100644 --- a/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-labs/sample-po-toolbar-labs.component.ts +++ b/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-labs/sample-po-toolbar-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { @@ -12,6 +12,7 @@ import { @Component({ selector: 'sample-po-toolbar-labs', templateUrl: './sample-po-toolbar-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoToolbarLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-logged/sample-po-toolbar-logged.component.ts b/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-logged/sample-po-toolbar-logged.component.ts index f684d541ed..4a6aebe191 100644 --- a/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-logged/sample-po-toolbar-logged.component.ts +++ b/projects/ui/src/lib/components/po-toolbar/samples/sample-po-toolbar-logged/sample-po-toolbar-logged.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoDialogService, PoNotificationService, PoToolbarAction, PoToolbarProfile } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoDialogService, PoNotificationService, PoToolbarAction, PoToolbarProfi selector: 'sample-po-toolbar-logged', templateUrl: './sample-po-toolbar-logged.component.html', providers: [PoNotificationService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoToolbarLoggedComponent { diff --git a/projects/ui/src/lib/components/po-tree-view/po-tree-view-base.component.spec.ts b/projects/ui/src/lib/components/po-tree-view/po-tree-view-base.component.spec.ts index 5b2c76e08a..e71e26815b 100644 --- a/projects/ui/src/lib/components/po-tree-view/po-tree-view-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-tree-view/po-tree-view-base.component.spec.ts @@ -496,12 +496,14 @@ describe('PoTreeViewBaseComponent:', () => { { label: 'B', value: 2, selected: false, disabled: true } ]; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion expect(component['everyItemSelected'](items as any)).toBe(true); }); it('everyItemSelected: should return false when there are no selectable items', () => { const items = [{ label: 'A', value: 1, selected: false, disabled: true }]; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion expect(component['everyItemSelected'](items as any)).toBe(false); }); @@ -756,18 +758,21 @@ describe('PoTreeViewBaseComponent:', () => { { label: 'C', value: 3, selected: true } ]; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion expect(component['getLastSelectedFinalItemValue'](items as any)).toBe(3); }); it('should return a nested final value when only a child is selected', () => { const items = [{ label: 'A', value: 1, subItems: [{ label: 'B', value: 2, selected: true }] }]; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion expect(component['getLastSelectedFinalItemValue'](items as any)).toBe(2); }); it('should return undefined when no final item is selected', () => { const items = [{ label: 'A', value: 1, subItems: [{ label: 'B', value: 2, selected: false }] }]; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion expect(component['getLastSelectedFinalItemValue'](items as any)).toBeUndefined(); }); diff --git a/projects/ui/src/lib/components/po-tree-view/po-tree-view.module.ts b/projects/ui/src/lib/components/po-tree-view/po-tree-view.module.ts index fd15b90297..40ce00c985 100644 --- a/projects/ui/src/lib/components/po-tree-view/po-tree-view.module.ts +++ b/projects/ui/src/lib/components/po-tree-view/po-tree-view.module.ts @@ -17,6 +17,7 @@ import { PoTreeViewItemContentComponent } from './po-tree-view-item-content/po-t * @description * * Módulo do componente `po-tree-view`. + * */ @NgModule({ declarations: [PoTreeViewComponent, PoTreeViewItemComponent, PoTreeViewItemContentComponent], diff --git a/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-basic/sample-po-tree-view-basic.component.ts b/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-basic/sample-po-tree-view-basic.component.ts index 36dbf847a6..c2d89d69b3 100644 --- a/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-basic/sample-po-tree-view-basic.component.ts +++ b/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-basic/sample-po-tree-view-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-tree-view-basic', templateUrl: 'sample-po-tree-view-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTreeViewBasicComponent {} diff --git a/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-folder-structure/sample-po-tree-view-folder-structure.component.ts b/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-folder-structure/sample-po-tree-view-folder-structure.component.ts index bca5b77a1f..ff811f1959 100644 --- a/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-folder-structure/sample-po-tree-view-folder-structure.component.ts +++ b/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-folder-structure/sample-po-tree-view-folder-structure.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoTreeViewItem } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-tree-view-folder-structure', templateUrl: 'sample-po-tree-view-folder-structure.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTreeViewFolderStructureComponent { diff --git a/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-labs/sample-po-tree-view-labs.component.ts b/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-labs/sample-po-tree-view-labs.component.ts index ad2bb488ad..6a7e516ad2 100644 --- a/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-labs/sample-po-tree-view-labs.component.ts +++ b/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-labs/sample-po-tree-view-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { NgForm } from '@angular/forms'; import { PoCheckboxGroupOption, PoRadioGroupOption, PoSelectOption, PoTreeViewItem } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoCheckboxGroupOption, PoRadioGroupOption, PoSelectOption, PoTreeViewIt @Component({ selector: 'sample-po-tree-view-labs', templateUrl: 'sample-po-tree-view-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTreeViewLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-supermarket/sample-po-tree-view-supermarket.component.ts b/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-supermarket/sample-po-tree-view-supermarket.component.ts index f6b1867129..8c0966d034 100644 --- a/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-supermarket/sample-po-tree-view-supermarket.component.ts +++ b/projects/ui/src/lib/components/po-tree-view/samples/sample-po-tree-view-supermarket/sample-po-tree-view-supermarket.component.ts @@ -1,10 +1,11 @@ -import { Component, ViewChild } from '@angular/core'; +import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoStepperComponent, PoTableColumn, PoTreeViewItem } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-tree-view-supermarket', templateUrl: 'sample-po-tree-view-supermarket.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTreeViewSupermarketComponent { diff --git a/projects/ui/src/lib/components/po-widget/po-widget-base.component.spec.ts b/projects/ui/src/lib/components/po-widget/po-widget-base.component.spec.ts index 06ee6723f3..a24f056e51 100644 --- a/projects/ui/src/lib/components/po-widget/po-widget-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-widget/po-widget-base.component.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { PoWidgetBaseComponent } from './po-widget-base.component'; @@ -8,6 +8,7 @@ import { PoThemeA11yEnum } from '../../services'; @Component({ template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: true }) class TestComponent extends PoWidgetBaseComponent {} diff --git a/projects/ui/src/lib/components/po-widget/po-widget-base.component.ts b/projects/ui/src/lib/components/po-widget/po-widget-base.component.ts index 4c4a5147d9..266befcde3 100644 --- a/projects/ui/src/lib/components/po-widget/po-widget-base.component.ts +++ b/projects/ui/src/lib/components/po-widget/po-widget-base.component.ts @@ -49,7 +49,6 @@ const PO_WIDGET_TAG_POSITION_DEFAULT = 'right'; * | `--font-size` | Tamanho da fonte | `var(--font-size-sm)` | * | `--font-weight` | Peso da fonte | `var(--font-weight-bold)` | * | `--font-color` | Cor da fonte | `var(--color-neutral-dark-95)` | - * | `--padding` - `@deprecated 21.x.x` | Preenchimento do componente | `1rem` | * | `--padding-header` | Preenchimento do header | `var(--spacing-sm) var(--spacing-sm) var(--spacing-xs) var(--spacing-sm)` | * | `--padding-body` | Preenchimento do body | `var(--spacing-xs) var(--spacing-sm) var(--spacing-xs) var(--spacing-sm)` | * | `--padding-avatar` | Preenchimento do avatar | `var(--spacing-sm) 0 var(--spacing-xs) var(--spacing-sm)` | diff --git a/projects/ui/src/lib/components/po-widget/po-widget.component.ts b/projects/ui/src/lib/components/po-widget/po-widget.component.ts index affbec0fe8..a3aeea4bf0 100644 --- a/projects/ui/src/lib/components/po-widget/po-widget.component.ts +++ b/projects/ui/src/lib/components/po-widget/po-widget.component.ts @@ -8,7 +8,8 @@ import { SimpleChanges, ViewChild, computed, - inject + inject, + ChangeDetectionStrategy } from '@angular/core'; import { PoLanguageService, poLocaleDefault, PoThemeA11yEnum, PoThemeService } from '../../services'; @@ -57,6 +58,7 @@ import { @Component({ selector: 'po-widget', templateUrl: './po-widget.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoWidgetComponent extends PoWidgetBaseComponent implements OnInit, OnChanges, AfterViewInit { diff --git a/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-basic/sample-po-widget-basic.component.ts b/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-basic/sample-po-widget-basic.component.ts index 30c33d565f..a30f808fc1 100644 --- a/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-basic/sample-po-widget-basic.component.ts +++ b/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-basic/sample-po-widget-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-widget-basic', templateUrl: './sample-po-widget-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoWidgetBasicComponent {} diff --git a/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-card/sample-po-widget-card.component.ts b/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-card/sample-po-widget-card.component.ts index d29440371c..49bde0ebee 100644 --- a/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-card/sample-po-widget-card.component.ts +++ b/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-card/sample-po-widget-card.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoModalComponent } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-widget-card', templateUrl: './sample-po-widget-card.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoWidgetCardComponent implements OnInit { diff --git a/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-finance-dashboard/sample-po-widget-finance-dashboard.component.ts b/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-finance-dashboard/sample-po-widget-finance-dashboard.component.ts index 2a0f9f5694..090b2efafb 100644 --- a/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-finance-dashboard/sample-po-widget-finance-dashboard.component.ts +++ b/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-finance-dashboard/sample-po-widget-finance-dashboard.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, inject } from '@angular/core'; +import { Component, ViewChild, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoModalComponent, PoMultiselectOption, PoNotificationService, PoTableColumn } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoModalComponent, PoMultiselectOption, PoNotificationService, PoTableCo selector: 'sample-po-widget-finance-dashboard', templateUrl: './sample-po-widget-finance-dashboard.component.html', styleUrls: ['./sample-po-widget-finance-dashboard.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoWidgetFinanceDashboardComponent { diff --git a/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-labs/sample-po-widget-labs.component.ts b/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-labs/sample-po-widget-labs.component.ts index 095bd3adfc..b8483f9989 100644 --- a/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-labs/sample-po-widget-labs.component.ts +++ b/projects/ui/src/lib/components/po-widget/samples/sample-po-widget-labs/sample-po-widget-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, inject } from '@angular/core'; +import { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoNotificationService, PoPopupAction, PoSelectOption } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoCheckboxGroupOption, PoNotificationService, PoPopupAction, PoSelectOp selector: 'sample-po-widget-labs', templateUrl: './sample-po-widget-labs.component.html', styleUrls: ['./sample-po-widget-labs.component.css'], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoWidgetLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/decorators/input-boolean/input-boolean.decorator.spec.ts b/projects/ui/src/lib/decorators/input-boolean/input-boolean.decorator.spec.ts index 71372dd7ca..15628fdba0 100644 --- a/projects/ui/src/lib/decorators/input-boolean/input-boolean.decorator.spec.ts +++ b/projects/ui/src/lib/decorators/input-boolean/input-boolean.decorator.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { configureTestSuite, expectPropertiesValues } from '../../util-test/util-expect.spec'; @@ -7,6 +7,7 @@ import { InputBoolean } from './input-boolean.decorator'; @Component({ selector: 'mock-component', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class PoMockComponent { diff --git a/projects/ui/src/lib/decorators/input-required/input-required.decorator.spec.ts b/projects/ui/src/lib/decorators/input-required/input-required.decorator.spec.ts index 6cea570ba5..f4f558e4d7 100644 --- a/projects/ui/src/lib/decorators/input-required/input-required.decorator.spec.ts +++ b/projects/ui/src/lib/decorators/input-required/input-required.decorator.spec.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { configureTestSuite } from '../../util-test/util-expect.spec'; @@ -7,6 +7,7 @@ import { InputRequired } from './input-required.decorator'; @Component({ selector: 'mock-component', template: '', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class PoMockComponent implements OnInit { @@ -33,7 +34,7 @@ describe('InputRequired:', () => { it('should call console.warn if `myProperty` is null', () => { spyOn(console, 'warn'); - const consoleMessage = 'PoMockComponent: myProperty is required, but was not provided'; + const consoleMessage = `${component.constructor.name}: myProperty is required, but was not provided`; component.ngOnInit(); diff --git a/projects/ui/src/lib/directives/po-drag-drop/po-drag-base.directive.spec.ts b/projects/ui/src/lib/directives/po-drag-drop/po-drag-base.directive.spec.ts index 864b39ea72..8d6ceb08a0 100644 --- a/projects/ui/src/lib/directives/po-drag-drop/po-drag-base.directive.spec.ts +++ b/projects/ui/src/lib/directives/po-drag-drop/po-drag-base.directive.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; @@ -24,8 +24,10 @@ interface TestItem { standalone: false }) class TestHostComponent { - item: TestItem = { id: '1', name: 'test' }; - disabled = false; + // Inputs do host para permitir atualização via fixture.componentRef.setInput, + // que é o mecanismo suportado para refletir mudanças de binding no ambiente de teste (Angular 22). + @Input() item: TestItem = { id: '1', name: 'test' }; + @Input() disabled = false; startedItem: TestItem | null = null; endedItem: TestItem | null = null; movedEvent: any = null; @@ -84,19 +86,19 @@ describe('PoDragBaseDirective (via PoDragDirective)', () => { }); it('should reflect changes when input item is updated', () => { - component.item = { id: '99', name: 'changed' }; + fixture.componentRef.setInput('item', { id: '99', name: 'changed' }); fixture.detectChanges(); expect(directive.data()).toEqual(jasmine.objectContaining({ id: '99', name: 'changed' })); }); it('should accept undefined as data value', () => { - component.item = undefined; + fixture.componentRef.setInput('item', undefined); fixture.detectChanges(); expect(directive.data()).toBeUndefined(); }); it('should accept null as data value', () => { - component.item = null; + fixture.componentRef.setInput('item', null); fixture.detectChanges(); expect(directive.data()).toBeNull(); }); @@ -108,15 +110,15 @@ describe('PoDragBaseDirective (via PoDragDirective)', () => { }); it('should read `dragDisabled` signal as true when bound to true', () => { - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); expect(directive.dragDisabled()).toBeTrue(); }); it('should toggle dragDisabled back to false', () => { - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); - component.disabled = false; + fixture.componentRef.setInput('disabled', false); fixture.detectChanges(); expect(directive.dragDisabled()).toBeFalse(); }); @@ -137,7 +139,7 @@ describe('PoDragBaseDirective (via PoDragDirective)', () => { it('should emit updated item data after input change', () => { const newItem: TestItem = { id: '5', name: 'new item' }; - component.item = newItem; + fixture.componentRef.setInput('item', newItem); fixture.detectChanges(); directive.dragStarted.emit(directive.data()); expect(component.startedItem).toEqual(newItem); diff --git a/projects/ui/src/lib/directives/po-drag-drop/po-drag.directive.spec.ts b/projects/ui/src/lib/directives/po-drag-drop/po-drag.directive.spec.ts index 5b43e5c6fa..8ceda476c3 100644 --- a/projects/ui/src/lib/directives/po-drag-drop/po-drag.directive.spec.ts +++ b/projects/ui/src/lib/directives/po-drag-drop/po-drag.directive.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { CdkDrag } from '@angular/cdk/drag-drop'; @@ -25,8 +25,10 @@ interface TestItem { standalone: false }) class TestHostComponent { - item: TestItem = { id: '1', name: 'test' }; - disabled = false; + // Inputs do host para permitir atualização via fixture.componentRef.setInput, + // que é o mecanismo suportado para refletir mudanças de binding no ambiente de teste (Angular 22). + @Input() item: TestItem = { id: '1', name: 'test' }; + @Input() disabled = false; startedItem: TestItem | null = null; endedItem: TestItem | null = null; movedEvent: any = null; @@ -63,7 +65,7 @@ class TestDisabledHostComponent { class TestDropListHostComponent { item: TestItem = { id: '1', name: 'test' }; items: Array = [{ id: '1', name: 'test' }]; - dropListDisabled = false; + @Input() dropListDisabled = false; } describe('PoDragDirective', () => { @@ -95,7 +97,7 @@ describe('PoDragDirective', () => { it('should update `data` signal when input changes', () => { const newItem: TestItem = { id: '2', name: 'updated' }; - component.item = newItem; + fixture.componentRef.setInput('item', newItem); fixture.detectChanges(); expect(directive.data()).toEqual(newItem); }); @@ -105,7 +107,7 @@ describe('PoDragDirective', () => { }); it('should read `dragDisabled` signal as true when disabled is set', () => { - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); expect(directive.dragDisabled()).toBeTrue(); }); @@ -141,16 +143,16 @@ describe('PoDragDirective', () => { }); it('should remove po-drag-drop-item class when disabled', () => { - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); const hostEl = fixture.debugElement.query(By.directive(PoDragDirective)).nativeElement; expect(hostEl.classList.contains('po-drag-drop-item')).toBeFalse(); }); it('should add po-drag-drop-item class back when re-enabled', () => { - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); - component.disabled = false; + fixture.componentRef.setInput('disabled', false); fixture.detectChanges(); const hostEl = fixture.debugElement.query(By.directive(PoDragDirective)).nativeElement; expect(hostEl.classList.contains('po-drag-drop-item')).toBeTrue(); @@ -175,7 +177,7 @@ describe('PoDragDirective', () => { }); it('should remove handle when drag is disabled', () => { - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); const hostEl = fixture.debugElement.query(By.directive(PoDragDirective)).nativeElement; const handle = hostEl.querySelector('po-drag-handle-button'); @@ -183,9 +185,9 @@ describe('PoDragDirective', () => { }); it('should re-append handle when drag is re-enabled', () => { - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); - component.disabled = false; + fixture.componentRef.setInput('disabled', false); fixture.detectChanges(); const hostEl = fixture.debugElement.query(By.directive(PoDragDirective)).nativeElement; const handle = hostEl.querySelector('po-drag-handle-button'); @@ -201,7 +203,7 @@ describe('PoDragDirective', () => { it('should update cdkDrag.data when input changes', () => { const newItem: TestItem = { id: '3', name: 'new' }; - component.item = newItem; + fixture.componentRef.setInput('item', newItem); fixture.detectChanges(); const cdkDrag = fixture.debugElement.query(By.directive(CdkDrag)).injector.get(CdkDrag); expect(cdkDrag.data).toEqual(newItem); @@ -317,7 +319,7 @@ describe('PoDragDirective', () => { describe('parent drop list disabled', () => { it('should not append handle when parent drop list is disabled', () => { const dropListFixture = TestBed.createComponent(TestDropListHostComponent); - dropListFixture.componentInstance.dropListDisabled = true; + dropListFixture.componentRef.setInput('dropListDisabled', true); dropListFixture.detectChanges(); const hostEl = dropListFixture.debugElement.query(By.directive(PoDragDirective)).nativeElement; @@ -334,7 +336,7 @@ describe('PoDragDirective', () => { it('should remove po-drag-drop-item class when parent drop list is disabled', () => { const dropListFixture = TestBed.createComponent(TestDropListHostComponent); - dropListFixture.componentInstance.dropListDisabled = true; + dropListFixture.componentRef.setInput('dropListDisabled', true); dropListFixture.detectChanges(); const hostEl = dropListFixture.debugElement.query(By.directive(PoDragDirective)).nativeElement; @@ -355,11 +357,11 @@ describe('PoDragDirective', () => { const hostEl = dropListFixture.debugElement.query(By.directive(PoDragDirective)).nativeElement; expect(hostEl.querySelector('po-drag-handle-button')).toBeTruthy(); - dropListFixture.componentInstance.dropListDisabled = true; + dropListFixture.componentRef.setInput('dropListDisabled', true); dropListFixture.detectChanges(); expect(hostEl.querySelector('po-drag-handle-button')).toBeNull(); - dropListFixture.componentInstance.dropListDisabled = false; + dropListFixture.componentRef.setInput('dropListDisabled', false); dropListFixture.detectChanges(); expect(hostEl.querySelector('po-drag-handle-button')).toBeTruthy(); }); @@ -371,18 +373,18 @@ describe('PoDragDirective', () => { expect(hostEl.querySelector('po-drag-handle-button')).toBeTruthy(); // Disabling destroys the handle - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); expect(hostEl.querySelector('po-drag-handle-button')).toBeNull(); // Re-enabling appends the handle again - component.disabled = false; + fixture.componentRef.setInput('disabled', false); fixture.detectChanges(); expect(hostEl.querySelector('po-drag-handle-button')).toBeTruthy(); }); it('should not append handle while dragDisabled is true', () => { - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); const hostEl = fixture.debugElement.query(By.directive(PoDragDirective)).nativeElement; diff --git a/projects/ui/src/lib/directives/po-drag-drop/po-drop-list-base.directive.spec.ts b/projects/ui/src/lib/directives/po-drag-drop/po-drop-list-base.directive.spec.ts index ec4dc0408b..f32e33c49d 100644 --- a/projects/ui/src/lib/directives/po-drag-drop/po-drop-list-base.directive.spec.ts +++ b/projects/ui/src/lib/directives/po-drag-drop/po-drop-list-base.directive.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; @@ -27,15 +27,17 @@ interface TestItem { standalone: false }) class TestHostComponent { - items: Array = [ + // Inputs do host para permitir atualização via fixture.componentRef.setInput, + // que é o mecanismo suportado para refletir mudanças de binding no ambiente de teste (Angular 22). + @Input() items: Array = [ { id: '1', value: 10 }, { id: '2', value: 20 } ]; - listId = 'test-list'; - disabled = false; - orientation: 'horizontal' | 'vertical' | 'mixed' = 'vertical'; - connectedTo: Array = []; - sortingDisabled = false; + @Input() listId = 'test-list'; + @Input() disabled = false; + @Input() orientation: 'horizontal' | 'vertical' | 'mixed' = 'vertical'; + @Input() connectedTo: Array = []; + @Input() sortingDisabled = false; droppedEvent: PoDropEvent | null = null; enteredEvent: PoDragEnterEvent | null = null; @@ -89,14 +91,14 @@ describe('PoDropListBaseDirective (via PoDropListDirective)', () => { }); it('should update items when bound array changes', () => { - component.items = [{ id: '3', value: 30 }]; + fixture.componentRef.setInput('items', [{ id: '3', value: 30 }]); fixture.detectChanges(); expect(directive.items()).toHaveSize(1); expect(directive.items()[0]).toEqual(jasmine.objectContaining({ id: '3', value: 30 })); }); it('should accept empty array', () => { - component.items = []; + fixture.componentRef.setInput('items', []); fixture.detectChanges(); expect(directive.items()).toEqual([]); }); @@ -123,15 +125,15 @@ describe('PoDropListBaseDirective (via PoDropListDirective)', () => { }); it('should read `dropListDisabled` signal as true when bound to true', () => { - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); expect(directive.dropListDisabled()).toBeTrue(); }); it('should toggle back to false', () => { - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); - component.disabled = false; + fixture.componentRef.setInput('disabled', false); fixture.detectChanges(); expect(directive.dropListDisabled()).toBeFalse(); }); @@ -152,13 +154,13 @@ describe('PoDropListBaseDirective (via PoDropListDirective)', () => { }); it('should update to "horizontal" when input changes', () => { - component.orientation = 'horizontal'; + fixture.componentRef.setInput('orientation', 'horizontal'); fixture.detectChanges(); expect(directive.dropListOrientation()).toBe('horizontal'); }); it('should accept "mixed" value', () => { - component.orientation = 'mixed'; + fixture.componentRef.setInput('orientation', 'mixed'); fixture.detectChanges(); expect(directive.dropListOrientation()).toBe('mixed'); }); @@ -170,15 +172,15 @@ describe('PoDropListBaseDirective (via PoDropListDirective)', () => { }); it('should update when string ids are provided', () => { - component.connectedTo = ['list-x', 'list-y']; + fixture.componentRef.setInput('connectedTo', ['list-x', 'list-y']); fixture.detectChanges(); expect(directive.dropListConnectedTo()).toEqual(['list-x', 'list-y']); }); it('should update back to empty array', () => { - component.connectedTo = ['list-x']; + fixture.componentRef.setInput('connectedTo', ['list-x']); fixture.detectChanges(); - component.connectedTo = []; + fixture.componentRef.setInput('connectedTo', []); fixture.detectChanges(); expect(directive.dropListConnectedTo()).toEqual([]); }); @@ -190,7 +192,7 @@ describe('PoDropListBaseDirective (via PoDropListDirective)', () => { }); it('should read `dropSortingDisabled` as true when bound to true', () => { - component.sortingDisabled = true; + fixture.componentRef.setInput('sortingDisabled', true); fixture.detectChanges(); expect(directive.dropSortingDisabled()).toBeTrue(); }); diff --git a/projects/ui/src/lib/directives/po-drag-drop/po-drop-list.directive.spec.ts b/projects/ui/src/lib/directives/po-drag-drop/po-drop-list.directive.spec.ts index 38e20e52eb..2964ef17e4 100644 --- a/projects/ui/src/lib/directives/po-drag-drop/po-drop-list.directive.spec.ts +++ b/projects/ui/src/lib/directives/po-drag-drop/po-drop-list.directive.spec.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { CdkDropList } from '@angular/cdk/drag-drop'; @@ -33,15 +33,17 @@ interface TestItem { standalone: false }) class TestHostComponent { - items: Array = [ + // Inputs do host para permitir atualização via fixture.componentRef.setInput, + // que é o mecanismo suportado para refletir mudanças de binding no ambiente de teste (Angular 22). + @Input() items: Array = [ { id: '1', name: 'Item 1' }, { id: '2', name: 'Item 2' }, { id: '3', name: 'Item 3' } ]; - disabled = false; - orientation: 'horizontal' | 'vertical' | 'mixed' = 'vertical'; - connectedTo: Array = []; - sortingDisabled = false; + @Input() disabled = false; + @Input() orientation: 'horizontal' | 'vertical' | 'mixed' = 'vertical'; + @Input() connectedTo: Array = []; + @Input() sortingDisabled = false; droppedEvent: PoDropEvent | null = null; dragEnteredEvent: PoDragEnterEvent | null = null; @@ -129,7 +131,7 @@ describe('PoDropListDirective', () => { it('should update `items` signal when input changes', () => { const newItems: Array = [{ id: '4', name: 'New Item' }]; - component.items = newItems; + fixture.componentRef.setInput('items', newItems); fixture.detectChanges(); expect(directive.items()).toEqual(newItems); }); @@ -143,7 +145,7 @@ describe('PoDropListDirective', () => { }); it('should read `dropListDisabled` signal as true when input changes', () => { - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); expect(directive.dropListDisabled()).toBeTrue(); }); @@ -153,7 +155,7 @@ describe('PoDropListDirective', () => { }); it('should update `dropListConnectedTo` when input changes', () => { - component.connectedTo = ['list-b', 'list-c']; + fixture.componentRef.setInput('connectedTo', ['list-b', 'list-c']); fixture.detectChanges(); expect(directive.dropListConnectedTo()).toEqual(['list-b', 'list-c']); }); @@ -163,13 +165,13 @@ describe('PoDropListDirective', () => { }); it('should update `dropListOrientation` when input changes', () => { - component.orientation = 'horizontal'; + fixture.componentRef.setInput('orientation', 'horizontal'); fixture.detectChanges(); expect(directive.dropListOrientation()).toBe('horizontal'); }); it('should accept "mixed" as orientation value', () => { - component.orientation = 'mixed'; + fixture.componentRef.setInput('orientation', 'mixed'); fixture.detectChanges(); expect(directive.dropListOrientation()).toBe('mixed'); }); @@ -179,7 +181,7 @@ describe('PoDropListDirective', () => { }); it('should read `dropSortingDisabled` as true when input changes', () => { - component.sortingDisabled = true; + fixture.componentRef.setInput('sortingDisabled', true); fixture.detectChanges(); expect(directive.dropSortingDisabled()).toBeTrue(); }); @@ -194,7 +196,7 @@ describe('PoDropListDirective', () => { it('should sync disabled state to CdkDropList', () => { expect(cdkDropList.disabled).toBeFalse(); - component.disabled = true; + fixture.componentRef.setInput('disabled', true); fixture.detectChanges(); expect(cdkDropList.disabled).toBeTrue(); }); @@ -209,13 +211,13 @@ describe('PoDropListDirective', () => { it('should sync sortingDisabled to CdkDropList', () => { expect(cdkDropList.sortingDisabled).toBeFalse(); - component.sortingDisabled = true; + fixture.componentRef.setInput('sortingDisabled', true); fixture.detectChanges(); expect(cdkDropList.sortingDisabled).toBeTrue(); }); it('should sync connectedTo as string[] to CdkDropList', () => { - component.connectedTo = ['list-b']; + fixture.componentRef.setInput('connectedTo', ['list-b']); fixture.detectChanges(); expect(cdkDropList.connectedTo).toEqual(['list-b']); }); diff --git a/projects/ui/src/lib/directives/po-tooltip/po-tooltip.directive.spec.ts b/projects/ui/src/lib/directives/po-tooltip/po-tooltip.directive.spec.ts index b04b5f65a3..82429b6268 100644 --- a/projects/ui/src/lib/directives/po-tooltip/po-tooltip.directive.spec.ts +++ b/projects/ui/src/lib/directives/po-tooltip/po-tooltip.directive.spec.ts @@ -1,4 +1,4 @@ -import { Component, Renderer2 } from '@angular/core'; +import { Component, Renderer2, ChangeDetectionStrategy } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; @@ -13,6 +13,7 @@ import { PoControlPositionService } from '../../services/po-control-position/po-
    `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class TestComponent {} diff --git a/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-basic/sample-po-tooltip-basic.component.ts b/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-basic/sample-po-tooltip-basic.component.ts index 20f9a1c4a8..1efd1d1282 100644 --- a/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-basic/sample-po-tooltip-basic.component.ts +++ b/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-basic/sample-po-tooltip-basic.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-tooltip-basic', templateUrl: './sample-po-tooltip-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTooltipBasicComponent {} diff --git a/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-labs/sample-po-tooltip-labs.component.ts b/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-labs/sample-po-tooltip-labs.component.ts index 383cf320df..c6ab49e483 100644 --- a/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-labs/sample-po-tooltip-labs.component.ts +++ b/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-labs/sample-po-tooltip-labs.component.ts @@ -1,10 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-tooltip-labs', templateUrl: './sample-po-tooltip-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTooltipLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-new-user/sample-po-tooltip-new-user.component.ts b/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-new-user/sample-po-tooltip-new-user.component.ts index 13fb22a826..46468c47fc 100644 --- a/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-new-user/sample-po-tooltip-new-user.component.ts +++ b/projects/ui/src/lib/directives/po-tooltip/samples/sample-po-tooltip-new-user/sample-po-tooltip-new-user.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { PoNotificationService } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-tooltip-new-user', templateUrl: './sample-po-tooltip-new-user.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoTooltipNewUserComponent implements OnInit { diff --git a/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-base.service.spec.ts b/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-base.service.spec.ts index 42ec5dd0bc..35691c6b1c 100644 --- a/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-base.service.spec.ts +++ b/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-base.service.spec.ts @@ -6,7 +6,8 @@ import { HttpRequest, HttpResponse, provideHttpClient, - withInterceptorsFromDi + withInterceptorsFromDi, + withXhr } from '@angular/common/http'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; @@ -48,7 +49,7 @@ describe('PoHttpInterceptorBaseService', () => { useClass: PoHttpInterceptorService, multi: true }, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }).compileComponents(); diff --git a/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-base.service.ts b/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-base.service.ts index 5be3f59ef2..bf21746a34 100644 --- a/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-base.service.ts +++ b/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-base.service.ts @@ -30,17 +30,15 @@ const NO_MESSAGE_HEADER_PARAM = 'X-PO-No-Message'; * * ## Configuração * - * Para o correto funcionamento do interceptor `po-http-interceptor`, deve ser importado o `BrowserAnimationsModule` na - * aplicação. Além disso, é necessário configurar o `HttpClient` para utilizar os interceptors registrados via Dependency - * Injection (DI) por meio da função `provideHttpClient(withInterceptorsFromDi())`. + * Para o correto funcionamento do interceptor `po-http-interceptor`, é necessário configurar o `HttpClient` para utilizar + * os interceptors registrados via Dependency Injection (DI) por meio da função `provideHttpClient(withInterceptorsFromDi())`. * * ### 1) NgModule * - * No módulo principal da aplicação (geralmente `AppModule`), importe o `BrowserAnimationsModule` e configure o `HttpClient`, + * No módulo principal da aplicação (geralmente `AppModule`), configure o `HttpClient`, * como no exemplo abaixo: * * ``` - * import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; * import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; * import { PoModule } from '@po-ui/ng-components'; * ... @@ -48,7 +46,6 @@ const NO_MESSAGE_HEADER_PARAM = 'X-PO-No-Message'; * @NgModule({ * imports: [ * BrowserModule, - * BrowserAnimationsModule, * ... * PoModule * ], @@ -76,13 +73,11 @@ const NO_MESSAGE_HEADER_PARAM = 'X-PO-No-Message'; * ``` * import { ApplicationConfig, importProvidersFrom } from '@angular/core'; * import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - * import { provideAnimations } from '@angular/platform-browser/animations'; * import { PoHttpInterceptorModule } from '@po-ui/ng-components'; * * export const appConfig: ApplicationConfig = { * providers: [ * ... - * provideAnimations(), * provideHttpClient(withInterceptorsFromDi()), * importProvidersFrom([ * PoHttpInterceptorModule diff --git a/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-detail/po-http-interceptor-detail.component.ts b/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-detail/po-http-interceptor-detail.component.ts index 9b9ca4de65..9d4473963d 100644 --- a/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-detail/po-http-interceptor-detail.component.ts +++ b/projects/ui/src/lib/interceptors/po-http-interceptor/po-http-interceptor-detail/po-http-interceptor-detail.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, OnInit, ViewChild } from '@angular/core'; +import { Component, EventEmitter, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoModalAction } from '../../../components/po-modal/po-modal-action.interface'; import { PoModalComponent } from '../../../components/po-modal/po-modal.component'; @@ -19,6 +19,7 @@ export const colors = { success: 'color-11', error: 'color-07', warning: 'color- @Component({ selector: 'po-http-interceptor-detail', templateUrl: './po-http-interceptor-detail.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoHttpInterceptorDetailComponent implements OnInit { diff --git a/projects/ui/src/lib/interceptors/po-http-interceptor/samples/sample-po-http-interceptor-labs.component.ts b/projects/ui/src/lib/interceptors/po-http-interceptor/samples/sample-po-http-interceptor-labs.component.ts index fda5140784..9367e6a281 100644 --- a/projects/ui/src/lib/interceptors/po-http-interceptor/samples/sample-po-http-interceptor-labs.component.ts +++ b/projects/ui/src/lib/interceptors/po-http-interceptor/samples/sample-po-http-interceptor-labs.component.ts @@ -1,6 +1,6 @@ // import { PoRadioGroupOption } from './../../../../../../../dist/ng-components/lib/components/po-field/po-radio-group/po-radio-group-option.interface.d'; import { HttpClient } from '@angular/common/http'; -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoRadioGroupOption } from '@po-ui/ng-components'; import { Subscription } from 'rxjs'; @@ -8,6 +8,7 @@ import { Subscription } from 'rxjs'; @Component({ selector: 'sample-po-http-interceptor-labs', templateUrl: './sample-po-http-interceptor-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoHttpInterceptorLabsComponent implements OnDestroy, OnInit { diff --git a/projects/ui/src/lib/interceptors/po-http-request/po-http-request-interceptor.service.spec.ts b/projects/ui/src/lib/interceptors/po-http-request/po-http-request-interceptor.service.spec.ts index acf19525a4..2e99cb955d 100644 --- a/projects/ui/src/lib/interceptors/po-http-request/po-http-request-interceptor.service.spec.ts +++ b/projects/ui/src/lib/interceptors/po-http-request/po-http-request-interceptor.service.spec.ts @@ -4,7 +4,8 @@ import { HTTP_INTERCEPTORS, HttpRequest, provideHttpClient, - withInterceptorsFromDi + withInterceptorsFromDi, + withXhr } from '@angular/common/http'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; @@ -37,7 +38,7 @@ describe('PoHttpRequestInterceptorService: ', () => { useClass: PoHttpRequestInterceptorService, multi: true }, - provideHttpClient(withInterceptorsFromDi()), + provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting() ] }); diff --git a/projects/ui/src/lib/interceptors/po-http-request/po-http-request-interceptor.service.ts b/projects/ui/src/lib/interceptors/po-http-request/po-http-request-interceptor.service.ts index 12bccdc1df..5a8107983b 100644 --- a/projects/ui/src/lib/interceptors/po-http-request/po-http-request-interceptor.service.ts +++ b/projects/ui/src/lib/interceptors/po-http-request/po-http-request-interceptor.service.ts @@ -88,7 +88,6 @@ const screenLock = 'X-PO-Screen-Lock'; * ``` * import { ApplicationConfig, importProvidersFrom } from '@angular/core'; * import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; - * import { provideAnimations } from '@angular/platform-browser/animations'; * import { PoHttpRequestModule } from '@po-ui/ng-components'; * * export const appConfig: ApplicationConfig = { diff --git a/projects/ui/src/lib/interceptors/po-http-request/samples/sample-po-http-request-interceptor-labs.component.ts b/projects/ui/src/lib/interceptors/po-http-request/samples/sample-po-http-request-interceptor-labs.component.ts index 0b877a926f..cd3bfc3cbc 100644 --- a/projects/ui/src/lib/interceptors/po-http-request/samples/sample-po-http-request-interceptor-labs.component.ts +++ b/projects/ui/src/lib/interceptors/po-http-request/samples/sample-po-http-request-interceptor-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Subscription } from 'rxjs'; @@ -8,6 +8,7 @@ import { PoHttpRequestInterceptorService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-http-request-interceptor-labs', templateUrl: './sample-po-http-request-interceptor-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoHttpRequestInterceptorLabsComponent implements OnInit, OnDestroy { diff --git a/projects/ui/src/lib/services/po-component-injector/po-component-injector.service.spec.ts b/projects/ui/src/lib/services/po-component-injector/po-component-injector.service.spec.ts index e376b8e8af..143d18a2ba 100644 --- a/projects/ui/src/lib/services/po-component-injector/po-component-injector.service.spec.ts +++ b/projects/ui/src/lib/services/po-component-injector/po-component-injector.service.spec.ts @@ -1,4 +1,4 @@ -import { NgModule, Component } from '@angular/core'; +import { NgModule, Component, ChangeDetectionStrategy } from '@angular/core'; import { TestBed, inject } from '@angular/core/testing'; import { CommonModule } from '@angular/common'; @@ -8,6 +8,7 @@ import { PoComponentInjectorService } from './po-component-injector.service'; @Component({ template: `
    test component
    `, + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class TestComponent { diff --git a/projects/ui/src/lib/services/po-component-injector/po-component-injector.service.ts b/projects/ui/src/lib/services/po-component-injector/po-component-injector.service.ts index 27b9a57f7e..972d453eb4 100644 --- a/projects/ui/src/lib/services/po-component-injector/po-component-injector.service.ts +++ b/projects/ui/src/lib/services/po-component-injector/po-component-injector.service.ts @@ -1,26 +1,37 @@ -import { Injectable, ComponentRef, ComponentFactoryResolver, ApplicationRef, Injector } from '@angular/core'; +import { Injectable, ComponentRef, ApplicationRef, Injector, createComponent, Type } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class PoComponentInjectorService { constructor( - private readonly componentResolver: ComponentFactoryResolver, private readonly applicationRef: ApplicationRef, private readonly injector: Injector ) {} - // Cria um dinamicamente no ApplicationRef - createComponentInApplication(component: any): ComponentRef { - const componentRef = this.componentResolver.resolveComponentFactory(component).create(this.injector); + /** + * Cria dinamicamente um componente no ApplicationRef e o anexa ao body do documento. + * @param component Classe do componente Angular (ex: MeuComponente) + */ + createComponentInApplication(component: Type): ComponentRef { + const componentRef = createComponent(component, { + environmentInjector: this.applicationRef.injector, + elementInjector: this.injector + }); + this.applicationRef.attachView(componentRef.hostView); - const domElem = (componentRef.hostView).rootNodes[0]; + + const domElem = (componentRef.hostView as any).rootNodes[0] as HTMLElement; document.body.appendChild(domElem); + return componentRef; } - // Destrói o componente e remove do ApplicationRef - destroyComponentInApplication(componentRef: any) { + /** + * Destrói o componente e remove suas referências do ApplicationRef e do DOM. + * @param componentRef Referência do componente que foi criado dinamicamente + */ + destroyComponentInApplication(componentRef: ComponentRef): void { this.applicationRef.detachView(componentRef.hostView); componentRef.destroy(); } diff --git a/projects/ui/src/lib/services/po-dialog/po-dialog.component.ts b/projects/ui/src/lib/services/po-dialog/po-dialog.component.ts index b81a2e5fa9..6b221b1176 100644 --- a/projects/ui/src/lib/services/po-dialog/po-dialog.component.ts +++ b/projects/ui/src/lib/services/po-dialog/po-dialog.component.ts @@ -1,4 +1,14 @@ -import { Component, ComponentRef, HostBinding, HostListener, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { + Component, + ComponentRef, + HostBinding, + HostListener, + Input, + OnDestroy, + OnInit, + ViewChild, + ChangeDetectionStrategy +} from '@angular/core'; import { Subscription } from 'rxjs'; @@ -39,6 +49,7 @@ export const poDialogConfirmLiteralsDefault = { @Component({ templateUrl: './po-dialog.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class PoDialogComponent implements OnDestroy, OnInit { diff --git a/projects/ui/src/lib/services/po-dialog/po-dialog.service.spec.ts b/projects/ui/src/lib/services/po-dialog/po-dialog.service.spec.ts index 2d64a97aba..f3550edba5 100644 --- a/projects/ui/src/lib/services/po-dialog/po-dialog.service.spec.ts +++ b/projects/ui/src/lib/services/po-dialog/po-dialog.service.spec.ts @@ -1,4 +1,4 @@ -import { Component, NgModule } from '@angular/core'; +import { Component, NgModule, ChangeDetectionStrategy } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ComponentFixture, inject, TestBed } from '@angular/core/testing'; @@ -18,6 +18,7 @@ class TestModule {} @Component({ template: ` test component `, providers: [PoComponentInjectorService, PoDialogService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) class TestComponent { diff --git a/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-basic/sample-po-dialog-basic.component.ts b/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-basic/sample-po-dialog-basic.component.ts index 05db343e79..fafb8fab6b 100644 --- a/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-basic/sample-po-dialog-basic.component.ts +++ b/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-basic/sample-po-dialog-basic.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoDialogService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-dialog-basic', templateUrl: './sample-po-dialog-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDialogBasicComponent { diff --git a/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-cancel-credit-card/sample-po-dialog-cancel-credit-card.component.ts b/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-cancel-credit-card/sample-po-dialog-cancel-credit-card.component.ts index d2c3a7ebb5..d780a9dc73 100644 --- a/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-cancel-credit-card/sample-po-dialog-cancel-credit-card.component.ts +++ b/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-cancel-credit-card/sample-po-dialog-cancel-credit-card.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { Component, OnDestroy, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { Subscription } from 'rxjs'; @@ -8,6 +8,7 @@ import { PoDialogService, PoNotificationService, PoPageAction, PoRadioGroupOptio @Component({ selector: 'sample-po-dialog-cancel-credit-card', templateUrl: './sample-po-dialog-cancel-credit-card.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDialogCancelCreditCardComponent implements OnDestroy, OnInit { diff --git a/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-labs/sample-po-dialog-labs.component.ts b/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-labs/sample-po-dialog-labs.component.ts index 09d28886a4..235bb4966b 100644 --- a/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-labs/sample-po-dialog-labs.component.ts +++ b/projects/ui/src/lib/services/po-dialog/samples/sample-po-dialog-labs/sample-po-dialog-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; @@ -7,6 +7,7 @@ import { PoDialogAlertLiterals, PoDialogConfirmLiterals, PoDialogService } from @Component({ selector: 'sample-po-dialog-labs', templateUrl: './sample-po-dialog-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoDialogLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/services/po-i18n/po-i18n-base.service.spec.ts b/projects/ui/src/lib/services/po-i18n/po-i18n-base.service.spec.ts index 89cdca7f3a..17796957df 100644 --- a/projects/ui/src/lib/services/po-i18n/po-i18n-base.service.spec.ts +++ b/projects/ui/src/lib/services/po-i18n/po-i18n-base.service.spec.ts @@ -1,6 +1,6 @@ import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; -import { HttpRequest, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; +import { HttpRequest, provideHttpClient, withInterceptorsFromDi, withXhr } from '@angular/common/http'; import { of } from 'rxjs'; @@ -44,7 +44,7 @@ describe('PoI18nService:', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [PoLanguageModule, PoI18nModule.config(config)], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting()] }).compileComponents(); service = TestBed.inject(PoI18nService); @@ -334,7 +334,7 @@ describe('PoI18nService:', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [PoLanguageModule, PoI18nModule.config(config)], - providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()] + providers: [provideHttpClient(withXhr(), withInterceptorsFromDi()), provideHttpClientTesting()] }); service = TestBed.inject(PoI18nService); @@ -398,8 +398,11 @@ describe('PoI18nService:', () => { const translations = {}; spyOn(service as any, 'mergeObject').and.callThrough(); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(service, 'searchInVarI18n' as keyof PoI18nService).and.returnValue(''); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(service, 'countObject' as keyof PoI18nService).and.returnValue('0'); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(service, 'getLiteralsLocalStorageAndCache' as keyof PoI18nService); service['getLiteralsFromContextService']( diff --git a/projects/ui/src/lib/services/po-i18n/samples/sample-po-i18n-pipe-labs.component.ts b/projects/ui/src/lib/services/po-i18n/samples/sample-po-i18n-pipe-labs.component.ts index 3dee1dabdb..0bdd45ca8e 100644 --- a/projects/ui/src/lib/services/po-i18n/samples/sample-po-i18n-pipe-labs.component.ts +++ b/projects/ui/src/lib/services/po-i18n/samples/sample-po-i18n-pipe-labs.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-i18n-pipe-labs', templateUrl: './sample-po-i18n-pipe-labs.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoI18nPipeLabsComponent { diff --git a/projects/ui/src/lib/services/po-i18n/samples/sample-po-i18n-pipe.component.ts b/projects/ui/src/lib/services/po-i18n/samples/sample-po-i18n-pipe.component.ts index f0c1b303c3..16e99066c8 100644 --- a/projects/ui/src/lib/services/po-i18n/samples/sample-po-i18n-pipe.component.ts +++ b/projects/ui/src/lib/services/po-i18n/samples/sample-po-i18n-pipe.component.ts @@ -1,8 +1,9 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'sample-po-i18n-pipe', templateUrl: './sample-po-i18n-pipe.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoI18nPipeComponent {} diff --git a/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-basic/sample-po-notification-basic.component.ts b/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-basic/sample-po-notification-basic.component.ts index 00abb4c048..b8961a0637 100644 --- a/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-basic/sample-po-notification-basic.component.ts +++ b/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-basic/sample-po-notification-basic.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoNotificationService } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-notification-basic', templateUrl: './sample-po-notification-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoNotificationBasicComponent { diff --git a/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-labs/sample-po-notification-labs.component.ts b/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-labs/sample-po-notification-labs.component.ts index b6ca6c0ee7..cbc51faddb 100644 --- a/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-labs/sample-po-notification-labs.component.ts +++ b/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-labs/sample-po-notification-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { PoModalComponent, @@ -13,6 +13,7 @@ import { selector: 'sample-po-notification-labs', templateUrl: './sample-po-notification-labs.component.html', providers: [PoNotificationService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoNotificationLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-sales/sample-po-notification-sales.component.ts b/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-sales/sample-po-notification-sales.component.ts index 627d3c6406..97a8043649 100644 --- a/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-sales/sample-po-notification-sales.component.ts +++ b/projects/ui/src/lib/services/po-notification/samples/sample-po-notification-sales/sample-po-notification-sales.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoComboOption, PoNotificationService, PoTableColumn } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoComboOption, PoNotificationService, PoTableColumn } from '@po-ui/ng-c selector: 'sample-po-notification-sales', templateUrl: './sample-po-notification-sales.component.html', providers: [PoNotificationService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoNotificationSalesComponent { diff --git a/projects/ui/src/lib/services/po-theme/samples/sample-po-theme-labs/sample-po-theme-labs.component.ts b/projects/ui/src/lib/services/po-theme/samples/sample-po-theme-labs/sample-po-theme-labs.component.ts index 582620ef53..91a0b0d43a 100644 --- a/projects/ui/src/lib/services/po-theme/samples/sample-po-theme-labs/sample-po-theme-labs.component.ts +++ b/projects/ui/src/lib/services/po-theme/samples/sample-po-theme-labs/sample-po-theme-labs.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild, ChangeDetectionStrategy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { @@ -20,6 +20,7 @@ import { PoModalAction, PoModalComponent } from '@po-ui/ng-components'; selector: 'sample-po-theme-labs', templateUrl: './sample-po-theme-labs.component.html', providers: [PoThemeService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoThemeLabsComponent implements OnInit, OnDestroy { diff --git a/projects/ui/src/lib/services/po-user-guide/po-user-guide-base.service.spec.ts b/projects/ui/src/lib/services/po-user-guide/po-user-guide-base.service.spec.ts index d551d75a29..f12c427027 100644 --- a/projects/ui/src/lib/services/po-user-guide/po-user-guide-base.service.spec.ts +++ b/projects/ui/src/lib/services/po-user-guide/po-user-guide-base.service.spec.ts @@ -48,11 +48,11 @@ describe('PoUserGuideBaseService:', () => { describe('validateSteps:', () => { it('should throw when steps is null', () => { - expect(() => service['validateSteps'](null as any)).toThrowError(/obrigatória/); + expect(() => service['validateSteps'](null)).toThrowError(/obrigatória/); }); it('should throw when steps is undefined', () => { - expect(() => service['validateSteps'](undefined as any)).toThrowError(/obrigatória/); + expect(() => service['validateSteps'](undefined)).toThrowError(/obrigatória/); }); it('should throw when steps is an empty array', () => { @@ -64,7 +64,7 @@ describe('PoUserGuideBaseService:', () => { }); it('should throw when a step entry is null', () => { - expect(() => service['validateSteps']([null] as any)).toThrowError(/índice 0 é inválido/); + expect(() => service['validateSteps']([null])).toThrowError(/índice 0 é inválido/); }); it('should throw when a step is missing the content property', () => { diff --git a/projects/ui/src/lib/services/po-user-guide/po-user-guide.service.spec.ts b/projects/ui/src/lib/services/po-user-guide/po-user-guide.service.spec.ts index 87b099b99e..fbe9a2ef34 100644 --- a/projects/ui/src/lib/services/po-user-guide/po-user-guide.service.spec.ts +++ b/projects/ui/src/lib/services/po-user-guide/po-user-guide.service.spec.ts @@ -350,7 +350,7 @@ describe('PoUserGuideService:', () => { expect(() => service.goTo(-1)).toThrowError(/fora do intervalo/); expect(() => service.goTo(2)).toThrowError(/fora do intervalo/); expect(() => service.goTo(Number.MAX_SAFE_INTEGER)).toThrowError(/fora do intervalo/); - expect(() => service.goTo(1.5 as any)).toThrowError(/fora do intervalo/); + expect(() => service.goTo(1.5)).toThrowError(/fora do intervalo/); expect(() => service.goTo('a' as any)).toThrowError(/fora do intervalo/); }); }); @@ -911,7 +911,7 @@ describe('PoUserGuideService:', () => { service.setSteps([{ content: 'a' }, { content: 'b' }]); expect(() => service.start(-1)).toThrowError(/fora do intervalo/); expect(() => service.start(5)).toThrowError(/fora do intervalo/); - expect(() => service.start(1.5 as any)).toThrowError(/fora do intervalo/); + expect(() => service.start(1.5)).toThrowError(/fora do intervalo/); expect(() => service.start('a' as any)).toThrowError(/fora do intervalo/); }); }); @@ -996,7 +996,9 @@ describe('PoUserGuideService:', () => { it('should return a Promise when importDriver is invoked directly', () => { const result = (service as any).importDriver(); - expect(result).toBeInstanceOf(Promise); + expect(result).toBeDefined(); + expect(typeof result.then).toBe('function'); + expect(typeof result.catch).toBe('function'); (result as Promise).catch(() => {}); }); @@ -1372,11 +1374,11 @@ describe('PoUserGuideService:', () => { describe('setSteps validation:', () => { it('should throw when steps is null', () => { - expect(() => service.setSteps(null as any)).toThrowError(/obrigatória/); + expect(() => service.setSteps(null)).toThrowError(/obrigatória/); }); it('should throw when steps is undefined', () => { - expect(() => service.setSteps(undefined as any)).toThrowError(/obrigatória/); + expect(() => service.setSteps(undefined)).toThrowError(/obrigatória/); }); it('should throw when steps is not an array', () => { @@ -1388,7 +1390,7 @@ describe('PoUserGuideService:', () => { }); it('should throw when a step entry is null', () => { - expect(() => service.setSteps([null] as any)).toThrowError(/índice 0 é inválido/); + expect(() => service.setSteps([null])).toThrowError(/índice 0 é inválido/); }); it('should throw when a step is missing the content property', () => { diff --git a/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-basic/sample-po-user-guide-basic.component.ts b/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-basic/sample-po-user-guide-basic.component.ts index ad93d67f61..afba12b5d1 100644 --- a/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-basic/sample-po-user-guide-basic.component.ts +++ b/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-basic/sample-po-user-guide-basic.component.ts @@ -1,10 +1,11 @@ -import { Component } from '@angular/core'; +import { Component, ChangeDetectionStrategy } from '@angular/core'; import { PoUserGuidePosition, PoUserGuideService, PoUserGuideStep } from '@po-ui/ng-components'; @Component({ selector: 'sample-po-user-guide-basic', templateUrl: './sample-po-user-guide-basic.component.html', + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUserGuideBasicComponent { diff --git a/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-labs/sample-po-user-guide-labs.component.ts b/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-labs/sample-po-user-guide-labs.component.ts index 9884dfa8e0..fa3b0126f8 100644 --- a/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-labs/sample-po-user-guide-labs.component.ts +++ b/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-labs/sample-po-user-guide-labs.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { PoUserGuideOptions, PoUserGuidePosition, PoUserGuideService, PoUserGuideStep } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoUserGuideOptions, PoUserGuidePosition, PoUserGuideService, PoUserGuid selector: 'sample-po-user-guide-labs', templateUrl: './sample-po-user-guide-labs.component.html', providers: [PoUserGuideService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUserGuideLabsComponent implements OnInit { diff --git a/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-onboarding/sample-po-user-guide-onboarding.component.ts b/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-onboarding/sample-po-user-guide-onboarding.component.ts index 82f6c37070..d6ddce029f 100644 --- a/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-onboarding/sample-po-user-guide-onboarding.component.ts +++ b/projects/ui/src/lib/services/po-user-guide/samples/sample-po-user-guide-onboarding/sample-po-user-guide-onboarding.component.ts @@ -1,4 +1,4 @@ -import { Component, AfterViewInit } from '@angular/core'; +import { Component, AfterViewInit, ChangeDetectionStrategy } from '@angular/core'; import { PoUserGuidePosition, PoUserGuideService, PoUserGuideStep } from '@po-ui/ng-components'; @@ -6,6 +6,7 @@ import { PoUserGuidePosition, PoUserGuideService, PoUserGuideStep } from '@po-ui selector: 'sample-po-user-guide-onboarding', templateUrl: './sample-po-user-guide-onboarding.component.html', providers: [PoUserGuideService], + changeDetection: ChangeDetectionStrategy.Eager, standalone: false }) export class SamplePoUserGuideOnboardingComponent implements AfterViewInit { diff --git a/projects/ui/src/lib/utils/util.spec.ts b/projects/ui/src/lib/utils/util.spec.ts index 4d23d6ceb5..b78eac2a20 100644 --- a/projects/ui/src/lib/utils/util.spec.ts +++ b/projects/ui/src/lib/utils/util.spec.ts @@ -1,7 +1,7 @@ import { ElementRef } from '@angular/core'; import { PoDensityMode } from '../enums/po-density-mode.enum'; import { PoFieldSize } from '../enums/po-field-size.enum'; -import { PoThemeA11yEnum, PoThemeService } from '../services'; +import { PoThemeA11yEnum } from '../services'; import { handleThrowError } from './../util-test/util-expect.spec'; import { @@ -1669,13 +1669,7 @@ describe('replaceFormatSeparator: ', () => { }); describe('accessibility level: ', () => { - describe('getDefaultSize', () => { - let poThemeServiceMock: jasmine.SpyObj; - - beforeEach(() => { - poThemeServiceMock = jasmine.createSpyObj('PoThemeService', ['getA11yLevel', 'getA11yDefaultSize']); - }); - + describe('getDefaultSizeFn', () => { beforeEach(() => { document.documentElement.removeAttribute('data-a11y'); localStorage.removeItem('po-default-size'); @@ -1686,13 +1680,6 @@ describe('accessibility level: ', () => { localStorage.removeItem('po-default-size'); }); - it('should return `small` when the default component size is `small` in accessibility level AA (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AA); - poThemeServiceMock.getA11yDefaultSize.and.returnValue('small'); - - expect(UtilFunctions.getDefaultSize(poThemeServiceMock, PoFieldSize)).toBe(PoFieldSize.Small); - }); - it('should return `small` when the default component size is `small` in accessibility level AA', () => { document.documentElement.setAttribute('data-a11y', PoThemeA11yEnum.AA); localStorage.setItem('po-default-size', 'small'); @@ -1700,12 +1687,6 @@ describe('accessibility level: ', () => { expect(UtilFunctions.getDefaultSizeFn(PoFieldSize)).toBe(PoFieldSize.Small); }); - it('should return `medium` if accessibility AA and default size is not set (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AA); - - expect(UtilFunctions.getDefaultSize(poThemeServiceMock, PoFieldSize)).toBe(PoFieldSize.Medium); - }); - it('should return `medium` if accessibility AA and default size is not set', () => { document.documentElement.setAttribute('data-a11y', PoThemeA11yEnum.AA); localStorage.removeItem('po-default-size'); @@ -1713,12 +1694,6 @@ describe('accessibility level: ', () => { expect(UtilFunctions.getDefaultSizeFn(PoFieldSize)).toBe(PoFieldSize.Medium); }); - it('should return `medium` when the accessibility level is AAA (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AAA); - - expect(UtilFunctions.getDefaultSize(poThemeServiceMock, PoFieldSize)).toBe(PoFieldSize.Medium); - }); - it('should return `medium` when the accessibility level is AAA', () => { document.documentElement.setAttribute('data-a11y', PoThemeA11yEnum.AAA); @@ -1726,13 +1701,7 @@ describe('accessibility level: ', () => { }); }); - describe('validateSize', () => { - let poThemeServiceMock: jasmine.SpyObj; - - beforeEach(() => { - poThemeServiceMock = jasmine.createSpyObj('PoThemeService', ['getA11yLevel', 'getA11yDefaultSize']); - }); - + describe('validateSizeFn', () => { beforeEach(() => { document.documentElement.removeAttribute('data-a11y'); localStorage.removeItem('po-default-size'); @@ -1743,13 +1712,6 @@ describe('accessibility level: ', () => { localStorage.removeItem('po-default-size'); }); - it('should return valid values based on accessibility level (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AA); - - expect(UtilFunctions.validateSize(PoFieldSize.Small, poThemeServiceMock, PoFieldSize)).toBe(PoFieldSize.Small); - expect(UtilFunctions.validateSize(PoFieldSize.Medium, poThemeServiceMock, PoFieldSize)).toBe(PoFieldSize.Medium); - }); - it('should return valid values based on accessibility level', () => { document.documentElement.setAttribute('data-a11y', PoThemeA11yEnum.AA); @@ -1757,24 +1719,12 @@ describe('accessibility level: ', () => { expect(UtilFunctions.validateSizeFn(PoFieldSize.Medium, PoFieldSize)).toBe(PoFieldSize.Medium); }); - it('should return `medium` when the value is `small` but the accessibility level is not AA (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AAA); - - expect(UtilFunctions.validateSize(PoFieldSize.Small, poThemeServiceMock, PoFieldSize)).toBe(PoFieldSize.Medium); - }); - it('should return `medium` when the value is `small` but the accessibility level is not AA', () => { document.documentElement.setAttribute('data-a11y', PoThemeA11yEnum.AAA); expect(UtilFunctions.validateSizeFn(PoFieldSize.Small, PoFieldSize)).toBe(PoFieldSize.Medium); }); - it('should return the default size when an invalid value is provided (Service)', () => { - poThemeServiceMock.getA11yLevel.and.returnValue(PoThemeA11yEnum.AA); - - expect(UtilFunctions.validateSize('xxg', poThemeServiceMock, PoFieldSize)).toBe(PoFieldSize.Medium); - }); - it('should return the default size when an invalid value is provided', () => { expect(UtilFunctions.validateSizeFn('xxg', PoFieldSize)).toBe(PoFieldSize.Medium); }); @@ -1982,6 +1932,7 @@ describe('getTextColor:', () => { let getComputedStyleSpy: jasmine.Spy; beforeEach(() => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion getComputedStyleSpy = spyOn(window, 'getComputedStyle').and.returnValue({ getPropertyValue: (token: string) => { const tokens = { @@ -2049,6 +2000,7 @@ describe('getTextColor:', () => { describe('getTextColorFromBackgroundColor:', () => { beforeEach(() => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion spyOn(window, 'getComputedStyle').and.returnValue({ getPropertyValue: (token: string) => { const tokens = { diff --git a/projects/ui/src/lib/utils/util.ts b/projects/ui/src/lib/utils/util.ts index dd31552893..50746fc36f 100644 --- a/projects/ui/src/lib/utils/util.ts +++ b/projects/ui/src/lib/utils/util.ts @@ -3,7 +3,6 @@ import { PoFieldSize } from '../enums/po-field-size.enum'; import { poLocaleDefault, poLocales } from '../services/po-language/po-language.constant'; import { ElementRef } from '@angular/core'; import { PoThemeA11yEnum } from '../services/po-theme/enum/po-theme-a11y.enum'; -import { PoThemeService } from '../services/po-theme/po-theme.service'; import { PoTableColumnSpacing } from '../components/po-table/enums/po-table-spacing.enum'; /** @@ -41,15 +40,6 @@ export function getBrowserLanguage(): string { return poLocales.includes(shortLanguage) ? language : poLocaleDefault; } -/** - * @deprecated use getDefaultSizeFn - * - * Retorna o tamanho padrão dos componentes conforme o nível de acessibilidade. - */ -export function getDefaultSize(poThemeService: PoThemeService, sizeEnum: T): T[keyof T] { - return poThemeService.getA11yDefaultSize() === 'small' ? sizeEnum['Small'] : sizeEnum['Medium']; -} - /** * Retorna o tamanho padrão dos componentes conforme o nível de acessibilidade. */ @@ -685,24 +675,6 @@ export function sortArrayOfObjects(items, key, isAscendingOrder) { } } -/** - * @deprecated use validateSizeFn - * - * Valida e retorna um tamanho permitido para os componentes, considerando a acessibilidade. - */ -export function validateSize(value: string, poThemeService: PoThemeService, sizeEnum: T): T[keyof T] { - const validSizes = Object.values(sizeEnum) as Array; - - if (value && validSizes.includes(value)) { - if (value === sizeEnum['Small'] && poThemeService.getA11yLevel() === PoThemeA11yEnum.AAA) { - return sizeEnum['Medium']; - } - return value as T[keyof T]; - } - - return getDefaultSize(poThemeService, sizeEnum); -} - /** * Valida e retorna um tamanho permitido para os componentes, considerando a acessibilidade. */ diff --git a/projects/ui/tsconfig.dts.json b/projects/ui/tsconfig.dts.json index ed6cb6dc74..ee7e147dcc 100644 --- a/projects/ui/tsconfig.dts.json +++ b/projects/ui/tsconfig.dts.json @@ -1,6 +1,7 @@ { "extends": "./tsconfig.lib.json", "compilerOptions": { + "rootDir": "./src", "declaration": true, "declarationMap": false, "emitDeclarationOnly": true, diff --git a/projects/ui/tsconfig.lib.json b/projects/ui/tsconfig.lib.json index 65eb256a90..0d64ccf35f 100644 --- a/projects/ui/tsconfig.lib.json +++ b/projects/ui/tsconfig.lib.json @@ -1,7 +1,6 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "baseUrl": ".", "outDir": "./dist/", "declarationMap": true, "declaration": true, @@ -11,9 +10,9 @@ "angularCompilerOptions": { "skipTemplateCodegen": true, "strictMetadataEmit": true, - "fullTemplateTypeCheck": true, "strictInjectionParameters": true, - "enableResourceInlining": true + "enableResourceInlining": true, + "strictTemplates": false }, "exclude": ["test.ts", "**/*.spec.ts", "**/*.e2e-spec.ts", "**/*.po.ts", "./node_modules/"] } diff --git a/projects/ui/tsconfig.schematics-spec.json b/projects/ui/tsconfig.schematics-spec.json new file mode 100644 index 0000000000..19387dd819 --- /dev/null +++ b/projects/ui/tsconfig.schematics-spec.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.schematics.json", + "compilerOptions": { + "noEmitOnError": false, + "noUnusedLocals": false, + "noUnusedParameters": false + }, + "include": ["schematics/**/*.spec.ts"], + "exclude": ["schematics/**/*/files/**/*", "schematics/ng-update/v22/gauge-manual-test/**/*"] +} diff --git a/projects/ui/tsconfig.schematics.json b/projects/ui/tsconfig.schematics.json index c2756d4fd7..07625afc82 100644 --- a/projects/ui/tsconfig.schematics.json +++ b/projects/ui/tsconfig.schematics.json @@ -1,11 +1,10 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "baseUrl": "../../", "lib": ["es2022", "dom"], "declaration": true, - "module": "commonjs", - "moduleResolution": "node", + "module": "node16", + "moduleResolution": "node16", "noEmitOnError": true, "noFallthroughCasesInSwitch": true, "noImplicitAny": false, @@ -22,5 +21,9 @@ "types": ["jasmine", "node"] }, "include": ["schematics/**/*"], - "exclude": ["schematics/**/*/files/**/*", "schematics/**/*/*.spec.ts"] + "exclude": [ + "schematics/**/*/files/**/*", + "schematics/**/*/*.spec.ts", + "schematics/ng-update/v22/gauge-manual-test/**/*" + ] } diff --git a/projects/ui/tsconfig.spec.json b/projects/ui/tsconfig.spec.json index 4005d5cb0f..96ecd96f9a 100644 --- a/projects/ui/tsconfig.spec.json +++ b/projects/ui/tsconfig.spec.json @@ -7,5 +7,8 @@ }, "files": ["src/test.ts"], "include": ["**/*.spec.ts", "**/*.d.ts", "src/lib/util-test/util-setup.ts"], - "exclude": ["schematics/**/*.spec.ts", "**/*.d.ts"] + "exclude": ["schematics/**/*.spec.ts", "**/*.d.ts"], + "angularCompilerOptions": { + "strictTemplates": false + } } diff --git a/scripts/generate-dist-trees.js b/scripts/generate-dist-trees.js new file mode 100644 index 0000000000..f36fa6b35f --- /dev/null +++ b/scripts/generate-dist-trees.js @@ -0,0 +1,67 @@ +/** + * generate-dist-trees.js + * + * Mapeia cada subdiretório presente em `dist/` e gera um arquivo + * `.tree` contendo a lista recursiva de todos os arquivos. + * + * Uso: + * node scripts/generate-dist-trees.js [outputDir] + * + * - outputDir (opcional): diretório onde os arquivos .tree serão salvos. + * Padrão: ./dist-trees + */ + +const fs = require('fs'); +const path = require('path'); + +const DIST_DIR = path.resolve(__dirname, '..', 'dist'); +const OUTPUT_DIR = path.resolve(process.argv[2] || path.join(__dirname, '..', 'dist-trees')); + +function getAllFiles(dirPath, basePath) { + const entries = fs.readdirSync(dirPath, { withFileTypes: true }); + let files = []; + + for (const entry of entries) { + const fullPath = path.join(dirPath, entry.name); + if (entry.isDirectory()) { + files = files.concat(getAllFiles(fullPath, basePath)); + } else { + // Caminho relativo ao diretório base (subdiretório de dist) + files.push(path.relative(basePath, fullPath).replace(/\\/g, '/')); + } + } + + return files; +} + +function main() { + if (!fs.existsSync(DIST_DIR)) { + console.error(`Erro: diretório "dist" não encontrado em: ${DIST_DIR}`); + process.exit(1); + } + + // Cria o diretório de saída se não existir + if (!fs.existsSync(OUTPUT_DIR)) { + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + } + + const subDirs = fs.readdirSync(DIST_DIR, { withFileTypes: true }).filter(d => d.isDirectory()); + + if (subDirs.length === 0) { + console.log('Nenhum subdiretório encontrado em dist/'); + return; + } + + for (const dir of subDirs) { + const dirFullPath = path.join(DIST_DIR, dir.name); + const files = getAllFiles(dirFullPath, dirFullPath).sort(); + const outputFile = path.join(OUTPUT_DIR, `${dir.name}.tree`); + + fs.writeFileSync(outputFile, files.join('\n') + '\n', 'utf-8'); + console.log(`✔ ${dir.name}.tree (${files.length} arquivos)`); + } + + console.log(`\nArquivos .tree salvos em: ${OUTPUT_DIR}`); +} + +main(); diff --git a/scripts/schematics.js b/scripts/schematics.js index 4c7ef6d7bb..033e8e2904 100644 --- a/scripts/schematics.js +++ b/scripts/schematics.js @@ -30,6 +30,23 @@ task('tsc:schematics', done => { }); }); +// Compiles the schematics *.spec.ts files so they can be executed with jasmine. +// The spec files are intentionally excluded from the production build (tsconfig.schematics.json), +// so this task uses a dedicated tsconfig that includes them. +task('tsc:schematics:spec', done => { + const lib = argv.lib; + + exec(`npm run tsc -- -p ./projects/${lib}/tsconfig.schematics-spec.json`, (err, stdout, stderr) => { + if (err) { + console.error(`exec error: ${err}`); + return done(err); + } + console.log(stdout); + console.log(stderr); + done(); + }); +}); + task('tsc:schematics:lib', done => { exec(`npm run tsc -- -p ./projects/schematics/tsconfig.json`, (err, stdout, stderr) => { if (err) { @@ -52,6 +69,16 @@ task('clean:schematics:lib', () => { return src('./dist/ng-schematics', { read: false, allowEmpty: true }).pipe(clean()); }); +// Removes the compiled schematics output of the library informed by the lib argument. +// Ensures a clean state for tests (e.g. avoids a leftover `dist//package.json` with +// `"type": "module"` from a previous production build breaking the CommonJS spec execution). +task('clean:schematics', () => { + const lib = argv.lib; + const distLib = lib === 'ui' ? 'components' : lib; + + return src(`./dist/ng-${distLib}`, { read: false, allowEmpty: true }).pipe(clean()); +}); + /** * build schematics of library informed by lib argument * @@ -59,5 +86,12 @@ task('clean:schematics:lib', () => { */ task('build:schematics', series('tsc:schematics', 'copy-resources:schematics')); +/** + * build schematics (including *.spec.ts files) so they can be executed with jasmine. + * + * ex: gulp build:schematics:spec --lib ui + */ +task('build:schematics:spec', series('tsc:schematics', 'copy-resources:schematics', 'tsc:schematics:spec')); + /** build ./project/schematics */ task('build:schematics:lib', series('clean:schematics:lib', 'tsc:schematics:lib', 'copy-resources:schematics:lib')); diff --git a/tsconfig.json b/tsconfig.json index 9b3b4da874..a1eb3c9cac 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,9 @@ { "compileOnSave": false, "compilerOptions": { - "baseUrl": "./", "outDir": "./dist/out-tsc", + "strict": false, + "esModuleInterop": true, "sourceMap": true, "declaration": false, "module": "es2022",