diff --git a/.gitignore b/.gitignore index b0decd9..5472d6b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,6 @@ node_modules # IDE - VSCode .vscode/* -!.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json @@ -41,4 +40,4 @@ Thumbs.db .angular TODO.md -.nx/cache \ No newline at end of file +.nx/cache diff --git a/.vscode/settings.json b/.vscode/settings.json index 1471fb9..e0a1291 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,6 @@ { - "eslint.validate": ["json"] + "eslint.validate": [ + "json" + ], + "cSpell.language": "en,es-ES" } diff --git a/docs/src/content/docs/es/challenges/angular/3-directive-enhancement.md b/docs/src/content/docs/es/challenges/angular/3-directive-enhancement.md new file mode 100644 index 0000000..e4514ac --- /dev/null +++ b/docs/src/content/docs/es/challenges/angular/3-directive-enhancement.md @@ -0,0 +1,52 @@ +--- +title: 馃煚 Mejorar Directiva +description: El desaf铆o 3 se trata de una directive incorporada. +author: thomas-laforge +challengeNumber: 3 +command: angular-ngfor-enhancement +blogLink: https://medium.com/@thomas.laforge/ngfor-enhancement-716b44656a6c +sidebar: + order: 101 +--- + +:::note[Nota] + +Este desaf铆o puede parecer obsoleto ahora que disponemos del nuevo control de flujo y el bloque vac铆o dentro de los bloques `@for`. Sin embargo, las **directivas estructuradas** no ser谩n borradas en ning煤n momento, de esta manera usted tendr谩 la oportunidad de aprender bastante de este desaf铆o. + +::: + +## Informaci贸n + +Las Directivas en Angular Framework son una herramienta muy poderosa. Usted puede aplicar los principios de DRY para aplicar una l贸gica compartida dentro de una directiva y aplicarla a cualquier componente. + +Pero el verdadero poder esta en mejorar una directiva ya existente que adem谩s **no te pertenece**. + +## Declaraci贸n + +En este desaf铆o, queremos mostrar una lista de personas. Si la lista esta vac铆a, usted deber谩 mostrar _" the list is empty !! "_. (La lista esta vac铆a) + +:::note[Nota] + +En caso que hayan test autom谩ticos para validar este desaf铆o, se ha preferido dejar la frase en ingles, en vez de utilizar una traducci贸n directa al espa帽ol. + +::: + +```typescript + +
+ {{ person.name }} +
+
+ The list is empty !! +``` + +Queremos desechar el uso de ng-container al escribir: + +```typescript +
+ {{ person.name }} +
+ The list is empty !! +``` + +La meta de este desaf铆o es **mejorar la directiva ngFor** diff --git a/docs/src/content/docs/es/challenges/angular/4-context-outlet-typed.md b/docs/src/content/docs/es/challenges/angular/4-context-outlet-typed.md new file mode 100644 index 0000000..0196812 --- /dev/null +++ b/docs/src/content/docs/es/challenges/angular/4-context-outlet-typed.md @@ -0,0 +1,46 @@ +--- +title: 馃敶 ContextOutlet en forma de tipo +description: El desaf铆o 4 se trata de tipificar de manera fuerte las directivas de ngContextOutlet +author: thomas-laforge +challengeNumber: 4 +command: angular-context-outlet-type +blogLink: https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6 +sidebar: + order: 201 +--- + +## Informaci贸n + +:::note[Nota] + +Las declaraciones de tipos permanecer谩n en ingles, asi como los nombres de los objetos y sus miembros. + +::: + +Angular ofrece la function est谩tica [`ngTemplateContextGuard`](https://angular.io/guide/structural-directives#typing-the-directives-context) para reforzar el tipo de una directiva estructural. + +Sin embargo, el contexto de **NgTemplateOutlet** es de tipo **Object**. Con la ayuda de la guardia mencionada anteriormente, podemos mejorar ese comportamiento. + +## Declaraci贸n + +En este desaf铆o, queremos aprender como reforzar el tipo de nuestro ng-template en AppComponent. + +Este desaf铆o ofrece dos niveles de complejidad: + +### Nivel 1: una Interfase conocida + +A continuaci贸n tenemos estas lineas de c贸digo: + +![Any en Person](../../../../../assets/4/unknown-person.png) + +Como se puede observar, "name" es de tipo "any". La meta es inferir el tipo correcto. + +### Nivel 2: una Interfase gen茅rica + +Actualmente, tenemos estas lineas de c贸digo: + +![Any en Student](../../../../../assets/4/unknown-student.png) + +Como puede apreciarse, "student" es de tipo "any". Queremos inferir el tipo de manera correcta. + +Pero en esta parte, podemos pasar a ListComponent, una lista de **cualquier cosa**. Aun asi, queremos inferir de manera correcta el tipo de dato. diff --git a/docs/src/content/docs/es/challenges/angular/5-crud.md b/docs/src/content/docs/es/challenges/angular/5-crud.md new file mode 100644 index 0000000..d0c5903 --- /dev/null +++ b/docs/src/content/docs/es/challenges/angular/5-crud.md @@ -0,0 +1,50 @@ +--- +title: 馃煝 Aplicaci贸n CRUD +description: El desaf铆o 5 se trata de refactorizar una aplicaci贸n CRUD. +author: thomas-laforge +challengeNumber: 5 +command: angular-crud +sidebar: + order: 2 +--- + +## Informaci贸n + +Comunicar y tener acceso a un estado global o local en sincronizaci贸n con tu backend es el coraz贸n de cualquier aplicaci贸n. Usted necesita dominar las siguientes mejores practicas para construir aplicaciones en Angular de manera solida y confiable. + +## Declaraci贸n + +En este desafi贸 tenemos una peque帽a aplicaci贸n CRUD, la cual puede obtener una lista de COSAS POR HACER, actualizar y borrar algunos de los elementos de dicha lista. + +Actualmente tenemos un ejemplo funcional, pero repleto de practicas err贸neas. + +### Paso 1: Refactorizar con mejores practicas. + +Usted necesitara: + +- Evite el uso del tipo **any**. Use interfaces para prevenir los errores de tipo en Typescript. +- Use un **servicio separado** para todas las llamadas de http, y use **Signals** para la lista de cosas por hacer. +- No **mutar** los datos + +```typescript +// Evite esto +this.todos[todoUpdated.id - 1] = todoUpdated; + +// en vez de ello, use algo como esto, pero necesitara mejorar la l贸gica de manera que preserve el mismo orden. +this.todos = [...this.todos.filter((t) => t.id !== todoUpdated.id), todoUpdated]; +``` + +### Step 2: Mejorar + +- Agregue un bot贸n para **borrar** : _Documentaci贸n de la API falsa_ +- Opera de manera correcta los **errores**. _(Globalmente)_ +- Agrega un indicador global de **carga**. _Puedes utilizar MatProgressSpinnerModule_ + +### Step 3: Mantenibilidad!! adiciona algunos tests + +- Adiciona 2/3 tests + +### Step 4: Creatividad!!! Domina tu estado. + +- Usa de manera apropiada **un component store de ngrx**, **ngrx/store**, **rxAngular**, **tanstack-query** o **ngrx/signal-store** como estado local de tu componente. +- Tener un indicador de Carga/Error **localizado**. Por ejemplo: Solo en el elemento seleccionado de la lista siendo procesado y **desactivar** todos los botones de dicho elemento. _(Pista: Necesitaras crear un ItemComponent)_ diff --git a/docs/src/content/docs/es/challenges/angular/6-permissions.md b/docs/src/content/docs/es/challenges/angular/6-permissions.md new file mode 100644 index 0000000..d6613b3 --- /dev/null +++ b/docs/src/content/docs/es/challenges/angular/6-permissions.md @@ -0,0 +1,61 @@ +--- +title: 馃煚 Directiva Estructural +description: El Desaf铆o 6 se trata de generar una Directiva Estructural que manipule los permisos +author: thomas-laforge +challengeNumber: 6 +command: angular-permissions +blogLink: https://medium.com/@thomas.laforge/create-a-custom-structural-directive-to-manage-permissions-like-a-pro-11a1acad30ad +sidebar: + order: 102 +--- + +## Informaci贸n + +Las Directivas Estructurales son in concepto importante que necesitaras dominar para mejorar tus habilidades y conocimientos en Angular. Esta es la primera parte del desaf铆o. + +En Angular, "Guard" es un concepto muy importante por que siempre las vas a necesitar en cada aplicaci贸n que construyas. + +## Declaraci贸n + +En LoginComponent, encontraras 6 botones correspondientes a 6 tipos de roles de usuario: + +:::note[Nota] + +Se dejaran los nombres de los roles en ingles. + +::: + +- Admin (Administrador) +- Manager (Gerente) +- Reader (Lector) +- Writer (Escritor) +- Reader and Writer (Lector y escritor) +- Client (Cliente) +- Everyone (Todos) + +## Paso 1 + +En `InformationComponent`, necesitaras mostrar la pieza de informaci贸n correcta por cada rol usando una directiva estructural. + +### Restricciones: + +- No puedes usar `ngIf` o `@if` dentro de `InformationComponent`. +- No puedes importar un store dentro de `InformationComponent`. + +You should end up with something like below: + +```html +
Informaci贸n del Role1
+``` + +```html +
Informaci贸n del Role1 y Role2
+``` + +```html +
Informaci贸n solo para el Super Administrador
+``` + +## Paso 2 + +En `Routes.ts`, deber谩s usar la guardia `CanMatch` para dirigir a todos los usuarios al correcto `DashboardComponent`.