diff --git a/apps/ngrx-notification/src/app/data-access/notification.service.ts b/apps/ngrx-notification/src/app/data-access/notification.service.ts index d675e94..8f17cb6 100644 --- a/apps/ngrx-notification/src/app/data-access/notification.service.ts +++ b/apps/ngrx-notification/src/app/data-access/notification.service.ts @@ -1,31 +1,27 @@ -import { Injectable } from '@angular/core'; -import { filter } from 'rxjs'; -import { PushService } from '../backend/push.service'; -import { Push } from '../model/push.model'; -import { isStudent } from '../model/student.model'; -import { isTeacher } from '../model/teacher.model'; +import { + isStudent, + isTeacher, + Push, +} from '@angular-challenges/ngrx-notification/model'; +import { inject, Injectable } from '@angular/core'; +import { PUSH_ACTION } from './notification.token'; import { StudentStore } from './student.store'; import { TeacherStore } from './teacher.store'; @Injectable({ providedIn: 'root' }) export class NotificationService { - constructor( - private pushService: PushService, - private teacherStore: TeacherStore, - private studentStore: StudentStore - ) {} + private notification$ = inject(PUSH_ACTION); + private teacherStore = inject(TeacherStore); + private studentStore = inject(StudentStore); init() { - this.pushService.notification$ - .pipe(filter(Boolean)) - .subscribe((notification: Push) => { - console.log(notification); - if (isTeacher(notification)) { - this.teacherStore.addOne(notification); - } - if (isStudent(notification)) { - this.studentStore.addOne(notification); - } - }); + this.notification$.subscribe((notification: Push) => { + if (isTeacher(notification)) { + this.teacherStore.addOne(notification); + } + if (isStudent(notification)) { + this.studentStore.addOne(notification); + } + }); } } diff --git a/apps/ngrx-notification/src/app/data-access/notification.token.ts b/apps/ngrx-notification/src/app/data-access/notification.token.ts new file mode 100644 index 0000000..da7d3c0 --- /dev/null +++ b/apps/ngrx-notification/src/app/data-access/notification.token.ts @@ -0,0 +1,12 @@ +import { PushService } from '@angular-challenges/ngrx-notification/backend'; +import { Push } from '@angular-challenges/ngrx-notification/model'; +import { inject, InjectionToken } from '@angular/core'; +import { filter, Observable, share } from 'rxjs'; + +export const PUSH_ACTION = new InjectionToken>( + 'Push messaging action stream', + { + factory: () => + inject(PushService).notification$.pipe(filter(Boolean), share()), + } +); diff --git a/apps/ngrx-notification/src/app/data-access/student.store.ts b/apps/ngrx-notification/src/app/data-access/student.store.ts index 7918118..5240c1f 100644 --- a/apps/ngrx-notification/src/app/data-access/student.store.ts +++ b/apps/ngrx-notification/src/app/data-access/student.store.ts @@ -1,6 +1,6 @@ +import { Student } from '@angular-challenges/ngrx-notification/model'; import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; -import { Student } from '../model/student.model'; @Injectable({ providedIn: 'root', diff --git a/apps/ngrx-notification/src/app/data-access/teacher.store.ts b/apps/ngrx-notification/src/app/data-access/teacher.store.ts index 93f68c4..fee7e6e 100644 --- a/apps/ngrx-notification/src/app/data-access/teacher.store.ts +++ b/apps/ngrx-notification/src/app/data-access/teacher.store.ts @@ -1,6 +1,6 @@ +import { Teacher } from '@angular-challenges/ngrx-notification/model'; import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; -import { Teacher } from '../model/teacher.model'; @Injectable({ providedIn: 'root', diff --git a/apps/ngrx-notification/src/main.ts b/apps/ngrx-notification/src/main.ts index 23644bb..4986c1c 100644 --- a/apps/ngrx-notification/src/main.ts +++ b/apps/ngrx-notification/src/main.ts @@ -1,8 +1,8 @@ import { APP_INITIALIZER, enableProdMode, inject } from '@angular/core'; import { bootstrapApplication } from '@angular/platform-browser'; import { of } from 'rxjs'; +import { PushService } from '../../../libs/ngrx-notification/backend/src/lib/push.service'; import { AppComponent } from './app/app.component'; -import { PushService } from './app/backend/push.service'; import { NotificationService } from './app/data-access/notification.service'; import { environment } from './environments/environment'; diff --git a/apps/ngrx-notification/tsconfig.editor.json b/apps/ngrx-notification/tsconfig.editor.json index 0f9036b..7e16fb8 100644 --- a/apps/ngrx-notification/tsconfig.editor.json +++ b/apps/ngrx-notification/tsconfig.editor.json @@ -1,7 +1,10 @@ { "extends": "./tsconfig.json", - "include": ["**/*.ts"], + "include": [ + "**/*.ts", + "../../libs/ngrx-notification/backend/src/lib/push.service.ts" + ], "compilerOptions": { "types": [] } -} +} \ No newline at end of file diff --git a/libs/ngrx-notification/backend/.eslintrc.json b/libs/ngrx-notification/backend/.eslintrc.json new file mode 100644 index 0000000..946116f --- /dev/null +++ b/libs/ngrx-notification/backend/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nrwl/nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "angularChallenges", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "angular-challenges", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/libs/ngrx-notification/backend/README.md b/libs/ngrx-notification/backend/README.md new file mode 100644 index 0000000..637ceb1 --- /dev/null +++ b/libs/ngrx-notification/backend/README.md @@ -0,0 +1,7 @@ +# ngrx-notification-backend + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test ngrx-notification-backend` to execute the unit tests. diff --git a/libs/ngrx-notification/backend/jest.config.ts b/libs/ngrx-notification/backend/jest.config.ts new file mode 100644 index 0000000..be62390 --- /dev/null +++ b/libs/ngrx-notification/backend/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +export default { + displayName: 'ngrx-notification-backend', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + globals: { + 'ts-jest': { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + }, + coverageDirectory: '../../../coverage/libs/ngrx-notification/backend', + transform: { + '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular', + }, + 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/libs/ngrx-notification/backend/project.json b/libs/ngrx-notification/backend/project.json new file mode 100644 index 0000000..eeb1e49 --- /dev/null +++ b/libs/ngrx-notification/backend/project.json @@ -0,0 +1,27 @@ +{ + "name": "ngrx-notification-backend", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "library", + "sourceRoot": "libs/ngrx-notification/backend/src", + "prefix": "angular-challenges", + "targets": { + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/ngrx-notification/backend/jest.config.ts", + "passWithNoTests": true + } + }, + "lint": { + "executor": "@nrwl/linter:eslint", + "options": { + "lintFilePatterns": [ + "libs/ngrx-notification/backend/**/*.ts", + "libs/ngrx-notification/backend/**/*.html" + ] + } + } + }, + "tags": [] +} diff --git a/libs/ngrx-notification/backend/src/index.ts b/libs/ngrx-notification/backend/src/index.ts new file mode 100644 index 0000000..bf72113 --- /dev/null +++ b/libs/ngrx-notification/backend/src/index.ts @@ -0,0 +1 @@ +export * from './lib/push.service'; diff --git a/apps/ngrx-notification/src/app/backend/push.service.ts b/libs/ngrx-notification/backend/src/lib/push.service.ts similarity index 76% rename from apps/ngrx-notification/src/app/backend/push.service.ts rename to libs/ngrx-notification/backend/src/lib/push.service.ts index e7fe2be..c1fda14 100644 --- a/apps/ngrx-notification/src/app/backend/push.service.ts +++ b/libs/ngrx-notification/backend/src/lib/push.service.ts @@ -1,11 +1,16 @@ +import { + Push, + randStudent, + randTeacher, +} from '@angular-challenges/ngrx-notification/model'; import { Injectable } from '@angular/core'; import { BehaviorSubject, tap, timer } from 'rxjs'; -import { randStudent } from '../model/student.model'; -import { randTeacher } from '../model/teacher.model'; @Injectable({ providedIn: 'root' }) export class PushService { - private notificationSubject = new BehaviorSubject(undefined); + private notificationSubject = new BehaviorSubject( + undefined + ); notification$ = this.notificationSubject.asObservable(); init() { diff --git a/libs/ngrx-notification/backend/src/test-setup.ts b/libs/ngrx-notification/backend/src/test-setup.ts new file mode 100644 index 0000000..1100b3e --- /dev/null +++ b/libs/ngrx-notification/backend/src/test-setup.ts @@ -0,0 +1 @@ +import 'jest-preset-angular/setup-jest'; diff --git a/libs/ngrx-notification/backend/tsconfig.json b/libs/ngrx-notification/backend/tsconfig.json new file mode 100644 index 0000000..7504c34 --- /dev/null +++ b/libs/ngrx-notification/backend/tsconfig.json @@ -0,0 +1,28 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "target": "es2020", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/libs/ngrx-notification/backend/tsconfig.lib.json b/libs/ngrx-notification/backend/tsconfig.lib.json new file mode 100644 index 0000000..dd189dc --- /dev/null +++ b/libs/ngrx-notification/backend/tsconfig.lib.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": [ + "src/test-setup.ts", + "**/*.spec.ts", + "jest.config.ts", + "**/*.test.ts" + ], + "include": ["**/*.ts"] +} diff --git a/libs/ngrx-notification/backend/tsconfig.spec.json b/libs/ngrx-notification/backend/tsconfig.spec.json new file mode 100644 index 0000000..7aa46d8 --- /dev/null +++ b/libs/ngrx-notification/backend/tsconfig.spec.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] +} diff --git a/libs/ngrx-notification/model/.eslintrc.json b/libs/ngrx-notification/model/.eslintrc.json new file mode 100644 index 0000000..946116f --- /dev/null +++ b/libs/ngrx-notification/model/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nrwl/nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "angularChallenges", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "angular-challenges", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/libs/ngrx-notification/model/README.md b/libs/ngrx-notification/model/README.md new file mode 100644 index 0000000..1a547f2 --- /dev/null +++ b/libs/ngrx-notification/model/README.md @@ -0,0 +1,7 @@ +# ngrx-notification-model + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test ngrx-notification-model` to execute the unit tests. diff --git a/libs/ngrx-notification/model/jest.config.ts b/libs/ngrx-notification/model/jest.config.ts new file mode 100644 index 0000000..a4d32f3 --- /dev/null +++ b/libs/ngrx-notification/model/jest.config.ts @@ -0,0 +1,22 @@ +/* eslint-disable */ +export default { + displayName: 'ngrx-notification-model', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + globals: { + 'ts-jest': { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + }, + coverageDirectory: '../../../coverage/libs/ngrx-notification/model', + transform: { + '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular', + }, + 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/libs/ngrx-notification/model/project.json b/libs/ngrx-notification/model/project.json new file mode 100644 index 0000000..5f69b48 --- /dev/null +++ b/libs/ngrx-notification/model/project.json @@ -0,0 +1,27 @@ +{ + "name": "ngrx-notification-model", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "library", + "sourceRoot": "libs/ngrx-notification/model/src", + "prefix": "angular-challenges", + "targets": { + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/ngrx-notification/model/jest.config.ts", + "passWithNoTests": true + } + }, + "lint": { + "executor": "@nrwl/linter:eslint", + "options": { + "lintFilePatterns": [ + "libs/ngrx-notification/model/**/*.ts", + "libs/ngrx-notification/model/**/*.html" + ] + } + } + }, + "tags": [] +} diff --git a/libs/ngrx-notification/model/src/index.ts b/libs/ngrx-notification/model/src/index.ts new file mode 100644 index 0000000..d81af44 --- /dev/null +++ b/libs/ngrx-notification/model/src/index.ts @@ -0,0 +1,3 @@ +export * from './lib/push.model'; +export * from './lib/student.model'; +export * from './lib/teacher.model'; diff --git a/apps/ngrx-notification/src/app/model/push.model.ts b/libs/ngrx-notification/model/src/lib/push.model.ts similarity index 100% rename from apps/ngrx-notification/src/app/model/push.model.ts rename to libs/ngrx-notification/model/src/lib/push.model.ts diff --git a/apps/ngrx-notification/src/app/model/student.model.ts b/libs/ngrx-notification/model/src/lib/student.model.ts similarity index 100% rename from apps/ngrx-notification/src/app/model/student.model.ts rename to libs/ngrx-notification/model/src/lib/student.model.ts diff --git a/apps/ngrx-notification/src/app/model/teacher.model.ts b/libs/ngrx-notification/model/src/lib/teacher.model.ts similarity index 93% rename from apps/ngrx-notification/src/app/model/teacher.model.ts rename to libs/ngrx-notification/model/src/lib/teacher.model.ts index 984a801..3fd5707 100644 --- a/apps/ngrx-notification/src/app/model/teacher.model.ts +++ b/libs/ngrx-notification/model/src/lib/teacher.model.ts @@ -24,7 +24,7 @@ export interface Teacher extends Push { const factoryTeacher = incrementalNumber(); -export const randTeacher = () => ({ +export const randTeacher = (): Teacher => ({ id: factoryTeacher(), firstname: randFirstName(), lastname: randLastName(), diff --git a/libs/ngrx-notification/model/src/test-setup.ts b/libs/ngrx-notification/model/src/test-setup.ts new file mode 100644 index 0000000..1100b3e --- /dev/null +++ b/libs/ngrx-notification/model/src/test-setup.ts @@ -0,0 +1 @@ +import 'jest-preset-angular/setup-jest'; diff --git a/libs/ngrx-notification/model/tsconfig.json b/libs/ngrx-notification/model/tsconfig.json new file mode 100644 index 0000000..7504c34 --- /dev/null +++ b/libs/ngrx-notification/model/tsconfig.json @@ -0,0 +1,28 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "target": "es2020", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/libs/ngrx-notification/model/tsconfig.lib.json b/libs/ngrx-notification/model/tsconfig.lib.json new file mode 100644 index 0000000..dd189dc --- /dev/null +++ b/libs/ngrx-notification/model/tsconfig.lib.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": [ + "src/test-setup.ts", + "**/*.spec.ts", + "jest.config.ts", + "**/*.test.ts" + ], + "include": ["**/*.ts"] +} diff --git a/libs/ngrx-notification/model/tsconfig.spec.json b/libs/ngrx-notification/model/tsconfig.spec.json new file mode 100644 index 0000000..7aa46d8 --- /dev/null +++ b/libs/ngrx-notification/model/tsconfig.spec.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 11253ac..e0ca0da 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -14,7 +14,14 @@ "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", - "paths": {} + "paths": { + "@angular-challenges/ngrx-notification/backend": [ + "libs/ngrx-notification/backend/src/index.ts" + ], + "@angular-challenges/ngrx-notification/model": [ + "libs/ngrx-notification/model/src/index.ts" + ] + } }, "exclude": ["node_modules", "tmp"] }