mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-10 04:43:03 -05:00
docs: translated to ES-LA exercises 3,4,5 and 6
docs: fixed markdown issues, minor typos docs: fixed markdown issues, minor typos docs: rephrasing translator comments and notes docs: some fix comments from PR docs: some fix comments from PR docs: some fix comments from PR docs: images fixed
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -19,7 +19,6 @@ node_modules
|
|||||||
|
|
||||||
# IDE - VSCode
|
# IDE - VSCode
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
!.vscode/tasks.json
|
||||||
!.vscode/launch.json
|
!.vscode/launch.json
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
|||||||
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -1,3 +1,6 @@
|
|||||||
{
|
{
|
||||||
"eslint.validate": ["json"]
|
"eslint.validate": [
|
||||||
|
"json"
|
||||||
|
],
|
||||||
|
"cSpell.language": "en,es-ES"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
<ng-container *ngIf="persons.length > 0; else emptyList">
|
||||||
|
<div *ngFor="let person of persons">
|
||||||
|
{{ person.name }}
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<ng-template #emptyList>The list is empty !!</ng-template>
|
||||||
|
```
|
||||||
|
|
||||||
|
Queremos desechar el uso de ng-container al escribir:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
<div *ngFor="let person of persons; empty: emptyList">
|
||||||
|
{{ person.name }}
|
||||||
|
</div>
|
||||||
|
<ng-template #emptyList>The list is empty !!</ng-template>
|
||||||
|
```
|
||||||
|
|
||||||
|
La meta de este desafío es **mejorar la directiva ngFor**
|
||||||
@@ -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:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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.
|
||||||
50
docs/src/content/docs/es/challenges/angular/5-crud.md
Normal file
50
docs/src/content/docs/es/challenges/angular/5-crud.md
Normal file
@@ -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** : _<a href="https://jsonplaceholder.typicode.com/" target="_blank">Documentación de la API falsa</a>_
|
||||||
|
- 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)_
|
||||||
61
docs/src/content/docs/es/challenges/angular/6-permissions.md
Normal file
61
docs/src/content/docs/es/challenges/angular/6-permissions.md
Normal file
@@ -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
|
||||||
|
<div *hasRole="Role1">Información del Role1</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div *hasRole="['Role1', 'Role2']">Información del Role1 y Role2</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div *hasRoleSuperAdmin="true">Información solo para el Super Administrador</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Paso 2
|
||||||
|
|
||||||
|
En `Routes.ts`, deberás usar la guardia `CanMatch` para dirigir a todos los usuarios al correcto `DashboardComponent`.
|
||||||
Reference in New Issue
Block a user