From 58215fe349b694a45f41bf9f8b9a57872204b6f0 Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 30 Oct 2023 21:28:40 +0100 Subject: [PATCH 01/13] feat(chritsmas): create challenge for christmas --- README.md | 2 +- .../christmas-web-worker/.eslintrc.json | 19 ++ .../christmas-web-worker/README.md | 13 + .../christmas-web-worker/project.json | 81 +++++++ .../src/app/app.component.ts | 32 +++ .../src/app/app.config.ts | 5 + .../src/app/prime-number.service.ts | 30 +++ .../unknown-person.component.css | 223 ++++++++++++++++++ .../unknown-person.component.ts | 35 +++ .../christmas-web-worker/src/assets/.gitkeep | 0 .../christmas-web-worker/src/favicon.ico | Bin 0 -> 15086 bytes .../christmas-web-worker/src/index.html | 13 + .../christmas-web-worker/src/main.ts | 7 + .../christmas-web-worker/src/styles.scss | 5 + .../christmas-web-worker/tailwind.config.js | 14 ++ .../christmas-web-worker/tsconfig.app.json | 10 + .../christmas-web-worker/tsconfig.editor.json | 7 + .../christmas-web-worker/tsconfig.json | 29 +++ challenge-number.json | 4 +- .../challenges/angular/39-injection-token.md | 1 - .../performance/40-christmas-web-worker.md | 20 ++ docs/src/content/docs/index.mdx | 6 +- 22 files changed, 549 insertions(+), 7 deletions(-) create mode 100644 apps/performance/christmas-web-worker/.eslintrc.json create mode 100644 apps/performance/christmas-web-worker/README.md create mode 100644 apps/performance/christmas-web-worker/project.json create mode 100644 apps/performance/christmas-web-worker/src/app/app.component.ts create mode 100644 apps/performance/christmas-web-worker/src/app/app.config.ts create mode 100644 apps/performance/christmas-web-worker/src/app/prime-number.service.ts create mode 100644 apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.css create mode 100644 apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts create mode 100644 apps/performance/christmas-web-worker/src/assets/.gitkeep create mode 100644 apps/performance/christmas-web-worker/src/favicon.ico create mode 100644 apps/performance/christmas-web-worker/src/index.html create mode 100644 apps/performance/christmas-web-worker/src/main.ts create mode 100644 apps/performance/christmas-web-worker/src/styles.scss create mode 100644 apps/performance/christmas-web-worker/tailwind.config.js create mode 100644 apps/performance/christmas-web-worker/tsconfig.app.json create mode 100644 apps/performance/christmas-web-worker/tsconfig.editor.json create mode 100644 apps/performance/christmas-web-worker/tsconfig.json create mode 100644 docs/src/content/docs/challenges/performance/40-christmas-web-worker.md diff --git a/README.md b/README.md index 2680b4a..4250a0a 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 39 challenges](https://angular-challenges.vercel.app/) +Check [all 40 challenges](https://angular-challenges.vercel.app/) ## Contributors ✨ diff --git a/apps/performance/christmas-web-worker/.eslintrc.json b/apps/performance/christmas-web-worker/.eslintrc.json new file mode 100644 index 0000000..d3cd799 --- /dev/null +++ b/apps/performance/christmas-web-worker/.eslintrc.json @@ -0,0 +1,19 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": {} + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/performance/christmas-web-worker/README.md b/apps/performance/christmas-web-worker/README.md new file mode 100644 index 0000000..6da9394 --- /dev/null +++ b/apps/performance/christmas-web-worker/README.md @@ -0,0 +1,13 @@ +# Web workers + +> Author: Thomas Laforge + +### Run Application + +```bash +npx nx serve performance-christmas-web-worker +``` + +### Documentation and Instruction + +Challenge documentation is [here](https://angular-challenges.vercel.app/challenges/performance/40-christmas-web-worker/). diff --git a/apps/performance/christmas-web-worker/project.json b/apps/performance/christmas-web-worker/project.json new file mode 100644 index 0000000..0f33ede --- /dev/null +++ b/apps/performance/christmas-web-worker/project.json @@ -0,0 +1,81 @@ +{ + "name": "performance-christmas-web-worker", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "prefix": "app", + "sourceRoot": "apps/performance/christmas-web-worker/src", + "tags": [], + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:browser", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/performance/christmas-web-worker", + "index": "apps/performance/christmas-web-worker/src/index.html", + "main": "apps/performance/christmas-web-worker/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/performance/christmas-web-worker/tsconfig.app.json", + "assets": [ + "apps/performance/christmas-web-worker/src/favicon.ico", + "apps/performance/christmas-web-worker/src/assets" + ], + "styles": ["apps/performance/christmas-web-worker/src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "browserTarget": "performance-christmas-web-worker:build:production" + }, + "development": { + "browserTarget": "performance-christmas-web-worker:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "performance-christmas-web-worker:build" + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": [ + "apps/performance/christmas-web-worker/**/*.ts", + "apps/performance/christmas-web-worker/**/*.html" + ] + } + } + } +} diff --git a/apps/performance/christmas-web-worker/src/app/app.component.ts b/apps/performance/christmas-web-worker/src/app/app.component.ts new file mode 100644 index 0000000..a7e757f --- /dev/null +++ b/apps/performance/christmas-web-worker/src/app/app.component.ts @@ -0,0 +1,32 @@ +import { CommonModule } from '@angular/common'; +import { Component, inject } from '@angular/core'; +import { PrimeService } from './prime-number.service'; +import { UnknownPersonComponent } from './unknown-person/unknown-person.component'; + +@Component({ + standalone: true, + imports: [CommonModule, UnknownPersonComponent], + providers: [PrimeService], + selector: 'app-root', + template: ` + + +
Progress: {{ loadingPercentage() }}%
+ `, + host: { + class: `flex flex-col h-screen w-screen bg-[#1f75c0]`, + }, +}) +export class AppComponent { + primeService = inject(PrimeService); + + loadingPercentage = this.primeService.loadingPercentage; + + discover() { + this.primeService.calculatePrimeLength(); + } +} diff --git a/apps/performance/christmas-web-worker/src/app/app.config.ts b/apps/performance/christmas-web-worker/src/app/app.config.ts new file mode 100644 index 0000000..81a6edd --- /dev/null +++ b/apps/performance/christmas-web-worker/src/app/app.config.ts @@ -0,0 +1,5 @@ +import { ApplicationConfig } from '@angular/core'; + +export const appConfig: ApplicationConfig = { + providers: [], +}; diff --git a/apps/performance/christmas-web-worker/src/app/prime-number.service.ts b/apps/performance/christmas-web-worker/src/app/prime-number.service.ts new file mode 100644 index 0000000..9ef52fa --- /dev/null +++ b/apps/performance/christmas-web-worker/src/app/prime-number.service.ts @@ -0,0 +1,30 @@ +import { Injectable, computed, signal } from '@angular/core'; + +@Injectable() +export class PrimeService { + private finalResult = 664579; + private primesLength = signal(0); + + loadingPercentage = computed( + () => (this.primesLength() * 100) / this.finalResult + ); + + calculatePrimeLength() { + this.findPrimesUpToLimit(10000000); + } + + private findPrimesUpToLimit(limit: number) { + for (let num = 2; num <= limit; num++) { + let isPrime = true; + for (let i = 2; i <= Math.sqrt(num); i++) { + if (num % i === 0) { + isPrime = false; + break; + } + } + if (isPrime) { + this.primesLength.update((l) => l + 1); + } + } + } +} diff --git a/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.css b/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.css new file mode 100644 index 0000000..254caa2 --- /dev/null +++ b/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.css @@ -0,0 +1,223 @@ +*, +*:before, +*:after { + padding: 0; + margin: 0; + box-sizing: border-box; +} +body { + background-color: #fff2c8; +} +.container { + width: 380px; + height: 500px; + position: absolute; + transform: translate(-50%, -50%); + top: 50%; + left: 50%; +} +.container *:before, +.container *:after { + position: absolute; + content: ''; +} +.santa { + height: 220px; + width: 200px; + background-color: #e84701; + border-radius: 80px; + position: absolute; + left: 115px; + top: 200px; +} +.santa:before, +.santa:after { + width: 40px; + margin: auto; + left: 0; + right: 0; + background-color: #fff2c8; +} +.santa:before { + height: 130px; +} +.santa:after { + height: 40px; + bottom: -15px; +} +.hand-l { + background-color: #e84701; + height: 90px; + width: 105px; + position: absolute; + right: -30px; + top: 20px; + border-radius: 0 80px 0 0; +} +.hand-l:before { + margin: auto; + width: 35px; + height: 15px; + background-color: #ffffff; + top: 85px; + left: 71px; +} +.hand-l:after { + height: 15px; + width: 30px; + background-color: #fad2af; + left: 74px; + top: 101px; + border-radius: 0 0 30px 30px; +} +.hand-r { + height: 150px; + width: 180px; + border: 30px solid transparent; + border-bottom: 40px solid #e84701; + position: absolute; + left: -100px; + bottom: 150px; + border-radius: 50%; + animation: wave 1.5s infinite; + transform-origin: right; +} +@keyframes wave { + 50% { + transform: rotate(15deg); + } +} +.hand-r:before { + width: 35px; + height: 15px; + background-color: #ffffff; + transform: rotate(-50deg); + top: 68px; + left: -22px; +} +.hand-r:after { + width: 30px; + height: 15px; + background-color: #fad2af; + transform: rotate(-50deg); + left: -31px; + top: 58px; + border-radius: 15px 15px 0 0; +} +.face { + position: absolute; + margin: auto; + height: 180px; + width: 180px; + background-color: #fad2af; + border: 25px solid #f2e6da; + border-radius: 50%; + left: 0; + right: 0; + bottom: 140px; +} +.beard { + position: absolute; + height: 90px; + width: 180px; + background-color: #ffffff; + border-radius: 0 0 90px 90px; + right: -25px; + bottom: -25px; +} +.beard:before { + width: 55px; + height: 25px; + background-color: #f2e6da; + border-radius: 20px 0; + left: 34px; +} +.beard:after { + height: 25px; + width: 55px; + background-color: #f2e6da; + border-radius: 0 20px; + right: 34px; +} +.eyes { + height: 12px; + width: 12px; + background-color: #0078ca; + border-radius: 50%; + position: absolute; + top: 40px; + left: 40px; + box-shadow: 38px 0 #0078ca, 19px 20px #f69697; +} +.eyes:before { + height: 12px; + width: 25px; + background-color: #ffffff; + border-radius: 10px 0; + left: -10px; + bottom: 20px; +} +.eyes:after { + height: 12px; + width: 25px; + background-color: #ffffff; + border-radius: 0 10px; + left: 32px; + bottom: 20px; +} +.hat { + position: absolute; + height: 60px; + width: 120px; + background-color: #e84701; + top: -98px; + left: 85px; + border-radius: 0 0 60px 60px; +} +.hat:before { + height: 40px; + width: 40px; + background-color: #ffffff; + left: 100px; + top: -15px; + border-radius: 50%; +} +.belt { + position: absolute; + width: 100%; + height: 30px; + background-color: #000000; + top: 100px; +} +.belt:before { + height: 100%; + width: 40px; + border: 7px solid #ffdc2e; + margin: auto; + left: 0; + right: 0; +} +.belt:after { + height: 5px; + width: 15px; + background-color: #ffdc2e; + left: 100px; + top: 12px; +} +.shoe { + height: 20px; + width: 20px; + background-color: #000000; + position: absolute; + top: 220px; + left: 60px; + border-radius: 20px 0 0 0; +} +.shoe:before { + height: 20px; + width: 20px; + background-color: #000000; + top: 0; + left: 60px; + border-radius: 0 20px 0 0; +} diff --git a/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts b/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts new file mode 100644 index 0000000..adbfa86 --- /dev/null +++ b/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts @@ -0,0 +1,35 @@ +import { NgIf } from '@angular/common'; +import { Component, Input } from '@angular/core'; +@Component({ + selector: 'unknown-person', + standalone: true, + imports: [NgIf], + template: ` +
+
+ Who is here? +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `, + styleUrls: [`unknown-person.component.css`], +}) +export class UnknownPersonComponent { + @Input({ required: true }) step!: number; +} diff --git a/apps/performance/christmas-web-worker/src/assets/.gitkeep b/apps/performance/christmas-web-worker/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/apps/performance/christmas-web-worker/src/favicon.ico b/apps/performance/christmas-web-worker/src/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..317ebcb2336e0833a22dddf0ab287849f26fda57 GIT binary patch literal 15086 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 + + + + performance-christmas-web-worker + + + + + + + + diff --git a/apps/performance/christmas-web-worker/src/main.ts b/apps/performance/christmas-web-worker/src/main.ts new file mode 100644 index 0000000..514c89a --- /dev/null +++ b/apps/performance/christmas-web-worker/src/main.ts @@ -0,0 +1,7 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, appConfig).catch((err) => + console.error(err) +); diff --git a/apps/performance/christmas-web-worker/src/styles.scss b/apps/performance/christmas-web-worker/src/styles.scss new file mode 100644 index 0000000..77e408a --- /dev/null +++ b/apps/performance/christmas-web-worker/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/performance/christmas-web-worker/tailwind.config.js b/apps/performance/christmas-web-worker/tailwind.config.js new file mode 100644 index 0000000..38183db --- /dev/null +++ b/apps/performance/christmas-web-worker/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/performance/christmas-web-worker/tsconfig.app.json b/apps/performance/christmas-web-worker/tsconfig.app.json new file mode 100644 index 0000000..5822042 --- /dev/null +++ b/apps/performance/christmas-web-worker/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/performance/christmas-web-worker/tsconfig.editor.json b/apps/performance/christmas-web-worker/tsconfig.editor.json new file mode 100644 index 0000000..4ee6393 --- /dev/null +++ b/apps/performance/christmas-web-worker/tsconfig.editor.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": { + "types": [] + } +} diff --git a/apps/performance/christmas-web-worker/tsconfig.json b/apps/performance/christmas-web-worker/tsconfig.json new file mode 100644 index 0000000..51c7908 --- /dev/null +++ b/apps/performance/christmas-web-worker/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "target": "es2022", + "useDefineForClassFields": false, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.editor.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/challenge-number.json b/challenge-number.json index 6e455d3..cd65533 100644 --- a/challenge-number.json +++ b/challenge-number.json @@ -1,6 +1,6 @@ { - "total": 39, + "total": 40, "🟢": 14, - "🟠": 118, + "🟠": 119, "🔴": 207 } diff --git a/docs/src/content/docs/challenges/angular/39-injection-token.md b/docs/src/content/docs/challenges/angular/39-injection-token.md index 5dfdbd8..36aab19 100644 --- a/docs/src/content/docs/challenges/angular/39-injection-token.md +++ b/docs/src/content/docs/challenges/angular/39-injection-token.md @@ -6,7 +6,6 @@ challengeNumber: 39 command: angular-injection-token sidebar: order: 118 - badge: New --- ## Information diff --git a/docs/src/content/docs/challenges/performance/40-christmas-web-worker.md b/docs/src/content/docs/challenges/performance/40-christmas-web-worker.md new file mode 100644 index 0000000..91570e9 --- /dev/null +++ b/docs/src/content/docs/challenges/performance/40-christmas-web-worker.md @@ -0,0 +1,20 @@ +--- +title: 🟠 Web workers +description: Challenge 40 is about ... +author: Thomas Laforge +challengeNumber: 40 +command: performance-christmas-web-worker +sidebar: + order: 119 + badge: New +--- + +:::note +WIP: The following documentation need to be written. +::: + +## Information + +## Statement + +## Constraints diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx index 3c7eabf..8cc1ae6 100644 --- a/docs/src/content/docs/index.mdx +++ b/docs/src/content/docs/index.mdx @@ -15,7 +15,7 @@ hero: icon: right-arrow variant: primary - text: Go to the latest Challenge - link: /challenges/angular/39-injection-token/ + link: /challenges/performance/40-christmas-web-worker/ icon: rocket - text: Give a star link: https://github.com/tomalaforge/angular-challenges @@ -27,8 +27,8 @@ import { Card, CardGrid } from '@astrojs/starlight/components'; import MyIcon from '../../components/MyIcon.astro'; - - This repository gathers 39 Challenges related to Angular, Nx, RxJS, Ngrx and Typescript. + + This repository gathers 40 Challenges related to Angular, Nx, RxJS, Ngrx and Typescript. These challenges resolve around real-life issues or specific features to elevate your skills. From bc6449cf571c5b2ac709e0b48b135037316726e6 Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 30 Oct 2023 22:13:53 +0100 Subject: [PATCH 02/13] feat: add text for happy christmas --- .../src/app/unknown-person/unknown-person.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts b/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts index adbfa86..dbf9095 100644 --- a/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts +++ b/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts @@ -14,6 +14,7 @@ import { Component, Input } from '@angular/core'; Who is here? +
Happy Christmas !!!
From b521f45f4a37c552754fd5f4e92efbc60213aa0c Mon Sep 17 00:00:00 2001 From: thomas Date: Fri, 3 Nov 2023 20:40:29 +0100 Subject: [PATCH 03/13] feat: rename prime to random --- .../src/app/app.component.ts | 10 +++---- .../src/app/app.config.ts | 5 ---- .../src/app/heavy-calculation.service.ts | 30 +++++++++++++++++++ .../src/app/prime-number.service.ts | 30 ------------------- .../christmas-web-worker/src/main.ts | 5 +--- 5 files changed, 36 insertions(+), 44 deletions(-) delete mode 100644 apps/performance/christmas-web-worker/src/app/app.config.ts create mode 100644 apps/performance/christmas-web-worker/src/app/heavy-calculation.service.ts delete mode 100644 apps/performance/christmas-web-worker/src/app/prime-number.service.ts diff --git a/apps/performance/christmas-web-worker/src/app/app.component.ts b/apps/performance/christmas-web-worker/src/app/app.component.ts index a7e757f..ba55d27 100644 --- a/apps/performance/christmas-web-worker/src/app/app.component.ts +++ b/apps/performance/christmas-web-worker/src/app/app.component.ts @@ -1,12 +1,12 @@ import { CommonModule } from '@angular/common'; import { Component, inject } from '@angular/core'; -import { PrimeService } from './prime-number.service'; +import { HeavyCalculationService } from './heavy-calculation.service'; import { UnknownPersonComponent } from './unknown-person/unknown-person.component'; @Component({ standalone: true, imports: [CommonModule, UnknownPersonComponent], - providers: [PrimeService], + providers: [HeavyCalculationService], selector: 'app-root', template: ` @@ -22,11 +22,11 @@ import { UnknownPersonComponent } from './unknown-person/unknown-person.componen }, }) export class AppComponent { - primeService = inject(PrimeService); + private heavyCalculationService = inject(HeavyCalculationService); - loadingPercentage = this.primeService.loadingPercentage; + readonly loadingPercentage = this.heavyCalculationService.loadingPercentage; discover() { - this.primeService.calculatePrimeLength(); + this.heavyCalculationService.startLoading(); } } diff --git a/apps/performance/christmas-web-worker/src/app/app.config.ts b/apps/performance/christmas-web-worker/src/app/app.config.ts deleted file mode 100644 index 81a6edd..0000000 --- a/apps/performance/christmas-web-worker/src/app/app.config.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ApplicationConfig } from '@angular/core'; - -export const appConfig: ApplicationConfig = { - providers: [], -}; diff --git a/apps/performance/christmas-web-worker/src/app/heavy-calculation.service.ts b/apps/performance/christmas-web-worker/src/app/heavy-calculation.service.ts new file mode 100644 index 0000000..84ce1e6 --- /dev/null +++ b/apps/performance/christmas-web-worker/src/app/heavy-calculation.service.ts @@ -0,0 +1,30 @@ +import { Injectable, computed, signal } from '@angular/core'; + +@Injectable() +export class HeavyCalculationService { + private finalLength = 664579; + private loadingLength = signal(0); + + loadingPercentage = computed( + () => (this.loadingLength() * 100) / this.finalLength + ); + + startLoading() { + this.randomHeavyCalculalationFunction(); + } + + private randomHeavyCalculalationFunction() { + for (let num = 2; num <= 10000000; num++) { + let randomFlag = true; + for (let i = 2; i <= Math.sqrt(num); i++) { + if (num % i === 0) { + randomFlag = false; + break; + } + } + if (randomFlag) { + this.loadingLength.update((l) => l + 1); + } + } + } +} diff --git a/apps/performance/christmas-web-worker/src/app/prime-number.service.ts b/apps/performance/christmas-web-worker/src/app/prime-number.service.ts deleted file mode 100644 index 9ef52fa..0000000 --- a/apps/performance/christmas-web-worker/src/app/prime-number.service.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Injectable, computed, signal } from '@angular/core'; - -@Injectable() -export class PrimeService { - private finalResult = 664579; - private primesLength = signal(0); - - loadingPercentage = computed( - () => (this.primesLength() * 100) / this.finalResult - ); - - calculatePrimeLength() { - this.findPrimesUpToLimit(10000000); - } - - private findPrimesUpToLimit(limit: number) { - for (let num = 2; num <= limit; num++) { - let isPrime = true; - for (let i = 2; i <= Math.sqrt(num); i++) { - if (num % i === 0) { - isPrime = false; - break; - } - } - if (isPrime) { - this.primesLength.update((l) => l + 1); - } - } - } -} diff --git a/apps/performance/christmas-web-worker/src/main.ts b/apps/performance/christmas-web-worker/src/main.ts index 514c89a..31c5da4 100644 --- a/apps/performance/christmas-web-worker/src/main.ts +++ b/apps/performance/christmas-web-worker/src/main.ts @@ -1,7 +1,4 @@ import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; -bootstrapApplication(AppComponent, appConfig).catch((err) => - console.error(err) -); +bootstrapApplication(AppComponent).catch((err) => console.error(err)); From 39702d3f385c396b87f2b50f0e3a8207ad820c6b Mon Sep 17 00:00:00 2001 From: thomas Date: Fri, 3 Nov 2023 22:05:32 +0100 Subject: [PATCH 04/13] feat: add documentation --- .../performance/40-christmas-web-worker.md | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/docs/src/content/docs/challenges/performance/40-christmas-web-worker.md b/docs/src/content/docs/challenges/performance/40-christmas-web-worker.md index 91570e9..0e6556c 100644 --- a/docs/src/content/docs/challenges/performance/40-christmas-web-worker.md +++ b/docs/src/content/docs/challenges/performance/40-christmas-web-worker.md @@ -1,6 +1,6 @@ --- title: 🟠 Web workers -description: Challenge 40 is about ... +description: Challenge 40 is about learning how to create and use a web worker author: Thomas Laforge challengeNumber: 40 command: performance-christmas-web-worker @@ -9,12 +9,24 @@ sidebar: badge: New --- -:::note -WIP: The following documentation need to be written. -::: - ## Information +This challenge has been created for Angular Advent Calendar 2023. + +This application is basic. We click on the **Discover** button to reveal the surprise hidden behind the black screen. However, the current application provides an awful user experience. When we click on the button, the page freezes, and after a while, it reveals the secret all at once without a smooth animation. + +> Note: To create the application freeze, the loader is based on a very heavy computation function. We could have used a basic timer, but that's not the point of this challenge. + +Since JavaScript is single-threaded, when we perform a heavy task, the browser cannot update the UI or respond to mouse clicks or any events. To free the main thread, the goal is to isolate the heavy computation into a different thread. To do so, we will need to use web workers. Web workers can run any scripts in the background, in isolation from the main thread, allowing the browser to still provide your user with a good experience. + +In Angular, this technology is often underused, however, it's straightforward to create one. There is a schematic that you can find here. + ## Statement -## Constraints +The goal of this challenge is to create a smooth animation by isolating the heavy computation function into a web worker. + +First, create a web worker using the schematics, then move the issuing function. Finally, the animation should be smooth and provide an awesome user experience. + +### Note + +Since we are inside an Nx workspace, simply replace the `ng` command with `nx` when running the schematic. From 5ab6f7e02c1528e32712efcf804db308b0e57147 Mon Sep 17 00:00:00 2001 From: thomas Date: Sun, 19 Nov 2023 22:36:38 +0400 Subject: [PATCH 05/13] feat: change target --- apps/performance/christmas-web-worker/project.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/apps/performance/christmas-web-worker/project.json b/apps/performance/christmas-web-worker/project.json index 0f33ede..a1eae3c 100644 --- a/apps/performance/christmas-web-worker/project.json +++ b/apps/performance/christmas-web-worker/project.json @@ -7,12 +7,12 @@ "tags": [], "targets": { "build": { - "executor": "@angular-devkit/build-angular:browser", + "executor": "@angular-devkit/build-angular:application", "outputs": ["{options.outputPath}"], "options": { "outputPath": "dist/apps/performance/christmas-web-worker", "index": "apps/performance/christmas-web-worker/src/index.html", - "main": "apps/performance/christmas-web-worker/src/main.ts", + "browser": "apps/performance/christmas-web-worker/src/main.ts", "polyfills": ["zone.js"], "tsConfig": "apps/performance/christmas-web-worker/tsconfig.app.json", "assets": [ @@ -39,9 +39,7 @@ "outputHashing": "all" }, "development": { - "buildOptimizer": false, "optimization": false, - "vendorChunk": true, "extractLicenses": false, "sourceMap": true, "namedChunks": true @@ -53,10 +51,10 @@ "executor": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { - "browserTarget": "performance-christmas-web-worker:build:production" + "buildTarget": "performance-christmas-web-worker:build:production" }, "development": { - "browserTarget": "performance-christmas-web-worker:build:development" + "buildTarget": "performance-christmas-web-worker:build:development" } }, "defaultConfiguration": "development" From 671c7bf8c3891494204f0004b27f5fe8000c9f0d Mon Sep 17 00:00:00 2001 From: thomas Date: Thu, 30 Nov 2023 14:11:15 +0400 Subject: [PATCH 06/13] feat: new control flow --- .../app/unknown-person/unknown-person.component.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts b/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts index dbf9095..1682ddf 100644 --- a/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts +++ b/apps/performance/christmas-web-worker/src/app/unknown-person/unknown-person.component.ts @@ -1,18 +1,17 @@ -import { NgIf } from '@angular/common'; import { Component, Input } from '@angular/core'; @Component({ selector: 'unknown-person', standalone: true, - imports: [NgIf], template: `
-
- Who is here? -
+ @if (step !== 100) { +
+ Who is here? +
+ }
Happy Christmas !!!
From 9a3bc613e8548566feed8a8146592f7eadc319a8 Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 11 Dec 2023 21:21:18 +0100 Subject: [PATCH 07/13] fix: fix pipeline --- .../performance/christmas-web-worker/src/app/app.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/performance/christmas-web-worker/src/app/app.component.ts b/apps/performance/christmas-web-worker/src/app/app.component.ts index ba55d27..6b9846b 100644 --- a/apps/performance/christmas-web-worker/src/app/app.component.ts +++ b/apps/performance/christmas-web-worker/src/app/app.component.ts @@ -11,11 +11,11 @@ import { UnknownPersonComponent } from './unknown-person/unknown-person.componen template: ` -
Progress: {{ loadingPercentage() }}%
+
Progress: {{ loadingPercentage() }}%
`, host: { class: `flex flex-col h-screen w-screen bg-[#1f75c0]`, From e92f044e0815a6f780f5c73c7acf2ad55f451758 Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 11 Dec 2023 21:24:03 +0100 Subject: [PATCH 08/13] fix: author --- .../docs/challenges/performance/40-christmas-web-worker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/challenges/performance/40-christmas-web-worker.md b/docs/src/content/docs/challenges/performance/40-christmas-web-worker.md index 0e6556c..a341d4d 100644 --- a/docs/src/content/docs/challenges/performance/40-christmas-web-worker.md +++ b/docs/src/content/docs/challenges/performance/40-christmas-web-worker.md @@ -1,7 +1,7 @@ --- title: 🟠 Web workers description: Challenge 40 is about learning how to create and use a web worker -author: Thomas Laforge +author: thomas-laforge challengeNumber: 40 command: performance-christmas-web-worker sidebar: From f11d34065ade3f83f2025ec7d79932c29a69a556 Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 11 Dec 2023 22:15:14 +0100 Subject: [PATCH 09/13] feat: start french translation --- docs/astro.config.mjs | 7 ++ .../content/docs/fr/guides/getting-started.md | 57 ++++++++++++ .../docs/fr/guides/resolve-challenge.md | 93 +++++++++++++++++++ docs/src/content/docs/fr/index.mdx | 78 ++++++++++++++++ 4 files changed, 235 insertions(+) create mode 100644 docs/src/content/docs/fr/guides/getting-started.md create mode 100644 docs/src/content/docs/fr/guides/resolve-challenge.md create mode 100644 docs/src/content/docs/fr/index.mdx diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 23bfa5a..8457cd4 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -4,6 +4,7 @@ import { defineConfig } from 'astro/config'; export const locales = { root: { label: 'English', lang: 'en' }, es: { label: 'Español', lang: 'es' }, + fr: { label: 'Français', lang: 'fr' }, }; // https://astro.build/config @@ -28,6 +29,7 @@ export default defineConfig({ autogenerate: { directory: 'guides' }, translations: { es: 'Guías', + fr: 'Guides', }, }, { @@ -35,6 +37,7 @@ export default defineConfig({ autogenerate: { directory: 'challenges' }, translations: { es: 'Desafíos', + fr: 'Challenges', }, }, ], @@ -73,6 +76,10 @@ export default defineConfig({ label: 'Español', lang: 'es', }, + fr: { + label: 'Français', + lang: 'fr', + }, }, }), ], diff --git a/docs/src/content/docs/fr/guides/getting-started.md b/docs/src/content/docs/fr/guides/getting-started.md new file mode 100644 index 0000000..c74353a --- /dev/null +++ b/docs/src/content/docs/fr/guides/getting-started.md @@ -0,0 +1,57 @@ +--- +title: Comment démarrer +description: Un guide sur la manière de commencer avec sur Angular Challenges. +sidebar: + order: 1 +--- + +Pour commencer avec les Challenges Angular, suivez ces étapes : + +## Créez un compte Github + +Si vous souhaitez soumettre une réponse, vous devrez avoir votre propre compte GitHub. De plus, avoir un compte GitHub est toujours bénéfique et c'est gratuit. + +## Forkez le projet GitHub + +Accédez au [répertoire des Challenges Angular](https://github.com/tomalaforge/angular-challenges) et cliquez sur le bouton Fork dans l'en-tête. Cela créera une copie de ce dépôt sur votre propre page GitHub. + +## Clonez le dépôt sur votre machine locale + +Sélectionnez un répertoire sur votre ordinateur local et clonez ce dépôt. + +Ouvrez un terminal, accédez au répertoire choisi et tapez la commande suivante : + +```bash +git clone https://github.com/[VOTRE_NOM_GITHUB]/angular-challenges.git +``` + +:::note +Vous pouvez trouver l'URL de clonage en cliquant sur le bouton <> Code dans votre propre instance du dépôt des Challenges Angular. + +![Header of github workpspace](../../../../assets/header-github.png) + +::: + +## Ouvrez le projet dans votre IDE préféré + +Ouvrez le projet dans n'importe quel IDE de votre choix. + +## Installez toutes les dépendances + +```bash +npm ci +``` + +## Choisissez un challenge + +Votre projet est maintenant opérationnel. La seule étape restante est de choisir un challenge 🚀 + +Chaque challenge se compose de : + +- Nom : indiquant de quoi traite le défi. +- Numéro : ordre de création. Le numéro n'a pas de signification particulière mais aide pour la référence dans la section des Demandes de Tirage (Pull Requests) GitHub. +- Badge : aide à visualiser le degré de difficulté. C'est entièrement subjectif 😅 + - 🟢 facile + - 🟠 moyen + - 🔴 difficile diff --git a/docs/src/content/docs/fr/guides/resolve-challenge.md b/docs/src/content/docs/fr/guides/resolve-challenge.md new file mode 100644 index 0000000..e16ac5c --- /dev/null +++ b/docs/src/content/docs/fr/guides/resolve-challenge.md @@ -0,0 +1,93 @@ +--- +title: Résoudre un Challenge +description: Guide pour résoudre un challenge +sidebar: + order: 2 +--- + +Dans ce guide, vous apprendrez comment résoudre un challenge et soumettre une réponse sur le répertoire principal de Github. + +## Introduction + +Ce répertoire utilise [Nx](https://nx.dev/getting-started/intro). Nx est un monorépo qui vous permet de stocker plusieurs applications à l'intérieur du même espace de travail. Chaque challenge est une application distincte. Si vous ouvrez le répertoire `apps`, vous trouverez plusieurs dossiers, chacun lié à un challenge spécifique. Chaque dossier représente une application autonome complète `Nx`. Pour exécuter et démarrer l'une d'entre elles, ouvrez votre terminal et exécutez : + +```bash +npx nx serve +``` + +:::note +Si vous n'êtes pas sûr de votre `NOM_APPLICATION`, ouvrez le fichier README.md. La commande `serve` y est écrite, avec un lien vers la documentation du challenge. +::: + +:::note +Si vous installez `nx` globalement sur votre ordinateur, vous éviterez de préfixer chaque commande par `npx`. + +Pour installer `nx` globalement, exécutez + +```bash +npm i -g nx +``` + +::: + +## Créer une Branche Git + +Avant de commencer à résoudre un challenge, créez une branche git pour y ajouter vos modifications. + +```bash +git checkout -b +``` + +## Résoudre un Challenge + +Suivez les instructions décrites sur chaque Challenge pour le résoudre. + +## Commitez et Pousser votre Travail + +La dernière étape consiste à valider votre travail en suivant les [Conventional Guidelines](https://www.conventionalcommits.org/en/v1.0.0/). + +Enfin, poussez votre travail vers le répertoire distant avec la commande suivante + +```bash + git push --set-upstream origin +``` + +:::tip[Pas besoin de retenir la commande par coeur] +Vous n'avez pas besoin de mémoriser précisément la commande. Il vous suffit de vous rappeler `git push `et si c'est la première fois que vous poussez cette branche, `git` vous fournira la commande complète. +::: + +## Soumettre votre Travail sur le répertoire Principal + +Maintenant, tout votre travail se trouve dans votre instance locale du dépôt de Angular Challenges. + +La prochaine étape est de vous rendre sur la page principale de Angular Challenges et de créer une nouvelle Pull Request. + +Github devrait afficher en en-tête une notification pour vous aider à créer la pull request. + +Si ce n'est pas le cas, vous avez soit mal effectué l'une des étapes précédentes, soit vous pouvez vous rendre sur l'onglet Pull Request et cliquer sur le bouton New pull request. + +Une fois que vous avez choisi les deux branches à comparer, vous devriez arriver sur la page suivante : + +![New pull request screen](../../../../assets/new-pull-request.png) + +Dans la section du titre, commencez par Réponse : suivi de votre numéro de challenge. Ensuite, vous êtes libre d'ajouter tout ce que vous souhaitez. + +:::danger +C'est très important. Cela permet aux autres de savoir quel challenge vous tentez de résoudre. +::: + +Dans la section de description, vous pouvez ajouter des questions, des problèmes rencontrés ou tout autre contenu que vous souhaitez partager. Vous pouvez laisser vide si vous n'avez rien à dire. + +Vous pouvez maintenant cliquer sur Créer pull request. + +Je la lirai et commenterai quand j'aurai du temps libre. + +

Ne vous inquiétez pas si votre réponse n'est pas examinée immédiatement. Je le fais gratuitement et pendant mon temps libre. Si vous souhaitez me soutenir, vous pouvez le faire en me sponsorisant sur github. Cela validera que mon travail vous aide, vous ou votre équipe.

+ +:::note +Tout le monde peut commenter ou lire les Pull Requests des autres participants. +::: + +:::tip[Champion OSS] +🔥 Une fois que vous avez terminé ce tutoriel, vous êtes prêt à contribuer à n'importe quel répertoire public Github et à soumettre une PR. C'est aussi simple que ça. 🔥 +::: diff --git a/docs/src/content/docs/fr/index.mdx b/docs/src/content/docs/fr/index.mdx new file mode 100644 index 0000000..6907cdc --- /dev/null +++ b/docs/src/content/docs/fr/index.mdx @@ -0,0 +1,78 @@ +--- +title: Bienvenue sur Angular Challenges +description: Commence par résoudre ces défis et deviens un meilleur ingénieur FrontEnd Angular. +template: splash +noCommentSection: true +banner: + content: J'aurai moins de temps libre dans les deux prochains mois, donc ne vous inquiétez pas si vos pull requests prennent du temps à être examinées. +hero: + tagline: Commence maintenant et deviens un expert Angular ! + image: + file: ../../../assets/angular-challenge.webp + actions: + - text: C'est parti ! + link: /guides/getting-started/ + icon: right-arrow + variant: primary + - text: Aller au dernier Challenge + link: /challenges/performance/40-christmas-web-worker/ + icon: rocket + - text: Donne une étoile + link: https://github.com/tomalaforge/angular-challenges + icon: github + variant: secondary +--- + +import { Card, CardGrid } from '@astrojs/starlight/components'; +import MyIcon from '../../../components/MyIcon.astro'; + + + + Ce répertoire rassemble 40 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. + + + + L'un des objectifs de ce répertoire est de rendre plus accessible les + contributions aux logiciels Open Source (OSS). En résolvant ces défis, vous + apprendrez comment commencer à contribuer à n'importe quel projet Open Source. + + + + Apprendre et démarrer sur un nouveau framework est toujours difficile. Cette + série de défis propose des cas d'utilisation réels pour appliquer ce que vous + avez appris. N'importe qui peut commenter ou aider.{' '} + + Apprendre seul est bien, mais apprendre aux côtés des autres vous fera + progresser davantage et plus rapidement. + + + + + Avez-vous un problème, un bug intéressant ou une idée ? N'hésitez pas ;{' '} + créez vos propres challenges sans perdre de temps. + + + + Résoudre ces challenges vous préparera aux éventuels défis techniques que vous + pourriez rencontrer lors d'un entretien pour un rôle d'ingénieur frontend. + + + + Ce projet est gratuit et vise à le rester le plus longtemps possible. Cependant, tout est réalisé pendant mon temps libre, y compris la création de challenges et la relecture des pull requests. Le sponsoring peut me soutenir et contribuer à la croissance du projet. + + + +--- + + + + From dc9e50a219b1f83b4d221d60a68a543eb4d4b587 Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 11 Dec 2023 22:18:04 +0100 Subject: [PATCH 10/13] feat: update read me --- .all-contributorsrc | 68 +++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 42 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9005b37..afb4aab 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -3,9 +3,7 @@ "projectOwner": "tomalaforge", "repoType": "github", "repoHost": "https://github.com", - "files": [ - "README.md" - ], + "files": ["README.md"], "imageSize": 100, "commit": true, "commitConvention": "angular", @@ -13,6 +11,18 @@ "challenge": { "symbol": "🧩", "description": "Created a challenge" + }, + "translation-es": { + "symbol": "🇪🇸", + "description": "Translate the side in spanish" + }, + "translation-fr": { + "symbol": "🇫🇷", + "description": "Translate the side in french" + }, + "translation-pt": { + "symbol": "🇵🇹", + "description": "Translate the side in portugese" } }, "contributors": [ @@ -27,7 +37,8 @@ "doc", "content", "ideas", - "design" + "design", + "translation-fr" ] }, { @@ -35,104 +46,77 @@ "name": "Alan Dragicevich", "avatar_url": "https://avatars.githubusercontent.com/u/31838230?v=4", "profile": "https://github.com/alan-bio", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "edimitchel", "name": "Michel EDIGHOFFER", "avatar_url": "https://avatars.githubusercontent.com/u/2922851?v=4", "profile": "https://github.com/edimitchel", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "gsgonzalez88", "name": "Gerardo Sebastian Gonzalez", "avatar_url": "https://avatars.githubusercontent.com/u/39884678?v=4", "profile": "https://github.com/gsgonzalez88", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "marryday", "name": "Evseev Yuriy", "avatar_url": "https://avatars.githubusercontent.com/u/57489315?v=4", "profile": "https://github.com/marryday", - "contributions": [ - "bug" - ] + "contributions": ["bug"] }, { "login": "tomer953", "name": "Tomer953", "avatar_url": "https://avatars.githubusercontent.com/u/1807493?v=4", "profile": "https://github.com/tomer953", - "contributions": [ - "bug", - "doc", - "code" - ] + "contributions": ["bug", "doc", "code"] }, { "login": "jdegand", "name": "J. Degand", "avatar_url": "https://avatars.githubusercontent.com/u/70610011?v=4", "profile": "https://github.com/jdegand", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "DeveshChau", "name": "Devesh Chaudhari", "avatar_url": "https://avatars.githubusercontent.com/u/9509673?v=4", "profile": "https://github.com/DeveshChau", - "contributions": [ - "code", - "bug", - "challenge" - ] + "contributions": ["code", "bug", "challenge"] }, { "login": "dmmishchenko", "name": "Dmitriy Mishchenko", "avatar_url": "https://avatars.githubusercontent.com/u/51910160?v=4", "profile": "https://github.com/dmmishchenko", - "contributions": [ - "doc" - ] + "contributions": ["doc"] }, { "login": "Sagardevkota", "name": "Sagar Devkota", "avatar_url": "https://avatars.githubusercontent.com/u/30800393?v=4", "profile": "http://www.sagardev.com.np", - "contributions": [ - "doc", - "code" - ] + "contributions": ["doc", "code"] }, { "login": "nelsongutidev", "name": "Nelson Gutierrez", "avatar_url": "https://avatars.githubusercontent.com/u/62297014?v=4", "profile": "https://nelsonguti.dev/", - "contributions": [ - "doc" - ] + "contributions": ["translation-es"] }, { "login": "ho-ssain", "name": "Hossain K. M.", "avatar_url": "https://avatars.githubusercontent.com/u/61125174?v=4", "profile": "https://github.com/ho-ssain", - "contributions": [ - "doc" - ] + "contributions": ["doc"] } ], "contributorsPerLine": 7, From 0868e4fe2185face8f517b183422b02ffa60d9aa Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 11 Dec 2023 22:19:45 +0100 Subject: [PATCH 11/13] feat: update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4250a0a..f144392 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Check [all 40 challenges](https://angular-challenges.vercel.app/) - + @@ -46,7 +46,7 @@ Check [all 40 challenges](https://angular-challenges.vercel.app/) - + From 103592d6e813c7c784060fcb4db27f05ef3dd10f Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 11 Dec 2023 22:21:14 +0100 Subject: [PATCH 12/13] fix: contributors --- .all-contributorsrc | 8 ++++---- README.md | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index afb4aab..2c4b901 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -10,19 +10,19 @@ "types": { "challenge": { "symbol": "🧩", - "description": "Created a challenge" + "description": "Create a challenge" }, "translation-es": { "symbol": "🇪🇸", - "description": "Translate the side in spanish" + "description": "Translate in Spanish" }, "translation-fr": { "symbol": "🇫🇷", - "description": "Translate the side in french" + "description": "Translate in French" }, "translation-pt": { "symbol": "🇵🇹", - "description": "Translate the side in portugese" + "description": "Translate in Portugese" } }, "contributors": [ diff --git a/README.md b/README.md index f144392..bc01dfb 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Check [all 40 challenges](https://angular-challenges.vercel.app/)
Laforge Thomas
Laforge Thomas

🧩 💻 📖 🖋 🤔 🎨
Laforge Thomas
Laforge Thomas

🧩 💻 📖 🖋 🤔 🎨 🇫🇷
Alan Dragicevich
Alan Dragicevich

📖
Michel EDIGHOFFER
Michel EDIGHOFFER

📖
Gerardo Sebastian Gonzalez
Gerardo Sebastian Gonzalez

📖
Devesh Chaudhari
Devesh Chaudhari

💻 🐛 🧩
Dmitriy Mishchenko
Dmitriy Mishchenko

📖
Sagar Devkota
Sagar Devkota

📖 💻
Nelson Gutierrez
Nelson Gutierrez

📖
Nelson Gutierrez
Nelson Gutierrez

🇪🇸
Hossain K. M.
Hossain K. M.

📖
- + @@ -43,10 +43,10 @@ Check [all 40 challenges](https://angular-challenges.vercel.app/) - + - + From 6913cba220684feaf6b48c69d570b22b38d0265a Mon Sep 17 00:00:00 2001 From: jdegand <70610011+jdegand@users.noreply.github.com> Date: Mon, 11 Dec 2023 19:32:42 -0500 Subject: [PATCH 13/13] fix: calculation spelling --- .../src/app/heavy-calculation.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/performance/christmas-web-worker/src/app/heavy-calculation.service.ts b/apps/performance/christmas-web-worker/src/app/heavy-calculation.service.ts index 84ce1e6..06dedd1 100644 --- a/apps/performance/christmas-web-worker/src/app/heavy-calculation.service.ts +++ b/apps/performance/christmas-web-worker/src/app/heavy-calculation.service.ts @@ -6,14 +6,14 @@ export class HeavyCalculationService { private loadingLength = signal(0); loadingPercentage = computed( - () => (this.loadingLength() * 100) / this.finalLength + () => (this.loadingLength() * 100) / this.finalLength, ); startLoading() { - this.randomHeavyCalculalationFunction(); + this.randomHeavyCalculationFunction(); } - private randomHeavyCalculalationFunction() { + private randomHeavyCalculationFunction() { for (let num = 2; num <= 10000000; num++) { let randomFlag = true; for (let i = 2; i <= Math.sqrt(num); i++) {
Laforge Thomas
Laforge Thomas

🧩 💻 📖 🖋 🤔 🎨 🇫🇷
Laforge Thomas
Laforge Thomas

🧩 💻 📖 🖋 🤔 🎨 🇫🇷
Alan Dragicevich
Alan Dragicevich

📖
Michel EDIGHOFFER
Michel EDIGHOFFER

📖
Gerardo Sebastian Gonzalez
Gerardo Sebastian Gonzalez

📖
J. Degand
J. Degand

📖
Devesh Chaudhari
Devesh Chaudhari

💻 🐛 🧩
Devesh Chaudhari
Devesh Chaudhari

💻 🐛 🧩
Dmitriy Mishchenko
Dmitriy Mishchenko

📖
Sagar Devkota
Sagar Devkota

📖 💻
Nelson Gutierrez
Nelson Gutierrez

🇪🇸
Nelson Gutierrez
Nelson Gutierrez

🇪🇸
Hossain K. M.
Hossain K. M.

📖