diff --git a/projects/cdk/schematics/ng-update/v4/steps/migrate-templates.ts b/projects/cdk/schematics/ng-update/v4/steps/migrate-templates.ts index 964168d32335..06e7d6857420 100644 --- a/projects/cdk/schematics/ng-update/v4/steps/migrate-templates.ts +++ b/projects/cdk/schematics/ng-update/v4/steps/migrate-templates.ts @@ -31,6 +31,7 @@ import { TAGS_TO_REPLACE, } from './constants'; import { + migrateActiveZoneParent, migrateAvatar, migrateAxes, migrateBadge, @@ -121,6 +122,7 @@ export function migrateTemplates(fileSystem: DevkitFileSystem, options: TuiSchem migrateNumberPrecision, migrateNotification, migrateFilterPipe, + migrateActiveZoneParent, ] as const; const progressLog = setupProgressLogger({ diff --git a/projects/cdk/schematics/ng-update/v4/steps/templates/index.ts b/projects/cdk/schematics/ng-update/v4/steps/templates/index.ts index e0b2510d5cfb..f26893dcb4cf 100644 --- a/projects/cdk/schematics/ng-update/v4/steps/templates/index.ts +++ b/projects/cdk/schematics/ng-update/v4/steps/templates/index.ts @@ -1,3 +1,4 @@ +export * from './migrate-active-zone'; export * from './migrate-avatar'; export * from './migrate-axes'; export * from './migrate-badge'; diff --git a/projects/cdk/schematics/ng-update/v4/steps/templates/migrate-active-zone.ts b/projects/cdk/schematics/ng-update/v4/steps/templates/migrate-active-zone.ts new file mode 100644 index 000000000000..3dca05db9384 --- /dev/null +++ b/projects/cdk/schematics/ng-update/v4/steps/templates/migrate-active-zone.ts @@ -0,0 +1,58 @@ +import type {UpdateRecorder} from '@angular-devkit/schematics'; +import type {DevkitFileSystem} from 'ng-morph'; + +import { + findElementsByFn, + findElementsByTagName, + hasElementAttribute, +} from '../../../../utils/templates/elements'; +import {findAttr} from '../../../../utils/templates/inputs'; +import { + getTemplateFromTemplateResource, + getTemplateOffset, +} from '../../../../utils/templates/template-resource'; +import type {TemplateResource} from '../../../interfaces'; +import {removeAttrs} from '../utils/remove-attrs'; + +export function migrateActiveZoneParent({ + resource, + recorder, + fileSystem, +}: { + fileSystem: DevkitFileSystem; + recorder: UpdateRecorder; + resource: TemplateResource; +}): void { + const template = getTemplateFromTemplateResource(resource, fileSystem); + const templateOffset = getTemplateOffset(resource); + + const elements = findElementsByTagName(template, 'ng-template'); + + elements.forEach(({attrs, sourceCodeLocation, childNodes}) => { + const zoneAttr = findAttr(attrs, 'let-activeZone'); + + if (!sourceCodeLocation) { + return; + } + + if (zoneAttr) { + removeAttrs([zoneAttr], sourceCodeLocation, recorder, templateOffset); + } + + const children = findElementsByFn(childNodes, (el) => + hasElementAttribute(el, 'tuiActiveZoneParent'), + ); + + children.forEach(({attrs, sourceCodeLocation}) => { + const parentAttr = findAttr(attrs, 'tuiActiveZoneParent'); + + if (!parentAttr || !sourceCodeLocation) { + return; + } + + if (parentAttr) { + removeAttrs([parentAttr], sourceCodeLocation, recorder, templateOffset); + } + }); + }); +} diff --git a/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-active-zone.spec.ts b/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-active-zone.spec.ts new file mode 100644 index 000000000000..91c09ad6c3ef --- /dev/null +++ b/projects/cdk/schematics/ng-update/v4/tests/schematic-migrate-active-zone.spec.ts @@ -0,0 +1,132 @@ +import {join} from 'node:path'; + +import {HostTree} from '@angular-devkit/schematics'; +import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing'; +import type {TuiSchema} from '@taiga-ui/cdk/schematics/ng-add/schema'; +import { + createProject, + createSourceFile, + resetActiveProject, + saveActiveProject, + setActiveProject, +} from 'ng-morph'; + +import {createAngularJson} from '../../../utils/create-angular-json'; + +const collectionPath = join(__dirname, '../../../migration.json'); + +const COMPONENT_BEFORE = ` +@Component({ + standalone: true, + templateUrl: './test.template.html', +}) +export class Test { +}`; + +const TEMPLATE_BEFORE = ` + + + + + + Nested Select + + + +`; + +const TEMPLATE_AFTER = ` +
+ +
+ + + Nested Select + + + +`; + +describe('ng-update', () => { + let host: UnitTestTree; + let runner: SchematicTestRunner; + + beforeEach(() => { + host = new UnitTestTree(new HostTree()); + runner = new SchematicTestRunner('schematics', collectionPath); + + setActiveProject(createProject(host)); + + createMainFiles(); + + saveActiveProject(); + }); + + it('should migrate active zone parent in template', async () => { + const tree = await runner.runSchematic( + 'updateToV4', + {'skip-logs': process.env['TUI_CI'] === 'true'} as Partial, + host, + ); + + expect(tree.readContent('test/app/test.template.html')).toEqual(TEMPLATE_AFTER); + }); + + afterEach(() => { + resetActiveProject(); + }); +}); + +function createMainFiles(): void { + createSourceFile('test/app/test.component.ts', COMPONENT_BEFORE); + + createSourceFile('test/app/test.template.html', TEMPLATE_BEFORE); + + createAngularJson(); + createSourceFile( + 'package.json', + '{"dependencies": {"@angular/core": "~13.0.0", "@taiga-ui/addon-commerce": "~3.42.0"}}', + ); +}