Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions projects/cdk/schematics/ng-update/v5/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ import {FINISH_SYMBOL, saveActiveProject, START_SYMBOL, titleLog} from 'ng-morph
import {TAIGA_VERSION} from '../../ng-add/constants/versions';
import {type TuiSchema} from '../../ng-add/schema';
import {getExecutionTime} from '../../utils/get-execution-time';
import {replaceIdentifiers} from '../steps/replace-identifier';
import {getFileSystem} from '../utils/get-file-system';
import {replaceFunctions} from '../utils/replace-functions';
import {REPLACE_FUNCTIONS} from './steps/constants/functions';
import {IDENTIFIERS_TO_REPLACE} from './steps/constants/identifiers-to-replace';
import {migrateTokens} from './steps/migrate-tokens/migrate-tokens';
import {updateTsConfig} from './steps/migrate-tokens/update-tsconfig';
import {migrateInputYearTemplates} from './steps/templates/migrate-input-year';

function main(options: TuiSchema): Rule {
return (tree: Tree, context: SchematicContext) => {
Expand All @@ -25,6 +28,8 @@ function main(options: TuiSchema): Rule {
migrateTokens(tree, options);
updateTsConfig(tree, options);
replaceFunctions(REPLACE_FUNCTIONS);
replaceIdentifiers(options, IDENTIFIERS_TO_REPLACE);
migrateInputYearTemplates(fileSystem, options);

fileSystem.commitEdits();
saveActiveProject();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {type ReplacementIdentifierMulti} from '../../../interfaces';

export const IDENTIFIERS_TO_REPLACE: ReplacementIdentifierMulti[] = [
{
from: {
name: 'TuiInputYearModule',
moduleSpecifier: '@taiga-ui/legacy',
},
to: {
name: 'TuiInputYear',
moduleSpecifier: '@taiga-ui/kit',
},
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import {
type DevkitFileSystem,
infoLog,
REPLACE_SYMBOL,
SMALL_TAB_SYMBOL,
SUCCESS_SYMBOL,
successLog,
type UpdateRecorder,
} from 'ng-morph';
import {type Element, type TextNode} from 'parse5/dist/tree-adapters/default';

import {ALL_TS_FILES} from '../../../../constants/file-globs';
import {type TuiSchema} from '../../../../ng-add/schema';
import {setupProgressLogger} from '../../../../utils/progress';
import {findElementsByTagName} from '../../../../utils/templates/elements';
import {getComponentTemplates} from '../../../../utils/templates/get-component-templates';
import {
getPathFromTemplateResource,
getTemplateFromTemplateResource,
getTemplateOffset,
} from '../../../../utils/templates/template-resource';
import {type TemplateResource} from '../../../interfaces/template-resource';
import {replaceTag} from '../../../utils/templates';

function migrateInputYear({
resource,
recorder,
fileSystem,
}: {
fileSystem: DevkitFileSystem;
recorder: UpdateRecorder;
resource: TemplateResource;
}): void {
const template = getTemplateFromTemplateResource(resource, fileSystem);
const templateOffset = getTemplateOffset(resource);
const elements = findElementsByTagName(template, 'tui-input-year');

elements.forEach((element) => {
const sourceCodeLocation = element.sourceCodeLocation;

replaceTag(
recorder,
sourceCodeLocation,
'tui-input-year',
'tui-textfield',
templateOffset,
);

const labelIndex = element.childNodes.findIndex(
(node) => node.nodeName === '#text' && (node as TextNode)?.value.trim(),
);

if (labelIndex !== -1) {
const labelNode = element.childNodes[labelIndex];
const labelTextStart =
(labelNode?.sourceCodeLocation?.startOffset ?? 0) + templateOffset;
const labelTextEnd =
(labelNode?.sourceCodeLocation?.endOffset ?? 0) + templateOffset;

recorder.insertRight(labelTextStart, '\n<label tuiLabel>');
recorder.insertRight(labelTextEnd, '</label>\n');
}

const calendarInsertOffset =
(sourceCodeLocation?.endTag?.startOffset ?? 0) + templateOffset;

recorder.insertRight(
calendarInsertOffset,
'\n<tui-calendar-year *tuiTextfieldDropdown />\n',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'\n<tui-calendar-year *tuiTextfieldDropdown />\n',
'\n<tui-calendar-year *tuiDropdown />\n',

);

element.childNodes
.filter((node): node is Element => node.nodeName === 'input')
.forEach((inputNode) => {
inputNode.attrs.forEach((attr) => {
if (/^tuiTextfield$|^tuiTextfieldLegacy$/i.exec(attr.name)) {
const {startOffset = 0, endOffset = 0} =
inputNode.sourceCodeLocation?.attrs?.[attr.name] ?? {};

recorder.remove(
templateOffset + startOffset,
endOffset - startOffset,
);

recorder.insertRight(
templateOffset + startOffset,
'tuiInputYear',
);
}
});
});
});
}

export function migrateInputYearTemplates(
fileSystem: DevkitFileSystem,
options: TuiSchema,
): void {
!options['skip-logs'] &&
infoLog(`${SMALL_TAB_SYMBOL}${REPLACE_SYMBOL} migrating templates...`);

const componentWithTemplatesPaths = getComponentTemplates(ALL_TS_FILES);

const progressLog = setupProgressLogger({
total: componentWithTemplatesPaths.length,
});

componentWithTemplatesPaths.forEach((resource) => {
const path = fileSystem.resolve(getPathFromTemplateResource(resource));
const recorder = fileSystem.edit(path);

!options['skip-logs'] && progressLog('tui-input-year migration', true);
migrateInputYear({resource, fileSystem, recorder});
});

!options['skip-logs'] &&
successLog(`${SMALL_TAB_SYMBOL}${SUCCESS_SYMBOL} templates migrated \n`);
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,16 @@
import {join} from 'node:path';

import {HostTree} from '@angular-devkit/schematics';
import {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing';
import {
createProject,
resetActiveProject,
saveActiveProject,
setActiveProject,
} from 'ng-morph';
import {resetActiveProject} from 'ng-morph';

const collectionPath = join(__dirname, '../../../migration.json');
import {runMigration} from '../../../utils/run-migration';

describe('ng-update', () => {
const runMigration = async (component: string): Promise<string> => {
const host = new UnitTestTree(new HostTree());
const runner = new SchematicTestRunner('schematics', collectionPath);

setActiveProject(createProject(host));

host.create('test/app/test.ts', component);
host.create('test/app/test.html', '');
host.create('package.json', '{}');

await runner.runSchematic('updateToV5', {'skip-logs': true}, host);

saveActiveProject();

return host.readContent('test/app/test.ts');
};
const collection = join(__dirname, '../../../migration.json');

it('migrate tuiIsNativeFocused to tuiIsFocused', async () => {
expect(
await runMigration(`
const {component} = await runMigration({
collection,
component: `
import {tuiIsNativeFocused} from '@taiga-ui/cdk';

@Component({})
Expand All @@ -41,9 +20,10 @@ export class Test {
this.el.blur();
}
}
}
`),
).toEqual(`
}`,
});

expect(component).toEqual(`
import {tuiIsFocused} from '@taiga-ui/cdk';

@Component({})
Expand All @@ -53,13 +33,13 @@ export class Test {
this.el.blur();
}
}
}
`);
}`);
});

it('migrate tuiIsNativeFocusedIn to tuiIsFocusedIn', async () => {
expect(
await runMigration(`
const {component} = await runMigration({
collection,
component: `
import {tuiIsNativeFocusedIn} from '@taiga-ui/cdk';

@Component({})
Expand All @@ -69,9 +49,10 @@ export class Test {
this.origin?.focus({preventScroll: true});
}
}
}
`),
).toEqual(`
}`,
});

expect(component).toEqual(`
import {tuiIsFocusedIn} from '@taiga-ui/cdk';

@Component({})
Expand All @@ -81,32 +62,32 @@ export class Test {
this.origin?.focus({preventScroll: true});
}
}
}
`);
}`);
});

it('migrate tuiGetNativeFocused to tuiGetFocused', async () => {
expect(
await runMigration(`
const {component} = await runMigration({
collection,
component: `
import {tuiGetNativeFocused} from '@taiga-ui/cdk';

@Component({})
export class Test {
private get focused(): boolean {
return this.dropdown.el.contains(tuiGetNativeFocused(this.doc));
}
}
`),
).toEqual(`
}`,
});

expect(component).toEqual(`
import {tuiGetFocused} from '@taiga-ui/cdk';

@Component({})
export class Test {
private get focused(): boolean {
return this.dropdown.el.contains(tuiGetFocused(this.doc));
}
}
`);
}`);
});

afterEach(() => resetActiveProject());
Expand Down
Loading
Loading