From c8ba057fe0cdcd123fd6457c03e915e6feccb2a7 Mon Sep 17 00:00:00 2001 From: Lance Finney Date: Mon, 27 May 2024 10:27:15 -0500 Subject: [PATCH] Additions/52 lazy load component (#963) * feat: create challenge 52 on lazy load component Initial boilerplate from `nx g @angular-challenges/cli:challenge` * feat: revert to NgModule Copy of 31 * feat: initial version of starting point * feat: add documentation * feat: pr tweaks Add author file Remove thomas from the contributor list Add a more direct hint * feat: pr tweaks Update "Go to the latest Challenge" link --- README.md | 2 +- .../52-lazy-load-component/.eslintrc.json | 36 ++++++++ apps/angular/52-lazy-load-component/README.md | 13 +++ .../52-lazy-load-component/jest.config.ts | 22 +++++ .../52-lazy-load-component/project.json | 79 ++++++++++++++++++ .../src/app/app.component.ts | 22 +++++ .../src/app/app.module.ts | 12 +++ .../src/app/placeholder.component.ts | 17 ++++ .../src/app/top.component.ts | 17 ++++ .../src/assets/.gitkeep | 0 .../52-lazy-load-component/src/favicon.ico | Bin 0 -> 15086 bytes .../52-lazy-load-component/src/index.html | 13 +++ .../52-lazy-load-component/src/main.ts | 6 ++ .../52-lazy-load-component/src/styles.scss | 5 ++ .../52-lazy-load-component/src/test-setup.ts | 2 + .../52-lazy-load-component/tailwind.config.js | 14 ++++ .../52-lazy-load-component/tsconfig.app.json | 10 +++ .../tsconfig.editor.json | 6 ++ .../52-lazy-load-component/tsconfig.json | 33 ++++++++ .../52-lazy-load-component/tsconfig.spec.json | 15 ++++ challenge-number.json | 4 +- docs/src/content/authors/lance-finney.json | 6 ++ .../angular/52-lazy-load-component.md | 49 +++++++++++ .../signal/51-function-call-effect.md | 1 - docs/src/content/docs/es/index.mdx | 6 +- docs/src/content/docs/fr/index.mdx | 6 +- docs/src/content/docs/index.mdx | 13 +-- docs/src/content/docs/pt/index.mdx | 6 +- docs/src/content/docs/ru/index.mdx | 2 +- 29 files changed, 397 insertions(+), 20 deletions(-) create mode 100644 apps/angular/52-lazy-load-component/.eslintrc.json create mode 100644 apps/angular/52-lazy-load-component/README.md create mode 100644 apps/angular/52-lazy-load-component/jest.config.ts create mode 100644 apps/angular/52-lazy-load-component/project.json create mode 100644 apps/angular/52-lazy-load-component/src/app/app.component.ts create mode 100644 apps/angular/52-lazy-load-component/src/app/app.module.ts create mode 100644 apps/angular/52-lazy-load-component/src/app/placeholder.component.ts create mode 100644 apps/angular/52-lazy-load-component/src/app/top.component.ts create mode 100644 apps/angular/52-lazy-load-component/src/assets/.gitkeep create mode 100644 apps/angular/52-lazy-load-component/src/favicon.ico create mode 100644 apps/angular/52-lazy-load-component/src/index.html create mode 100644 apps/angular/52-lazy-load-component/src/main.ts create mode 100644 apps/angular/52-lazy-load-component/src/styles.scss create mode 100644 apps/angular/52-lazy-load-component/src/test-setup.ts create mode 100644 apps/angular/52-lazy-load-component/tailwind.config.js create mode 100644 apps/angular/52-lazy-load-component/tsconfig.app.json create mode 100644 apps/angular/52-lazy-load-component/tsconfig.editor.json create mode 100644 apps/angular/52-lazy-load-component/tsconfig.json create mode 100644 apps/angular/52-lazy-load-component/tsconfig.spec.json create mode 100644 docs/src/content/authors/lance-finney.json create mode 100644 docs/src/content/docs/challenges/angular/52-lazy-load-component.md diff --git a/README.md b/README.md index 6accbf4..cf4f2b3 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ If you would like to propose a challenge, this project is open source, so feel f ## Challenges -Check [all 51 challenges](https://angular-challenges.vercel.app/) +Check [all 52 challenges](https://angular-challenges.vercel.app/) ## Contributors ✨ diff --git a/apps/angular/52-lazy-load-component/.eslintrc.json b/apps/angular/52-lazy-load-component/.eslintrc.json new file mode 100644 index 0000000..8ebcbfd --- /dev/null +++ b/apps/angular/52-lazy-load-component/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/angular/52-lazy-load-component/README.md b/apps/angular/52-lazy-load-component/README.md new file mode 100644 index 0000000..58d2922 --- /dev/null +++ b/apps/angular/52-lazy-load-component/README.md @@ -0,0 +1,13 @@ +# lazy-load-component + +> author: thomas-laforge + +### Run Application + +```bash +npx nx serve angular-lazy-load-component +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/angular/52-lazy-load-component/). diff --git a/apps/angular/52-lazy-load-component/jest.config.ts b/apps/angular/52-lazy-load-component/jest.config.ts new file mode 100644 index 0000000..a0fd110 --- /dev/null +++ b/apps/angular/52-lazy-load-component/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +export default { + displayName: 'angular-lazy-load-component', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/apps/angular/52-lazy-load-component', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/apps/angular/52-lazy-load-component/project.json b/apps/angular/52-lazy-load-component/project.json new file mode 100644 index 0000000..7767de5 --- /dev/null +++ b/apps/angular/52-lazy-load-component/project.json @@ -0,0 +1,79 @@ +{ + "name": "angular-lazy-load-component", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/angular/52-lazy-load-component/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/angular/52-lazy-load-component", + "index": "apps/angular/52-lazy-load-component/src/index.html", + "browser": "apps/angular/52-lazy-load-component/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/angular/52-lazy-load-component/tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "apps/angular/52-lazy-load-component/src/favicon.ico", + "apps/angular/52-lazy-load-component/src/assets" + ], + "styles": ["apps/angular/52-lazy-load-component/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-lazy-load-component:build:production" + }, + "development": { + "buildTarget": "angular-lazy-load-component:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "angular-lazy-load-component:build" + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "apps/angular/52-lazy-load-component/jest.config.ts" + } + } + } +} diff --git a/apps/angular/52-lazy-load-component/src/app/app.component.ts b/apps/angular/52-lazy-load-component/src/app/app.component.ts new file mode 100644 index 0000000..ccad632 --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/app.component.ts @@ -0,0 +1,22 @@ +import { Component, signal } from '@angular/core'; + +@Component({ + selector: 'app-root', + template: ` +
+ @if (topLoaded()) { + + } @else { + + + } +
+ `, +}) +export class AppComponent { + topLoaded = signal(false); +} diff --git a/apps/angular/52-lazy-load-component/src/app/app.module.ts b/apps/angular/52-lazy-load-component/src/app/app.module.ts new file mode 100644 index 0000000..b5d430e --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/app.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppComponent } from './app.component'; +import { PlaceholderComponent } from './placeholder.component'; +import { TopComponent } from './top.component'; + +@NgModule({ + declarations: [AppComponent, PlaceholderComponent, TopComponent], + imports: [BrowserModule], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/apps/angular/52-lazy-load-component/src/app/placeholder.component.ts b/apps/angular/52-lazy-load-component/src/app/placeholder.component.ts new file mode 100644 index 0000000..051e394 --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/placeholder.component.ts @@ -0,0 +1,17 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-placeholder', + template: ` + I'm a placeholder component. + `, + styles: ` + :host { + display: grid; + padding: 20px; + background-color: #f0f0f0; + height: 50%; + } + `, +}) +export class PlaceholderComponent {} diff --git a/apps/angular/52-lazy-load-component/src/app/top.component.ts b/apps/angular/52-lazy-load-component/src/app/top.component.ts new file mode 100644 index 0000000..d9104be --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/app/top.component.ts @@ -0,0 +1,17 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-top', + template: ` + I am a very heavy, expensive component that should be lazy loaded. + `, + styles: ` + :host { + display: grid; + padding: 20px; + background-color: #f0f0f0; + height: 50%; + } + `, +}) +export class TopComponent {} diff --git a/apps/angular/52-lazy-load-component/src/assets/.gitkeep b/apps/angular/52-lazy-load-component/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/angular/52-lazy-load-component/src/favicon.ico b/apps/angular/52-lazy-load-component/src/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..317ebcb2336e0833a22dddf0ab287849f26fda57 GIT binary patch literal 15086 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 + + + + angular-lazy-load-component + + + + + + + + diff --git a/apps/angular/52-lazy-load-component/src/main.ts b/apps/angular/52-lazy-load-component/src/main.ts new file mode 100644 index 0000000..16de236 --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/main.ts @@ -0,0 +1,6 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app/app.module'; + +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/apps/angular/52-lazy-load-component/src/styles.scss b/apps/angular/52-lazy-load-component/src/styles.scss new file mode 100644 index 0000000..77e408a --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/styles.scss @@ -0,0 +1,5 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* You can add global styles to this file, and also import other style files */ diff --git a/apps/angular/52-lazy-load-component/src/test-setup.ts b/apps/angular/52-lazy-load-component/src/test-setup.ts new file mode 100644 index 0000000..15de72a --- /dev/null +++ b/apps/angular/52-lazy-load-component/src/test-setup.ts @@ -0,0 +1,2 @@ +import '@testing-library/jest-dom'; +import 'jest-preset-angular/setup-jest'; diff --git a/apps/angular/52-lazy-load-component/tailwind.config.js b/apps/angular/52-lazy-load-component/tailwind.config.js new file mode 100644 index 0000000..38183db --- /dev/null +++ b/apps/angular/52-lazy-load-component/tailwind.config.js @@ -0,0 +1,14 @@ +const { createGlobPatternsForDependencies } = require('@nx/angular/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/apps/angular/52-lazy-load-component/tsconfig.app.json b/apps/angular/52-lazy-load-component/tsconfig.app.json new file mode 100644 index 0000000..5822042 --- /dev/null +++ b/apps/angular/52-lazy-load-component/tsconfig.app.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [] + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/52-lazy-load-component/tsconfig.editor.json b/apps/angular/52-lazy-load-component/tsconfig.editor.json new file mode 100644 index 0000000..a8ac182 --- /dev/null +++ b/apps/angular/52-lazy-load-component/tsconfig.editor.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": {}, + "exclude": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] +} diff --git a/apps/angular/52-lazy-load-component/tsconfig.json b/apps/angular/52-lazy-load-component/tsconfig.json new file mode 100644 index 0000000..4383e7e --- /dev/null +++ b/apps/angular/52-lazy-load-component/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/apps/angular/52-lazy-load-component/tsconfig.spec.json b/apps/angular/52-lazy-load-component/tsconfig.spec.json new file mode 100644 index 0000000..1a4817a --- /dev/null +++ b/apps/angular/52-lazy-load-component/tsconfig.spec.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node", "@testing-library/jest-dom"] + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/challenge-number.json b/challenge-number.json index 7891d9a..024679a 100644 --- a/challenge-number.json +++ b/challenge-number.json @@ -1,6 +1,6 @@ { - "total": 51, - "🟢": 20, + "total": 52, + "🟢": 21, "🟠": 121, "🔴": 209 } diff --git a/docs/src/content/authors/lance-finney.json b/docs/src/content/authors/lance-finney.json new file mode 100644 index 0000000..be44e3e --- /dev/null +++ b/docs/src/content/authors/lance-finney.json @@ -0,0 +1,6 @@ +{ + "name": "Lance Finney", + "twitter": "https://twitter.com/LMFinneyCoder", + "linkedin": "https://www.linkedin.com/in/lmfinney/", + "github": "https://github.com/LMFinney" +} diff --git a/docs/src/content/docs/challenges/angular/52-lazy-load-component.md b/docs/src/content/docs/challenges/angular/52-lazy-load-component.md new file mode 100644 index 0000000..6f638c8 --- /dev/null +++ b/docs/src/content/docs/challenges/angular/52-lazy-load-component.md @@ -0,0 +1,49 @@ +--- +title: 🟢 Lazy Load a Component +description: Challenge 52 is about understanding how to lazy load a component in Angular. +author: lance-finney +contributors: + - LMFinney +challengeNumber: 52 +command: angular-lazy-load-component +sidebar: + order: 21 + badge: New +--- + +## Information + +Angular has long had route-based lazy loading for entire modules, but lazy loading individual components was much more complicated. This challenge is about understanding how to lazy load a component easily with a feature that was introduced in Angular 17. + +## Statement + +This is a simple application that can display a `TopComponent` that we are pretending would slow the application down if it were part of the initial bundle (it actually contains just a bit of text, but we are pretending). + +The current implementation shows a `PlaceholderComponent` until the user clicks a button to display the `TopComponent`. However, even though the `TopComponent` isn't visible until the button is clicked, it is still loaded as part of the initial bundle. + +Use a new feature of Angular 17 to lazy load the `TopComponent` so that it is visible _and loaded_ when the user clicks the button to display it. + +When you are done, you should be able to see the `TopComponent` being loaded into the browser in a separate bundle when you click the button to display it. In Chrome, you should see this by opening the DevTools, going to the Network tab, and then clicking the button to display the `TopComponent`. + +## Hints + +
+ Hint 1 + +You should be able to remove the `topLoaded` signal when you are done. + +
+ +
+ Hint 2 + +The new Angular feature will hide the `TopComponent` from view, but it will still be loaded in the initial bundle unless you change how both `AppComponent` and `TopComponent` are defined in their decorators. This challenge start with the old `NgModule`-based architecture, but you will need to change it to use the new feature. + +
+ +
+ Hint 3 + +The new feature is [Deferrable Views](https://angular.dev/guide/defer), which provides several different triggers. One of them is ideal for this challenge. + +
diff --git a/docs/src/content/docs/challenges/signal/51-function-call-effect.md b/docs/src/content/docs/challenges/signal/51-function-call-effect.md index 9a25314..e2a9469 100644 --- a/docs/src/content/docs/challenges/signal/51-function-call-effect.md +++ b/docs/src/content/docs/challenges/signal/51-function-call-effect.md @@ -8,7 +8,6 @@ challengeNumber: 51 command: signal-function-call-effect sidebar: order: 20 - badge: New --- ## Information diff --git a/docs/src/content/docs/es/index.mdx b/docs/src/content/docs/es/index.mdx index cefa56b..dabaa29 100644 --- a/docs/src/content/docs/es/index.mdx +++ b/docs/src/content/docs/es/index.mdx @@ -13,7 +13,7 @@ hero: icon: right-arrow variant: primary - text: Ir al Desafío más reciente - link: /es/challenges/signal/51-function-call-effect + link: /es/challenges/angular/52-lazy-load-component/ icon: rocket - text: Dar una estrella link: https://github.com/tomalaforge/angular-challenges @@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro'; import SubscriptionForm from '../../../components/SubscriptionForm.astro'; - - Este repositorio contiene 51 Desafíos relacionados con Angular, Nx, RxJS, Ngrx y Typescript. + + Este repositorio contiene 52 Desafíos relacionados con Angular, Nx, RxJS, Ngrx y Typescript. Estos desafíos se resuelven en torno a problemas de la vida real o características específicas para mejorar tus habilidades. diff --git a/docs/src/content/docs/fr/index.mdx b/docs/src/content/docs/fr/index.mdx index e510057..2982de9 100644 --- a/docs/src/content/docs/fr/index.mdx +++ b/docs/src/content/docs/fr/index.mdx @@ -13,7 +13,7 @@ hero: icon: right-arrow variant: primary - text: Aller au dernier Challenge - link: /fr/challenges/signal/51-function-call-effect + link: /fr/challenges/angular/52-lazy-load-component/ icon: rocket - text: Donne une étoile link: https://github.com/tomalaforge/angular-challenges @@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro'; import SubscriptionForm from '../../../components/SubscriptionForm.astro'; - - Ce répertoire rassemble 51 Défis liés à Angular, Nx, RxJS, Ngrx et Typescript. Ces défis portent sur des problèmes réels ou des fonctionnalités spécifiques pour améliorer vos compétences. + + Ce répertoire rassemble 52 Défis liés à Angular, Nx, RxJS, Ngrx et Typescript. Ces défis portent sur des problèmes réels ou des fonctionnalités spécifiques pour améliorer vos compétences. diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx index 60f3a6d..f44194f 100644 --- a/docs/src/content/docs/index.mdx +++ b/docs/src/content/docs/index.mdx @@ -13,7 +13,7 @@ hero: icon: right-arrow variant: primary - text: Go to the latest Challenge - link: /challenges/signal/51-function-call-effect + link: /challenges/angular/52-lazy-load-component icon: rocket - text: Give a star link: https://github.com/tomalaforge/angular-challenges @@ -27,8 +27,8 @@ import MyIcon from '../../components/MyIcon.astro'; import SubscriptionForm from '../../components/SubscriptionForm.astro'; - - This repository gathers 51 Challenges related to Angular, Nx, RxJS, Ngrx and Typescript. + + This repository gathers 52 Challenges related to Angular, Nx, RxJS, Ngrx and Typescript. These challenges resolve around real-life issues or specific features to elevate your skills. @@ -43,8 +43,8 @@ import SubscriptionForm from '../../components/SubscriptionForm.astro'; - Learning and practicing a new framework is always challenging. This set of -  challenges provide real-world use cases to apply what you've been learning. + Learning and practicing a new framework is always challenging. This set of   + challenges provide real-world use cases to apply what you've been learning. Anyone can comment or offer assistance. Learning alone is great, but learning alongside others will get you further. @@ -57,7 +57,8 @@ import SubscriptionForm from '../../components/SubscriptionForm.astro'; - By completing these challenges, you'll be ready for any technical questions that may come up during a frontend job interview. + By completing these challenges, you'll be ready for any technical questions + that may come up during a frontend job interview. diff --git a/docs/src/content/docs/pt/index.mdx b/docs/src/content/docs/pt/index.mdx index e399368..84c7e55 100644 --- a/docs/src/content/docs/pt/index.mdx +++ b/docs/src/content/docs/pt/index.mdx @@ -13,7 +13,7 @@ hero: icon: right-arrow variant: primary - text: Ir para o desafio mais recente - link: /pt/challenges/signal/51-function-call-effect + link: /pt/challenges/angular/52-lazy-load-component/ icon: rocket - text: Dar uma estrela link: https://github.com/tomalaforge/angular-challenges @@ -26,8 +26,8 @@ import MyIcon from '../../../components/MyIcon.astro'; import SubscriptionForm from '../../../components/SubscriptionForm.astro'; - - Este repositório possui 51 Desafios relacionados a Angular, Nx, RxJS, + + Este repositório possui 52 Desafios relacionados a Angular, Nx, RxJS, Ngrx e Typescript. Esses desafios são voltados para problemas reais ou funcionalidades específicas afim de melhorar suas habilidades. diff --git a/docs/src/content/docs/ru/index.mdx b/docs/src/content/docs/ru/index.mdx index 79f2bd2..0e3e1bf 100644 --- a/docs/src/content/docs/ru/index.mdx +++ b/docs/src/content/docs/ru/index.mdx @@ -13,7 +13,7 @@ hero: icon: right-arrow variant: primary - text: Перейти к последней задаче - link: /ru/challenges/signal/51-function-call-effect + link: /ru/challenges/angular/52-lazy-load-component/ icon: rocket - text: Добавить звезду link: https://github.com/tomalaforge/angular-challenges