Building management school with Spring boot & Angular Pt 3

Getting Started | Building an Application with Angular


Angular 10 Front-end

In this tutorial We will build an application School To display the database Add, update or delete.


Technology

Angular 10

Angular HTTPClient

Angular Router


Angular CLI version (10.1.1)

ng new

The Angular CLI makes it easy to create an application that already works, right out of the box. It already follows our best practices!


ng generate

Generate components, routes, services and pipes with a simple command. The CLI will also create simple test shells for all of these.


ng serve

Easily test your app locally while developing.



$  npm install -g @angular/cli
$ ng new school
$ cd school
$ ng serve

Project Structure


Font Awesome

Font Awesome is a font and icon toolkit based on CSS and Less. It was made by Dave Gandy for use with Bootstrap, and later was incorporated into the BootstrapCDN. Font Awesome has a 38% market share among those websites that use third-party font scripts on their platform, ranking it second place after Google Fonts.


Add this link in index.html to use Font Awesome


<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous">

Angular Material Tutorial

The idea of this is article is to teach you how to use Angular Material through a hands-on exercise. First, you will check the dependencies that you need on your computer to use and develop with Angular Material, then you will learn how to configure and use different components.


Install Angular Material

Angular Material In addition to the install schematic, Angular Material comes with several schematics (like nav, table, address-form, etc.) that can be used to easily generate pre-built components in your application.


$  ng add @angular/material

MaterialModule

In earlier versions of Angular Material, we could import MaterialModule which imports all components from Angular Material and makes them available in our app. Most of the time we will need to import the most of material.


src/app/material-module.ts


import { NgModule } from '@angular/core'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatBadgeModule } from '@angular/material/badge'; import { MatBottomSheetModule } from '@angular/material/bottom-sheet'; import { MatButtonModule } from '@angular/material/button'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatCardModule } from '@angular/material/card'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatChipsModule } from '@angular/material/chips'; import { MatStepperModule } from '@angular/material/stepper'; import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatDialogModule } from '@angular/material/dialog'; import { MatDividerModule } from '@angular/material/divider'; import { MatExpansionModule } from '@angular/material/expansion'; import { MatGridListModule } from '@angular/material/grid-list'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatListModule } from '@angular/material/list'; import { MatMenuModule } from '@angular/material/menu'; import { MatNativeDateModule, MatRippleModule } from '@angular/material/core'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatRadioModule } from '@angular/material/radio'; import { MatSelectModule } from '@angular/material/select'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatSliderModule } from '@angular/material/slider'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { MatSnackBarModule } from '@angular/material/snack-bar'; import { MatSortModule } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; import { MatTabsModule } from '@angular/material/tabs'; import { MatToolbarModule } from '@angular/material/toolbar'; import { MatTooltipModule } from '@angular/material/tooltip'; import { MatTreeModule } from '@angular/material/tree'; @NgModule({ exports: [ MatAutocompleteModule, MatBadgeModule, MatBottomSheetModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatStepperModule, MatDatepickerModule, MatDialogModule, MatDividerModule, MatExpansionModule, MatGridListModule, MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule, MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule, MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule, MatTooltipModule, MatTreeModule, ], imports: [ MatAutocompleteModule, MatBadgeModule, MatBottomSheetModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatStepperModule, MatDatepickerModule, MatDialogModule, MatDividerModule, MatExpansionModule, MatGridListModule, MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatNativeDateModule, MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule, MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule, MatTooltipModule, MatTreeModule, ] }) export class MaterialModule { }

Modals interfaces

The purpose of this class is to map the specified fields with the fields of Spring entity class.


Angular NgModules differ from and complement JavaScript (ES2015) modules. An NgModule declares a compilation context for a set of components that is dedicated to an application domain, a workflow, or a closely related set of capabilities. An NgModule can associate its components with related code, such as services, to form functional units.


Every Angular app has a root module, conventionally named AppModule, which provides the bootstrap mechanism that launches the application. An app typically contains many functional modules.


src/app/modal/Modal.ts


export interface PersistableElement { id: number ; createdAt: any; description: string; } export interface Activity extends PersistableElement { type: string; day: string; endDate: string; startDate: string; date: string; } export interface Coefficient extends PersistableElement { grade: number ; } export interface Exam extends PersistableElement { date: string; start: string; end: string; } export interface Manager extends PersistableElement { id: number ; firstName: string; lastName: string; } export interface Subject extends PersistableElement { name: string; color: string; programs: Program[]; coefficients: Coefficient[]; } export interface Note extends PersistableElement { score: number ; } export interface Program extends PersistableElement { name: string; } export interface Room extends PersistableElement { code: string; capacity: number ; levels: Level[]; } export interface School extends PersistableElement { name: string; city: string; department: string; open: string; close: string; } export interface Schooling extends PersistableElement { year: number ; } export interface Level extends PersistableElement { label: string; courses: Course[]; } export interface Course extends PersistableElement { date: string; endDate: string; startDate: string; }

Angular Services

Angular services are singleton objects that get instantiated only once during the lifetime of an application. They contain methods that maintain data throughout the life of an application, i.e. data does not get refreshed and is available all the time. The main objective of a service is to organize and share business logic, models, or data and functions with different components of an Angular application.


An example of when to use services would be to transfer data from one controller to another custom service.


Why Should We Use Services in Angular? The separation of concerns is the main reason why Angular services came into existence. An Angular service is a stateless object and provides some very useful functions. These functions can be invoked from any component of Angular, like Controllers, Directives, etc. This helps in dividing the web application into small, different logical units which can be reused.


Create Data services

This service will use Angular HTTPClient to send HTTP requests. You can see that its functions includes CRUD operations and finder method


Create these services in the service package

-> activity.service.ts

-> coefficient.service.ts

-> course.service.ts

-> exam.service.ts

-> level.service.ts

-> manager.service.ts

-> note.service.ts

-> program.service.ts

-> room.service.ts

-> school.service.ts

-> schooling.service.ts

-> subject.service.ts

-> tree-application.service.ts


src/app/service/activity.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class ActivityService { constructor(private http: HttpClient) { } addActivity(data: any, id: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addActivity/${id}`, data); } editActivity(data: any, id: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editActivity/${id}`, data); } findActivity(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findActivity/${id}`); } deleteActivity(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteActivity/${id}`); } findActivitiesForSchool(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findActivitiesForSchool/${id}`); } }

src/app/service/coefficient.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class CoefficientService { constructor(private http: HttpClient) { } addCoefficient(data: any, id: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addCoefficient/${id}`, data); } editCoefficient(data: any, id: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editCoefficient/${id}`, data); } findCoefficient(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findCoefficient/${id}`); } deleteCoefficient(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteCoefficient/${id}`); } }

src/app/service/course.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class CourseService { constructor(private http: HttpClient) { } addCourse(data: any, idLevel: number, idSubject: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addCourse/${idLevel}/${idSubject}`, data); } editCourse(data: any, idCourse: number, idSubject: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editCourse/${idCourse}/${idSubject}`, data); } findCourse(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findCourse/${id}`); } deleteCourse(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteCourse/${id}`); } }

src/app/service/exam.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class ExamService { constructor(private http: HttpClient) { } addExam(data: any, idSchool: number, idSubject: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addExam/${idSchool}/${idSubject}`, data); } editExam(data: any, idCourse: number, idSubject: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editExam/${idCourse}/${idSubject}`, data); } findExam(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findExam/${id}`); } deleteExam(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteExam/${id}`); } findExamsForSchool(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findExamsForSchool/${id}`); } }

src/app/service/exam.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class LevelService { constructor(private http: HttpClient) { } addLevel(data: any, id: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addLevel/${id}`, data); } editLevel(data: any, id: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editLevel/${id}`, data); } findLevel(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findLevel/${id}`); } deleteLevel(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteLevel/${id}`); } addLevelToRoom(idRoom: number, idLevel: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addLevelToRoom/${idRoom}/${idLevel}`); } findLevelForRoom(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findLevelForRoom/${id}`); } findLevels(): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findLevels`); } deleteLevelFromRoom(idRoom: number, idLevel: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteLevelFromRoom/${idRoom}/${idLevel}`); } }

src/app/service/manager.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class ManagerService { constructor(private http: HttpClient) { } addManager(data: any, id: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addManager/${id}`, data); } editManager(data: any, id: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editManager/${id}`, data); } deleteManager(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteManager/${id}`); } findManager(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findManager/${id}`); } findManagerForSchool(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findManagerForSchool/${id}`); } }

src/app/service/note.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class NoteService { constructor(private http: HttpClient) { } addNote((data: any, id: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addNote/${id}`, data); } editNote(data: any, id: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editNote/${id}`, data); } findNote(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findNote/${id}`); } deleteNote(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteNote/${id}`); } }

src/app/service/program.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class ProgramService { constructor(private http: HttpClient) { } addProgram((data: any, id: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addProgram/${id}`, data); } editProgram(data: any, id: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editProgram/${id}`, data); } findProgram(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findProgram/${id}`); } deleteProgram(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteProgram/${id}`); } }

src/app/service/room.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class RoomService { constructor(private http: HttpClient) { } addRoom((data: any, id: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addRoom/${id}`, data); } editRoom(data: any, id: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editRoom/${id}`, data); } findRoom(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findRoom/${id}`); } deleteRoom(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteRoom/${id}`); } findRoomsForSchool(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findRoomsForSchool/${id}`); } }

src/app/service/school.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class SchoolService { constructor(private http: HttpClient) { } addSchool((data: any): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addSchool`, data); } editSchool(data: any, id: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editSchool/${id}`, data); } findSchool(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findSchool/${id}`); } deleteSchool(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteSchool/${id}`); } findSchools(): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findSchools`); } }

src/app/service/schooling.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class SchoolingService { constructor(private http: HttpClient) { } addSchooling((data: any, id: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addSchooling/${id}`, data); } editSchooling(data: any, id: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editSchooling/${id}`, data); } findSchooling(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findSchooling/${id}`); } deleteSchooling(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteSchooling/${id}`); } findSchoolingsForSchool(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findSchoolingsForSchool/${id}`); } }

src/app/service/subject.service.ts


import { Injectable } form '@angular/core'; import { Observable } form 'rxjs'; import { HttpClient } form '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class SubjectService { constructor(private http: HttpClient) { } addSubject((data: any, id: number): Observable<any> { return this.http.post<any>(`http://localhost:8080/api/addSubject/${id}`, data); } editSubject(data: any, id: number): Observable<any> { return this.http.put<any>(`http://localhost:8080/api/editSubject/${id}`, data); } findSubject(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findSubject/${id}`); } deleteSubject(id: number): Observable<any> { return this.http.delete<any>(`http://localhost:8080/api/deleteSubject/${id}`); } findAllSubjectsForSchool(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findAllSubjectsForSchool/${id}`); } findSubjectForExam(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findSubjectForExam/${id}`); } findSubjectForCourse(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findSubjectForCourse/${id}`); } findSubjectsForSchool(id: number): Observable<any> { return this.http.get<any>(`http://localhost:8080/api/findSubjectsForSchool/${id}`); } }

Flat tree

The mat-tree provides a Material Design styled tree that can be used to display hierarchy data.
This tree builds on the foundation of the CDK tree and uses a similar interface for its data source input and template, except that its element and attribute selectors will be prefixed with mat- instead of cdk-.
There are two types of trees: Flat tree and nested tree. The DOM structures are different for these two types of trees.


In a flat tree, the hierarchy is flattened; nodes are not rendered inside of each other, but instead are rendered as siblings in sequence. An instance of TreeFlattener is used to generate the flat list of items from hierarchical data. The "level" of each tree node is read through the getLevel method of the TreeControl; this level can be used to style the node such that it is indented to the appropriate level.


src/app/service/tree-application.service.ts


import { Injectable } form '@angular/core' ; import { ActivatedRoute } form '@angular/router' ; import { BehaviorSubject, Observable } form 'rxjs' ; import { School } form '../modal/Modal' ; import { SchoolService } form './school.service' ; export class NodeAction { linkActive: string; url: string; title: string; } export class ApplicationItemNode { children: ApplicationItemNode[] = []; name: string; id: number; clazz: string; actions: NodeAction[] = []; title: string; routerLink: any; } export class ApplicationItemFlatNode { id: number; item: string; clazz: string; level: number; name: string; expandable: boolean; actions: NodeAction[] = []; title: string; routerLink: any; } @Injectable({ providedIn: 'root' }) export class TreeApplicationService { idSchool: any; applicationData = new BehaviorSubject<ApplicationItemNode[]>([]); applicationState = new BehaviorSubject<School>({} as School); constructor(private route: ActivatedRoute, private schoolService: SchoolService) { this.initialize(); } initialize() { this.idSchool = this.route.snapshot.params.idSchool; this.applicationState.subscribe(() => { this.buildFileTree(0).subscribe(value => { this.applicationData.next(value); }); }); this.buildFileTree(0).subscribe(value => { this.applicationData.next(value); }); } get data(): ApplicationItemNode[] { return this.applicationData.value; } buildFileTree(level: number): Observable<ApplicationItemNode[]> { const nodes: ApplicationItemNode[] = []; return new Observable((observer) => { return this.schoolService.findSchool(this.idSchool).subscribe(school => { const activityRoot = new ApplicationItemNode(); activityRoot.name = 'Activities'; activityRoot.title = 'More details'; activityRoot.clazz = 'fas fa-swimmer'; activityRoot.routerLink = '/find-school/' + school.id + '/find-activities'; nodes.push(activityRoot); if(school.activities.length > 0) { school.activities.forEach((activity) => { const activityNodeRoot = new ApplicationItemNode(); activityNodeRoot.name = 'Activity ' + activity.type; activityNodeRoot.title = 'Level details'; activityNodeRoot.clazz = 'fas fa-swimmer'; activityNodeRoot.routerLink = '/find-school/' + school.id + '/find-activity/' + activity.id; activityRoot.children.push(activityNodeRoot); }); } const SubjectRoot = new ApplicationItemNode(); SubjectRoot.name = 'Subjects'; SubjectRoot.title = 'More details'; SubjectRoot.clazz = 'far fa-copy'; SubjectRoot.routerLink = '/find-school/' + school.id + '/find-subjects'; nodes.push(SubjectRoot); if (school.subjects.length > 0 && Array.isArray(school.subjects)) { school.subjects.forEach((subject) => { const subjectNodeRoot = new ApplicationItemNode(); subjectNodeRoot.name = subject.name; subjectNodeRoot.title = 'Parent details'; subjectNodeRoot.clazz = 'far fa-copy'; subjectNodeRoot.routerLink = '/find-school/' + school.id + '/find-subject/' + subject.id; SubjectRoot.children.push(subjectNodeRoot); if(subject.programs.length > 0) { subject.programs.forEach((program) => { const programNodeRoot = new ApplicationItemNode(); programNodeRoot.name = program.name; programNodeRoot.clazz = 'fas fa-project-diagram'; programNodeRoot.routerLink = '/find-school/' + school.id + '/find-program/' + program.id; subjectNodeRoot.children.push(programNodeRoot); if(program.coefficients.length > 0) { program.coefficients.forEach((coefficient) => { const coefficientNodeRoot = new ApplicationItemNode(); coefficientNodeRoot.name = 'Coefficient = (' + coefficient.grade + ')'; coefficientNodeRoot.clazz = 'fas fa-not-equal'; coefficientNodeRoot.routerLink = '/find-school/' + school.id + '/find-coefficient/' + coefficient.id; programNodeRoot.children.push(coefficientNodeRoot); }); } }); } }); } const examRoot = new ApplicationItemNode(); examRoot.name = 'Exams'; examRoot.title = 'More details'; examRoot.clazz = 'fas fa-book-open'; examRoot.routerLink = '/find-school/' + school.id + '/find-exams'; nodes.push(examRoot); if(school.exams.length > 0) { school.exams.forEach((exam) => { const examNodeRoot = new ApplicationItemNode(); examNodeRoot.name = 'Date: ' + exam.date; examNodeRoot.title = 'Level details'; examNodeRoot.clazz = 'fas fa-book-open'; examNodeRoot.routerLink = '/find-school/' + school.id + '/find-exam/' + exam.id; examRoot.children.push(examNodeRoot); if(exam.notes.length > 0) { exam.notes.forEach((note, index) => { const noteNodeRoot = new ApplicationItemNode(); const noteLength = index + 1; noteNodeRoot.name = 'Note ' + noteLength; noteNodeRoot.clazz = 'fas fa-book'; noteNodeRoot.routerLink = '/find-school/' + school.id + '/find-note/' + note.id; examNodeRoot.children.push(noteNodeRoot); }); } }); } const roomRoot = new ApplicationItemNode(); roomRoot.name = 'Rooms'; roomRoot.title = 'More details'; roomRoot.clazz = 'fas fa-university'; roomRoot.routerLink = '/find-school/' + school.id + '/find-rooms'; nodes.push(roomRoot); if(school.rooms.length > 0) { school.rooms.forEach((room) => { const roomNodeRoot = new ApplicationItemNode(); roomNodeRoot.name = 'Room ' + room.code; roomNodeRoot.title = 'Level details'; roomNodeRoot.clazz = 'fas fa-university'; roomNodeRoot.routerLink = '/find-school/' + school.id + '/find-room/' + room.id; roomRoot.children.push(roomNodeRoot); }); } const yearRoot = new ApplicationItemNode(); yearRoot.name = 'Schoolings'; yearRoot.title = 'More details'; yearRoot.clazz = 'fas fa-calendar-alt'; yearRoot.routerLink = '/find-school/' + school.id + '/find-schoolings'; nodes.push(yearRoot); if(school.schoolings.length > 0) { school.schoolings.forEach((schooling) => { const schoolingNodeRoot = new ApplicationItemNode(); schoolingNodeRoot.name = 'Year ' + schooling.year; schoolingNodeRoot.title = 'Year details'; schoolingNodeRoot.clazz = 'fas fa-calendar-alt'; schoolingNodeRoot.routerLink = '/find-school/' + school.id + '/find-schoolling/' + schooling.id; yearRoot.children.push(schoolingNodeRoot); if (schooling.levels.length > 0) { schooling.levels.forEach((level) => { const levelNodeRoot = new ApplicationItemNode(); levelNodeRoot.name = level.label; levelNodeRoot.title = 'More details'; levelNodeRoot.clazz = 'fas fa-swatchbook'; levelNodeRoot.routerLink = '/find-school/' + school.id + '/find-level/' + level.id; schoolingNodeRoot.children.push(levelNodeRoot); if(level.courses.length > 0) { level.courses.forEach((course, index) => { const courseNodeRoot = new ApplicationItemNode(); const courseLength = index + 1; courseNodeRoot.name = 'Course: ' + courseLength; courseNodeRoot.title = 'More details'; courseNodeRoot.clazz = 'fas fa-atlas'; courseNodeRoot.routerLink = '/find-school/' + school.id + '/find-course/' + course.id; levelNodeRoot.children.push(courseNodeRoot); }); } }); } }); } observer.next(nodes); }) }); } }

Components

The @Component decorator identifies the class immediately below it as a component class, and specifies its metadata. In the example code below, you can see that Component is just a class, with no special Angular notation or syntax at all. It's not a component until you mark it as one with the @Component decorator.


The metadata for a component tells Angular where to get the major building blocks that it needs to create and present the component and its view. In particular, it associates a template with the component, either directly with inline code, or by reference. Together, the component and its template describe a view.


In addition to containing or pointing to the template, the @Component metadata configures, for example, how the component can be referenced in HTML and what services it requires.


- app.component.html

The above files were created by default when we created new project using the angular-cli command.

We need to create these components


ng generate component add-activity

ng generate component add-coefficient

ng generate component add-course

ng generate component add-exam

ng generate component add-level-to-room

ng generate component add-level

ng generate component add-manager

ng generate component add-note

ng generate component add-program

ng generate component add-room

ng generate component add-school

ng generate component add-schooling

ng generate component add-subject

ng generate component dashboard

ng generate component display-school

ng generate component find-activities

ng generate component find-activity

ng generate component find-coefficient

ng generate component find-course

ng generate component find-exam

ng generate component find-exams

ng generate component find-level-to-room

ng generate component find-level

ng generate component find-note

ng generate component find-program

ng generate component find-room

ng generate component find-rooms

ng generate component find-school

ng generate component find-schooling

ng generate component find-schoolings

ng generate component find-subject

ng generate component find-subjects

ng generate component home


Add the AppRoutingModule

In Angular, the best practice is to load and configure the router in a separate, top-level module that is dedicated to routing and imported by the root AppModule.


By convention, the module class name is AppRoutingModule and it belongs in the app-routing.module.ts in the src/app folder.


app-routing-module.ts

src/app/app-routing.module.ts


import { NgModule } form '@angular/core'; import { Routes, RouterModule } form '@angular/router'; import { HomeComponent } form './home/home.component'; import { FindSchoolComponent } form './find-school/find-school.component'; import { DisplaySchoolComponent } form './display-school/display-school.component'; import { FindActivityComponent } form './find-activity/find-activity.component'; import { FindActivitiesComponent } form './find-activities/find-activities.component'; import { FindSchoolingsComponent } form './find-schoolings/find-schoolings.component'; import { FindSchoolingComponent } form './find-schooling/find-schooling.component'; import { FindRoomsComponent } form './find-rooms/find-rooms.component'; import { FindRoomComponent } form './find-room/find-room.component'; import { FindSubjectsComponent } form './find-subjects/find-subjects.component'; import { FindSubjectComponent } form './find-subject/find-subject.component'; import { FindProgramComponent } form './find-program/find-program.component'; import { FindCoefficientComponent } form './find-coefficient/find-coefficient.component'; import { FindExamsComponent } form './find-exams/find-exams.component'; import { FindExamComponent } form './find-exam/find-exam.component'; import { FindNoteComponent } form './find-note/find-note.component'; import { FindLevelComponent } form './find-level/find-level.component'; import { AddCourseComponent } form './add-course/add-course.component'; import { FindCourseComponent } form './find-course/find-course.component'; import { DashboardComponent } form './dashboard/dashboard.component'; const routes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: 'find-school/:idSchool', component: FindSchoolComponent, children: [ { path: '', component: DashboardComponent }, { path: 'display-school/:idSchool', component: DisplaySchoolComponent }, { path: 'find-activities', component: FindActivitiesComponent }, { path: 'find-activity/:idActivity', component: FindActivityComponent }, { path: 'find-schoolings', component: FindSchoolingsComponent }, { path: 'find-schoolling/:idSchooling', component: FindSchoolingComponent }, { path: 'find-rooms', component: FindRoomsComponent }, { path: 'find-room/:idRoom', component: FindRoomComponent }, { path: 'find-subjects', component: FindSubjectsComponent }, { path: 'find-subject/:idSubject', component: FindSubjectComponent }, { path: 'find-program/:idProgram', component: FindProgramComponent }, { path: 'find-coefficient/:idCoefficient', component: FindCoefficientComponent }, { path: 'find-exams', component: FindExamsComponent }, { path: 'find-exam/:idExam', component: FindExamComponent }, { path: 'find-note/:idNote', component: FindNoteComponent }, { path: 'find-level/:idLevel', component: FindLevelComponent }, { path: 'add-course/:idLevel', component: AddCourseComponent }, { path: 'edit-course/:idCourse', component: AddCourseComponent }, { path: 'find-course/:idCourse', component: FindCourseComponent } ] } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }

src/app/app.component.html


<style> body { margin: 0; font-family: Arial, Helvetica, sans-serif; } .topnav { overflow: hidden; background-color: #333; } .topnav a { float: left; color: #f2f2f2; text-align: center; padding: 14px 16px; text-decoration: none; font-size: 17px; } .topnav a:hover { background-color: #ddd; color: black; } .topnav a.active { background-color: #4CAF50; color: white; } </style> <div class="topnav"> <a class="active" href="/home">Home</;a> <a href="#news">News</a> <a href="#contact">Contact</a> <a href="#about">About</a> >/div> <router-outlet>>/router-outlet>

src/app/home-component.ts


import { Component, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { AddSchoolComponent } from '../add-school/add-school.component'; import { School } from '../modal/Modal'; import { SchoolService } from '../service/school.service'; @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.css'] }) export class HomeComponent implements OnInit { schools: School[]; constructor(private dialog: MatDialog, private schoolService: SchoolService) { } ngOnInit(): void { this.schoolService.findSchools().subscribe((schools) => { this.schools = schools; }); } addSchool() { const id = null; this.dialog.open(AddSchoolComponent, { data: {id}, height: '580px', width: '400px', }); } }

Home Components

In home commnent we will display all school and add a new school

src/app/home-component.html


<div style="width: 30%; float:left"> <mat-card> <mat-card-header> <mat-card-title>Find all schools </mat-card-title> </mat-card-header><hr> <mat-card-content> <mat-list *ngFor="let school of schools"> <mat-list-item> <mat-icon mat-list-icon>school</mat-icon> <div mat-line style="cursor: pointer; color: #73AD21;" [routerLink]="['/find-school/', school.id]">{{school.name}}</div> <div mat-line style="color: #99a1a8;"> {{school.createdAt|date}} </div> </mat-list-item> <mat-divider></mat-divider> </mat-list> <h4 style="color: rgba(117, 114, 114, 0.87); margin-top: 240px; background: #f2f2f2; padding: 5px 10px;">All copy right reserved by issamdrmas</h4> </mat-card-content> </mat-card> </div> <div style="width: 70%; float:right"> <div style="margin: auto; width: 50%; border: 3px solid #73AD21; padding: 10px; margin-top: 40px;"> <mat-card> <mat-card-header> <mat-card-title>Welcome to gestion school</mat-card-title> </mat-card-header><hr> <mat-card-content> <i class="fas fa-school" style="font-size: 200px; margin-left: 130px;"></i> </mat-card-content><hr> <mat-card-actions> <button mat-raised-button color="warn" (click)="addSchool()">Add a new school</button> </mat-card-actions> </mat-card> </div> </div>

Dashboard Components

In dashboard commnent we will display the length of school, activity, subject, exam, room and schooling

src/app/dashboard-component.ts


import { Component, OnInit } from '@angular/core'; import { SchoolService } from '../service/school.service'; import { ActivityService } from '../service/activity.service'; import { ActivatedRoute } from '@angular/router'; import { SubjectService } from '../service/subject.service'; import { ExamService } from '../service/exam.service'; import { RoomService } from '../service/room.service'; import { SchoolingService } from '../service/schooling.service'; @Component({ selector: 'app-dashboard', templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.css'] }) export class DashboardComponent implements OnInit { schoolLength = 0; activityLength = 0; subjectLength = 0; examsLength = 0; roomLength = 0; schoolingLength = 0; constructor(private schoolService: SchoolService, private activityService: ActivityService, private route: ActivatedRoute, private subjectService: SubjectService, private examService: ExamService, private roomService: RoomService, private schoolingService: SchoolingService) { } ngOnInit(): void { const id = this.route.parent.snapshot.params.idSchool; this.schoolService.findSchools().subscribe(schools => { this.schoolLength = schools.length; }) this.activityService.findActivitiesForSchool(id).subscribe(activities => { this.activityLength = activities.length; }) this.subjectService.findAllSubjectsForSchool(id).subscribe(subjects => { this.subjectLength = subjects.length; }) this.examService.findExamsForSchool(id).subscribe(exams => { this.examsLength = exams.length; }) this.roomService.findRoomsForSchool(id).subscribe(rooms => { this.roomLength = rooms.length; }) this.schoolingService.findSchoolingsForSchool(id).subscribe(schoolings => { this.schoolingLength = schoolings.length; }) } }

src/app/dashboard-component.ts


<div id="container"> <div id="left"> <mat-card style="background-color: #9b59b6"> <mat-card-header> <mat-card-title *ngIf="schoolLength>0"> <button mat-mini-fab disabled style="color: #ecf0f1"> {{schoolLength}} </button> </mat-card-title> <mat-card-title *ngIf="schoolLength==0"> <button mat-mini-fab disabled style="color: #ecf0f1"> 0 </button> </mat-card-title> <mat-card-subtitle style="font-weight: bold">Schools</mat-card-subtitle> <mat-card-subtitle style="margin-top: -14px;">Total schools</mat-card-subtitle> </mat-card-header> <mat-divider></mat-divider> <mat-card-actions> <i class="fas fa-school"></i> </mat-card-actions> </mat-card> </div> <div id="center"> <mat-card style="background-color: #3498db"> <mat-card-header> <mat-card-title *ngIf="activityLength>0"> <button mat-mini-fab disabled style="color: #ecf0f1"> {{activityLength}} </button> </mat-card-title> <mat-card-title *ngIf="activityLength==0"> <button mat-mini-fab disabled style="color: #ecf0f1"> 0 </button> </mat-card-title> <mat-card-subtitle style="font-weight: bold">Activities</mat-card-subtitle> <mat-card-subtitle style="margin-top: -14px;">Total activities</mat-card-subtitle> </mat-card-header> <mat-divider></mat-divider> <mat-card-actions> <i class="fas fa-swimmer"></i> </mat-card-actions> </mat-card> </div> <div id="right"> <mat-card style="background-color: #e67e22"> <mat-card-header> <mat-card-title *ngIf="subjectLength>0"> <button mat-mini-fab disabled style="color: #ecf0f1"> {{subjectLength}} </button> </mat-card-title> <mat-card-title *ngIf="subjectLength==0"> <button mat-mini-fab disabled style="color: #ecf0f1"> 0 </button> </mat-card-title> <mat-card-subtitle style="font-weight: bold">Subjects</mat-card-subtitle> <mat-card-subtitle style="margin-top: -14px;">Total subjects</mat-card-subtitle> </mat-card-header> <mat-divider></mat-divider> <mat-card-actions> <i class="far fa-copy"></i> </mat-card-actions> </mat-card> </div> </div> <div id="container"> <div id="left" style="margin-top: 20px !important;"> <mat-card style="background-color: #16a085"> <mat-card-header> <mat-card-title *ngIf="examsLength>0"> <button mat-mini-fab disabled style="color: #ecf0f1"> {{examsLength}} </button> </mat-card-title> <mat-card-title *ngIf="examsLength==0"> <button mat-mini-fab disabled style="color: #ecf0f1"> 0 </button> </mat-card-title> <mat-card-subtitle style="font-weight: bold">Exams</mat-card-subtitle> <mat-card-subtitle style="margin-top: -14px;">Total exams</mat-card-subtitle> </mat-card-header> <mat-divider></mat-divider> <mat-card-actions> <i class="fas fa-book-open"></i> </mat-card-actions> </mat-card> </div> <div id="center" style="margin-top: 20px !important;"> <mat-card style="background-color: #c0392b"> <mat-card-header> <mat-card-title *ngIf="roomLength>0"> <button mat-mini-fab disabled style="color: #ecf0f1"> {{roomLength}} </button> </mat-card-title> <mat-card-title *ngIf="roomLength==0"> <button mat-mini-fab disabled style="color: #ecf0f1"> 0 </button> </mat-card-title> <mat-card-subtitle style="font-weight: bold">Rooms</mat-card-subtitle> <mat-card-subtitle style="margin-top: -14px;">Total rooms</mat-card-subtitle> </mat-card-header> <mat-divider></mat-divider> <mat-card-actions> <i class="far fa-hospital"></i> </mat-card-actions> </mat-card> </div> <div id="right" style="margin-top: 20px !important;"> <mat-card style="background-color: #7f8c8d"> <mat-card-header> <mat-card-title *ngIf="schoolingLength>0"> <button mat-mini-fab disabled style="color: #ecf0f1"> {{schoolingLength}} </button> </mat-card-title> <mat-card-title *ngIf="schoolingLength==0"> <button mat-mini-fab disabled style="color: #ecf0f1"> 0 </button> </mat-card-title> <mat-card-subtitle style="font-weight: bold">Schoolings</mat-card-subtitle> <mat-card-subtitle style="margin-top: -14px;">Total schoolings</mat-card-subtitle> </mat-card-header> <mat-divider></mat-divider> <mat-card-actions> <i class="fas fa-calendar-alt"></i> </mat-card-actions> </mat-card> </div> </div>

src/app/dashboard-component.css


#container { width:100%; } #left, #center, #right { width:32%; float:left; text-align:center; } #center { overflow:hidden; margin: 0 1%; } mat-card-title, mat-card-subtitle { padding-left: 80px; color: #ecf0f1; } #container i { font-size: 40px; color: #ecf0f1; }

Find Activities Components

In find activities commnent we can display all activities

src/app/school/find-activities.component.html


<mat-card class="example-card"> <mat-card-content style="margin: 16px;"> <img mat-card-image src="https://blogsimages.adobe.com/creative/files/2019/06/Fotolia_224946995_M-1.jpg" alt="photo"> </mat-card-content> </mat-card>

Find school Components

In find school commnent We can display all information in tree like list

src/app/find-school.ts


import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { School } from '../model/Model'; import { SchoolService } from '../service/school.service'; import { FlatTreeControl } from '@angular/cdk/tree'; import { MatDialog } from '@angular/material/dialog'; import { MatTreeFlattener, MatTreeFlatDataSource } from '@angular/material/tree'; import { AddSchoolComponent } from '../add-school/add-school.component'; import { ApplicationItemFlatNode, ApplicationItemNode, TreeApplicationService } from '../service/tree-application.service'; @Component({ selector: 'app-find-school', templateUrl: './find-school.component.html', styleUrls: ['./find-school.component.css'], providers: [TreeApplicationService] }) export class FindSchoolComponent implements OnInit { school: School = {} as School; idSchool: number; flatNodeMap = new Map<ApplicationItemFlatNode, ApplicationItemNode>(); nestedNodeMap = new Map<ApplicationItemNode, ApplicationItemFlatNode>(); treeControl: FlatTreeControl<ApplicationItemFlatNode>; treeFlattener: MatTreeFlattener<ApplicationItemNode, ApplicationItemFlatNode>; dataSource: MatTreeFlatDataSource<ApplicationItemNode, ApplicationItemFlatNode>; expandedNodes: ApplicationItemFlatNode[]; constructor(private route: ActivatedRoute, private schoolService: SchoolService, private dialog: MatDialog, private treeApplicationService: TreeApplicationService) { this.route.params.subscribe( params => { this.idSchool = this.route.snapshot.params.idSchool; this.treeFlattener = new MatTreeFlattener(this.transform, this.getLevel, this.isExpandable, this.getChildren); this.treeControl = new FlatTreeControl<ApplicationItemFlatNode>(this.getLevel, this.isExpandable); this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); this.saveExpandedNodes(); this.restoreExpandedNodes(); treeApplicationService.applicationData.subscribe(school => { this.dataSource.data = school; }); this.treeApplicationService.applicationState.next(this.school); this.schoolService.findSchool(this.idSchool).subscribe((school) => { this.school = school; }) } ) } ngOnInit(): void {} getLevel = (node: ApplicationItemFlatNode) => node.level; isExpandable = (node: ApplicationItemFlatNode) => node.expandable; getChildren = (node: ApplicationItemNode): ApplicationItemNode [] => node.children; hasChild = (_: number, nodeDate: ApplicationItemFlatNode) => nodeDate.expandable; hasNoContent = (_: number, nodeData: ApplicationItemFlatNode) => nodeData.item === ''; transform = (node: ApplicationItemNode, level: number) => { const existingNode = this.nestedNodeMap.get(node); const flatNode = existingNode && existingNode.name === node.name ? existingNode : new ApplicationItemFlatNode(); flatNode.name = node.name; flatNode.id = node.id; flatNode.clazz = node.clazz; flatNode.level = level; flatNode.title = node.title; flatNode.routerLink = node.routerLink; flatNode.actions = node.actions; flatNode.expandable = (node.children && node.children.length > 0); this.flatNodeMap.set(flatNode, node); this.nestedNodeMap.set(node, flatNode); return flatNode; } private saveExpandedNodes() { if(this.treeControl && this.treeControl.dataNodes) { this.expandedNodes = new Arrayalt;ApplicationItemFlatNode>(); this.treeControl.dataNodes.forEach(node => { if(node.expandable && this.treeControl.isExpanded(node)) { this.expandedNodes.push(node); } }); } } private restoreExpandedNodes() { if(this.expandedNodes && this.expandedNodes.length > 0) { this.expandedNodes.forEach(node => { this.treeControl.expand(this.treeControl.dataNodes.find(n => n.id === node.id)); }); } } deleteSchool() { if(confirm('Are you sure')) { this.schoolService.deleteSchool(this.idSchool).subscribe(() => { window.location.replace('/home'); }) } } editSchool(id: number) { this.dialog.open(AddSchoolComponent, { data: {id}, height: '580px', width: '400px', }); } }

src/app/find-school.html


<div style="width: 30%; float:left"> <mat-card> <mat-card-header> <mat-card-title> {{school.name}} </mat-card-title> <mat-card-subtitle>{{school.createdAt|date}}</mat-card-subtitle> </mat-card-header> <hr> <mat-card-content> <mat-list-item><i class="fas fa-th-list" style="margin: 0 15px 0 10px;"></i> <a style="color: #4CAF50;" [routerLink]="['/find-school/', school.id]" routerLinkActive="router-link-active" >Dashbaord</a></mat-list-item> <mat-tree [dataSource]="dataSource" [treeControl]="treeControl"> <mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding matTreeNodeToggle> <mat-basic-chip class="checklist-leaf-node root" [routerLink]="[node.routerLink]" routerLinkActive="linkActive"> <a title="{{node.title}}"> <i [ngClass]="node.clazz" style="margin-right: 5px; color: #666a6c;"></i> {{node.name}} </a> </mat-basic-chip> </mat-tree-node> <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding> <span [attr.aria-label]="'toggle ' + node.filename" id="chevronIcon" matTreeNodeToggle style="background: transparent;"> <mat-icon class="mat-icon-rtl-mirror" id="mat-icon-plus"> {{treeControl.isExpanded(node) ? 'arrow_drop_down' : 'arrow_right'}} </mat-icon> </span> <mat-basic-chip class="root" [routerLink]="[node.routerLink]" routerLinkActive="linkActive"> <a title="{{node.title}}"> <i [ngClass]="node.clazz" style="margin-right: 5px; color: #666a6c;"></i> {{node.name}} </a> </mat-basic-chip> </mat-tree-node> </mat-tree> </mat-card-content> <mat-card-actions> <button mat-raised-button color="primary" (click)="editSchool(school.id)">Update school</button> <button mat-raised-button color="warn" (click)="deleteSchool()">Delete school</button> <button mat-raised-button [routerLink]="['/find-school/' + school.id + '/display-school/', school.id]">School details</button> </mat-card-actions> </mat-card> </div> <div style="width: 68%; float:right; margin-top: 30px; padding: 1%;"> <router-outlet></router-outlet> </div>

src/app/find-school.css


.full-height { background: #f1f2f6; } .root { width: 100%; font-size: 16px; display: block; background: #f5f6fa; padding: 0 10px; border-radius: 4px; } a { font-family: initial; color: #2f3542; text-decoration: none; } #mat-icon-plus { color: #666a6c; font-size: 24px; margin-top: 4px; } .root:hover { -webkit-transition: all .4s ease-in-out; -moz-transition: all .4s ease-in-out; transition: all .4s ease-in-out; cursor: pointer; } #chevronIcon { cursor: pointer; } .mat-tree-node { margin-bottom: -15px; } h2 { background: #e58e26; padding: 0 16px; border-radius: 5px; } .linkActive { background-color: #bcffb6 !important; padding: 2px 10px 0 3px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; color: #a94442 !important; -webkit-transition: all .4s ease-in-out; -moz-transition: all .4s ease-in-out; transition: all .4s ease-in-out; } .content-logo { padding-top: 15px; padding-left: 30px; margin-bottom: 10px; } .content-logo .fa-user-graduate { font-size: 24px; color: #2d3436; }

Find Subjects Components

In find subjects commnent we can display all subjects

src/app/school/find-subjects.component.html


<mat-card class="example-card"> <mat-card-content style="margin: 16px;"> <img mat-card-image src="https://i.ytimg.com/vi/AnZxeX_8mVk/maxresdefault.jpg" alt="photo"> </mat-card-content> </mat-card>

Find Exams Components

In find subjects commnent we can display all exams

src/app/school/find-exams.component.html


<mat-card class="example-card"> <mat-card-content style="margin: 16px;"> <img mat-card-image src="https://static01.nyt.com/images/2020/11/22/magazine/22Ethicist/22Ethicist-superJumbo.jpg" alt="photo"> </mat-card-content> </mat-card>

Find Rooms Components

In find rooms commnent we can display all rooms

src/app/school/find-rooms.component.html


<mat-card class="example-card"> <mat-card-content style="margin: 16px;"> <img mat-card-image src="https://thumbs.dreamstime.com/b/illustration-du-vecteur-concept-d-encadrement-professionnel-chef-%C3%A9quipe-promotion-des-employ%C3%A9s-cours-de-perfectionnement-156525531.jpg" alt="photo"> </mat-card-content> </mat-card>

Find Schoolings Components

In find schoolings commnent we can display all schoolings

src/app/school/find-schoolings.component.html


<mat-card class="example-card"> <mat-card-content style="margin: 16px;"> <img mat-card-image src="https://i.ytimg.com/vi/AnZxeX_8mVk/maxresdefault.jpg" alt="photo"> </mat-card-content> </mat-card>

Add School Components

In add school commnent we can add a new school

src/app/add-school-component.ts


import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { School } from '../modal/Modal'; import { SchoolService } from '../service/school.service'; @Component({ selector: 'app-add-school', templateUrl: './add-school.component.html', styleUrls: ['./add-school.component.css'] }) export class AddSchoolComponent implements OnInit { progressBar = false; school: School = {} as School; constructor(private schoolService: SchoolService, @Inject(MAT_DIALOG_DATA) private data: any) {} ngOnInit(): void { if(this.data.id != null) { this.schoolService.findSchool(this.data.id).subscribe((school) => { this.school = school; }); } } addSchool() { this.progressBar = true; if(this.data.id != null) { this.schoolService.editSchool(this.school, this.data.id).subscribe((school) => { this.school = school; window.location.reload(); }); } else { this.schoolService.addSchool(this.school).subscribe((school) => { this.school = school; window.location.reload(); }); } } }

src/app/add-school-component.html


<div style="margin: auto; width: 100%; border: 3px solid #73AD21;"> <mat-card> <mat-card-header> <mat-card-title>Add a new school</mat-card-title> </mat-card-header> <mat-card-content><br> <mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar> <form> <mat-form-field appearance=fill style="width: 100%;"> <mat-label>Enter name</mat-label> <input matInput type="text" placeholder="name" name="name" [(ngModel)]="school.name" #name="ngModel" required> </mat-form-field><br> <mat-form-field appearance=fill style="width: 100%;"> <mat-label>Enter city</mat-label> <input matInput type="text" placeholder="city" name="city" [(ngModel)]="school.city" #city="ngModel" required> </mat-form-field><br> <mat-form-field appearance=fill style="width: 100%;"> <mat-label>Enter department</mat-label> <input matInput type="text" placeholder="department" name="department" [(ngModel)]="school.department" #department="ngModel" required> </mat-form-field><br> <mat-form-field> <mat-label>Enter open</mat-label> <input type="time" matInput placeholder="open" name="open" [(ngModel)]="school.open" #open="ngModel" required> </mat-form-field> <br> <mat-form-field> <mat-label>Enter close</mat-label> <input type="time" matInput placeholder="close" name="close" [(ngModel)]="school.close" #close="ngModel" required> </mat-form-field> <br> <mat-form-field style="width: 100%;"> <mat-label>Enter description</mat-label> <textarea matInput placeholder="Description" name="description" [(ngModel)]="school.description" #description="ngModel"></textarea> </mat-form-field><br> <button mat-raised-button color="primary" [disabled]="name.invalid || city.invalid || description.invalid || department.invalid || open.invalid || close.invalid" (click)="addSchool()" style="width: 10em !important">Save</button> </form> </mat-card-content> </mat-card> </div>

Display School Components

In Display school commnent We will display the school information open time and close time or update/delete. We can also add a new activity, subject, exam, room and schooling

src/app/display-school-component.ts


import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { MatDialog } from '@angular/material/dialog'; import { AddActivityComponent } from '../add-activity/add-activity.component'; import { AddManagerComponent } from '../add-manager/add-manager.component'; import { School, Manager } from '../modal/Modal'; import { ManagerService } from '../service/manager.service'; import { SchoolService } from '../service/school.service'; import { AddSchoolingComponent } from '../add-schooling/add-schooling.component'; import { AddRoomComponent } from '../add-room/add-room.component'; import { AddSubjectComponent } from '../add-subject/add-subject.component'; import { AddExamComponent } from '../add-exam/add-exam.component'; @Component({ selector: 'app-display-school', templateUrl: './display-school.component.html', styleUrls: ['./display-school.component.css'] }) export class DisplaySchoolComponent implements OnInit { school: School = {} as School; manager: Manager = {} as Manager; idSchool: number; constructor(private route: ActivatedRoute, private schoolService: SchoolService, private dialog: MatDialog, private managerService: ManagerService) { this.route.params.subscribe( params => { this.idSchool = this.route.snapshot.params.idSchool; this.schoolService.findSchool(this.idSchool).subscribe((school) => { this.school = school; if(this.manager!=null) { this.managerService.findManagerForSchool(this.idSchool).subscribe((manager) => { this.manager = manager }) } }) }) } ngOnInit(): void {} addManager(id: number) { this.dialog.open(AddManagerComponent, { data: {id}, height: '320px', width: '400px', }); } editManager(idManager: number) { this.dialog.open(AddManagerComponent, { data: {idManager}, height: '320px', width: '400px', }); } deleteManager(idManager: number, idSchool: number) { if(confirm('Are you sur')) { this.managerService.deleteManager(idManager, idSchool).subscribe(() => { window.location.reload(); }) } } addSchoolling(idSchool: number) { this.dialog.open(AddActivityComponent, { data: {idSchool}, height: '600px', width: '400px', }); } addActivity(idSchool: number) { this.dialog.open(AddSchoolingComponent, { data: {idSchool}, height: '300px', width: '400px', }); } addRoom(idSchool: number) { this.dialog.open(AddRoomComponent, { data: {idSchool}, height: '370px', width: '400px', }); } addSubject(idSchool: number) { this.dialog.open(AddSubjectComponent, { data: {idSchool}, height: '620px', width: '400px', }); } addExam(idSchool: number) { this.dialog.open(AddExamComponent, { data: {idSchool}, height: '480px', width: '400px', }); } }

src/app/display-school-component.html


<mat-card> <mat-card-header> <mat-card-title>Welcome to {{school.name}} </mat-card-title> <mat-card-subtitle>{{school.createdAt|date}}</mat-card-subtitle> </mat-card-header><hr> <mat-card-content> <mat-list> <mat-list-item> <div mat-line style="color: #222f3e;"> <h2 *ngIf="manager!=null">Manager: {{manager.firstName}} {{manager.lastName}} <span class="material-icons" (click)="deleteManager(manager.id, school.id)" style="cursor: pointer; color: #c0392b;">close</span> </h2> </div> <div mat-line style="color: #222f3e;">City: {{school.city}}</div> <div mat-line style="color: #222f3e;">Department: {{school.department}}</div> </mat-list-item> </mat-list><</br> <mat-chip-list cdkDropList cdkDropListOrientation="horizontal"> <mat-chip>Open: {{school.open}} </mat-chip> <mat-chip>Close: {{school.close}} </mat-chip> </mat-chip-list> <p style="background: #f5f6fa; padding: 10px; border-radius: 5px; color: #444;"> {{school.description}} </p> </mat-card-content><hr> <mat-card-actions><br> <button mat-stroked-button color="accent" (click)="editManager(manager.id)" *ngIf="manager!=null">Edit the manager</button> <button mat-stroked-button color="accent" (click)="addManager(school.id)" *ngIf="manager==null">Add a manager</button> <button mat-stroked-button color="primary" (click)="addActivity(school.id)">Add an activity</button> <button mat-stroked-button color="primary" (click)="addSchoolling(school.id)">Add a schooling</button> <button mat-stroked-button color="primary" (click)="addRoom(school.id)">Add a room</button> <button mat-stroked-button color="primary" (click)="addSubject(school.id)">Add a subject</button> <button mat-stroked-button color="primary" (click)="addExam(school.id)">Add an exam</button> </mat-card-actions> </mat-card>

Add Manager Components

In add manager commnent we can add a new manager for each school

src/app/add-manager-component.ts


import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { Manager } from '../model/Model'; import { ManagerService} from '../service/manager.service'; @Component({ selector: 'app-add-manager', templateUrl: './add-manager.component.html', styleUrls: ['./add-manager.component.css'] }) export class AddManagerComponent implements OnInit { progressBar = false; manager: Manager = {} as Manager; constructor(private managerService: ManagerService, @Inject(MAT_DIALOG_DATA) private data: any) { } ngOnInit(): void { if(this.data.idManager!=null) { this.managerService.findManager(this.data.idManager).subscribe((manager) => { this.manager = manager; }) } } addManager() { this.progressBar = true; if(this.data.idManager!=null) { this.managerService.editManager(this.manager, this.data.idManager).subscribe((manager) => { this.manager = manager; window.location.reload() }) } else { this.managerService.addManager(this.manager, this.data.id).subscribe((manager) => { this.manager = manager; window.location.reload() }) } } }

src/app/add-manager-component.html


<div style="margin: auto; width: 100%; border: 3px solid #73AD21;"> <mat-card=> <mat-card-header> <mat-card-title>Add a new manager</mat-card-title> </mat-card-header> <mat-card-content><br> <mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar> <form> <mat-form-field appearance= fill style="width: 100%;"> <mat-label>Enter firstName</mat-label> <input matInput type="text" placeholder="firstName" name="firstName" [(ngModel)]="manager.firstName" #firstName="ngModel" required> </mat-form-field><br> <mat-form-field appearance= fill style="width: 100%;"> <mat-label>Enter lastName</mat-label> <input matInput type="text" placeholder="lastName" name="lastName" [(ngModel)]="manager.lastName" #lastName="ngModel" required> </mat-form-field><br> <button mat-raised-button color="primary" [disabled]="firstName.invalid || lastName.invalid" (click)="addManager()" style="width: 10em !important">Save</button> </form> </mat-card-content> </mat-card= </div>

Add Activity Components

In add activity commnent we can add a new activity for each school

src/app/add-activity-component.ts


import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { Activity } from '../model/Model'; import { ActivityService } from '../service/activity.service'; @Component({ selector: 'app-add-activity', templateUrl: './add-activity.component.html', styleUrls: ['./add-activity.component.css'] }) export class AddActivityComponent implements OnInit { progressBar = false; activity: Activity = {} as Activity; weekDay: any = {}; constructor(private activityService: ActivityService, @Inject(MAT_DIALOG_DATA) private data: any) {} ngOnInit(): void { if(this.data.idActivity) { this.activityService.findActivity(this.data.idActivity).subscribe((activity) => { this.activity = activity; }); } } onSelectedDay() { this.activity.day = this.weekDay; } onDateTime(e) { this.activity.date = e.target.value; } addActivity() { this.progressBar = true; if(this.data.idActivity) { this.activityService.editActivity(this.activity, this.data.idActivity).subscribe((activity) => { this.activity = activity; window.location.reload(); }); } else { this.activityService.addActivity(this.activity, this.data.idSchool).subscribe((activity) => { this.activity = activity; window.location.reload(); }); } } }

src/app/add-activity-component.html


<div style="margin: auto; width: 100%; border: 3px solid #73AD21;"> <mat-card> <mat-card-header> <mat-card-title>Add a new activity</mat-card-title> </mat-card-header> <mat-card-content><br> <mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar> <form> <mat-form-field appearance="fill" style="width: 100%;"> <mat-label>Enter type</mat-label> <input matInput type="text" placeholder="type" name="type" [(ngModel)]="activity.type" #type="ngModel" required> </mat-form-field><br> <div style="margin-bottom: 15px;"> <strong>Day</strong> </div> <mat-radio-group [(ngModel)]="weekDay" name="weekDay" (change)="onSelectedDay()"> <mat-radio-button value="Monday">Monday</mat-radio-button> <mat-radio-button value="Tuesday">Tesday</mat-radio-button> <mat-radio-button value="Wednesday">Wendesday</mat-radio-button> <mat-radio-button value="Thursday">Thursday</mat-radio-button> <mat-radio-button value="Friday">Friday</mat-radio-button> </mat-radio-group> <hr> <mat-form-field style="width: 100%;"> <input matInput type="date" name="date" min="minDate" [(ngModel)]="activity.date" #date="ngModel" required (change)="onDateTime($event)"> </mat-form-field> <br> <mat-form-field style="width: 100%;"> <mat-label>START</mat-label> <input matInput type="time" placeholder="startTime" name="startTime" [(ngModel)]="activity.startDate" #startTime="ngModel" required> </mat-form-field> <br> <mat-form-field style="width: 100%;"> <mat-label>END</mat-label> <input matInput type="time" placeholder="endTime" name="endTime" [(ngModel)]="activity.endDate" #endTime="ngModel" required> </mat-form-field> <br> <mat-form-field style="width: 100%;"> <mat-label>Enter description</mat-label> <textarea matInput placeholder="Description" name="description" [(ngModel)]="activity.description" #description="ngModel"></textarea> </mat-form-field><br> <button mat-raised-button color="primary" [disabled]="type.invalid || description.invalid || startTime.invalid || endTime.invalid" (click)="addActivity()" style="width: 10em !important">Save</button> </form> </mat-card-content> </mat-card> </div>

Add schooling Components

In add schooling commnent we can add a new schooling for each school

src/app/add-schooling-component.ts


import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { Schooling } from '../model/Model'; import { SchoolingService } from '../service/schooling.service'; @Component({ selector: 'app-add-schooling', templateUrl: './add-schooling.component.html', styleUrls: ['./add-schooling.component.css'] }) export class AddSchoolingComponent implements OnInit { progressBar = false; schooling: Schooling = {} as Schooling; constructor(private schoolingService: SchoolingService, @Inject(MAT_DIALOG_DATA) private data: any) { } ngOnInit(): void { if (this.data.idSchooling!=null) { this.schoolingService.findSchooling(this.data.idSchooling).subscribe(schooling => { this.schooling = schooling; }) } } addSchoolling() { this.progressBar = true; if (this.data.idSchooling!=null) { this.schoolingService.editSchooling(this.schooling, this.data.idSchooling).subscribe(schooling => { this.schooling = schooling; window.location.reload(); }) } else { this.schoolingService.addSchooling(this.schooling, this.data.idSchool).subscribe(schooling => { this.schooling = schooling; window.location.reload(); }) } } }

src/app/add-schooling-component.html


<div style="margin: auto; width: 100%; border: 3px solid #73AD21;"> <mat-card> <mat-card-header> <mat-card-title>Add a new schoolling</mat-card-title> </mat-card-header> <mat-card-content><br> <mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar> <form> <mat-form-field style="width: 100%;"> <mat-label>Year</mat-label> <input matInput type="number" placeholder="Year" name="year" [(ngModel)]="schooling.year" #year="ngModel" required> </mat-form-field> <br> <mat-form-field style="width: 100%;"> <mat-label>Enter description</mat-label> <textarea matInput placeholder="Description" name="description" [(ngModel)]="schooling.description" #description="ngModel"></textarea> </mat-form-field><br> <button mat-raised-button color="primary" [disabled]="year.invalid || description.invalid" (click)="addSchoolling()" style="width: 10em !important">Save</button> </form> </mat-card-content> </mat-card> </div>

Add room Components

In add room commnent we can add a new room for each school

src/app/add-room-component.ts


import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { Room } from '../model/Model'; import { RoomService } from '../service/room.service'; @Component({ selector: 'app-add-room', templateUrl: './add-room.component.html', styleUrls: ['./add-room.component.css'] }) export class AddRoomComponent implements OnInit { progressBar = false; room: Room = {} as Room; constructor(private roomService: RoomService, @Inject(MAT_DIALOG_DATA) private data: any) { } ngOnInit(): void { if(this.data.idRoom !=null) { this.roomService.findRoom(this.data.idRoom).subscribe(room => { this.room = room; }) } } addRoom() { this.progressBar = true; if(this.data.idRoom !=null ) { this.roomService.editRoom(this.room, this.data.idRoom ).subscribe(room => { this.room = room; window.location.reload(); }) } else { this.roomService.addRoom(this.room, this.data.idSchool).subscribe(room => { this.room = room; window.location.reload(); }) } } }

src/app/add-room-component.html


<div style="margin: auto; width: 100%; border: 3px solid #73AD21;"> <mat-card> <mat-card-header> <mat-card-title>Add a new room</mat-card-title> </mat-card-header> <mat-card-content><br> <mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar> <form> <mat-form-field style="width: 100%;"> <mat-label>Code</mat-label> <input matInput type="text" placeholder="Code" name="code" [(ngModel)]="room.code" #code="ngModel" required> </mat-form-field> <br> <mat-form-field style="width: 100%;"> <mat-label>Capacity</mat-label> <input matInput type="number" placeholder="Capacity" name="capacity" [(ngModel)]="room.capacity" #capacity="ngModel" required> </mat-form-field> <br> <mat-form-field style="width: 100%;"> <mat-label>Enter description</mat-label> <textarea matInput placeholder="Description" name="description" [(ngModel)]="room.description" #description="ngModel"></textarea> </mat-form-field><br> <button mat-raised-button color="primary" [disabled]="capacity.invalid || description.invalid || code.invalid" (click)="addRoom()" style="width: 10em !important">Save</button> </form> </mat-card-content> </mat-card> </div>

Add subject Components

In add subject commnent we can add a new subject for each school

src/app/add-subject-component.ts


import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { Subject } from '../model/Model'; import { SubjectService } from '../service/subject.service'; @Component({ selector: 'app-add-subject', templateUrl: './add-subject.component.html', styleUrls: ['./add-subject.component.css'] }) export class AddSubjectComponent implements OnInit { progressBar = false; subject: Subject = {} as Subject; public arrayColors: any = { color1: '#f8c291', color2: '#d1f28e', color3: 'rgb(255,245,0)', color4: 'rgb(236,64,64)', color5: 'rgba(45,208,45,1)' }; color1: '#d1f28e'; public selectedColor = 'color2'; constructor(private subjectService: SubjectService, @Inject(MAT_DIALOG_DATA) private data: any) { } ngOnInit(): void { if(this.data.idSubject!=null) { this.subjectService.findSubject(this.data.idSubject).subscribe(subject => { this.subject = subject; }) } } updateColor(event) { this.color1 = event; this.subject.color = this.color1; } addMatter() { this.progressBar = true; if(this.data.idSubject!=null) { this.subjectService.editSubject(this.subject, this.data.idSubject).subscribe(subject => { this.subject = subject; window.location.reload(); }) } else { this.subjectService.addSubject(this.subject, this.data.idSchool).subscribe(subject => { this.subject = subject; window.location.reload(); }) } } }

src/app/add-subject-component.html


<div style="margin: auto; width: 100%; border: 3px solid #73AD21;"> <mat-card> <mat-card-header> <mat-card-title>Add a new subject</mat-card-title> </mat-card-header> <mat-card-content><br> <mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar> <form> <mat-form-field style="width: 100%;"> <mat-label>Name</mat-label> <input matInput type="text" placeholder="Name" name="name" [(ngModel)]="subject.name" #name="ngModel" required> </mat-form-field> <br> <mat-form-field style="width: 100%;"> <mat-label>Description</mat-label> <textarea matInput placeholder="Description" name="description" [(ngModel)]="subject.description" #description="ngModel" required></textarea> </mat-form-field> <div> <span [style.background]="arrayColors[selectedColor]" [cpToggle]="true" [cpDialogDisplay]="'inline'" [cpCancelButton]="true" [(colorPicker)]="arrayColors[selectedColor]" (colorPickerChange)="updateColor($event)" ></span> </div><br> <button mat-raised-button color="primary" [disabled]="name.invalid || description.invalid" (click)="addMatter()" style="width: 10em !important">Save</button> </form> </mat-card-content> </mat-card> </div>

Add exam Components

In add exam commnent we can add a new exam for each school

src/app/add-exam-component.ts


import { Component, Inject, OnInit } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material/dialog'; import { Exam, Subject } from '../model/Model'; import { ExamService } from '../service/exam.service'; import { dashCaseToCamelCase } from '@angular/compiler/src/util'; import { SubjectService } from '../service/subject.service'; @Component({ selector: 'app-add-exam', templateUrl: './add-exam.component.html', styleUrls: ['./add-exam.component.css'] }) export class AddExamComponent implements OnInit { progressBar = false; exam: Exam = {} as Exam; idSubject: number; subjects: Subject[]; subject: Subject = {} as Subject; constructor(private examService: ExamService, private subjectService: SubjectService, @Inject(MAT_DIALOG_DATA) private data: any) { } ngOnInit(): void { if(this.data.idExam!=null) { this.examService.findExam(this.data.idExam).subscribe(exam => { this.exam = exam; this.subjectService.findSubjectForExam(this.data.idExam).subscribe(subject => { this.subject = subject; }) }) } this.subjectService.findAllSubjectsForSchool(this.data.idSchool).subscribe(subjects => { this.subjects = subjects; }) } onSelecSubject(e) { this.idSubject = e.target.value; } onDateTime(e) { this.exam.date = e.target.value; } addExam() { this.progressBar = true; if(this.data.idExam!=null) { this.examService.editExam(this.exam, this.data.idExam).subscribe(exam => { this.exam = exam; window.location.reload(); }) } else { this.examService.addExam(this.exam, this.data.idSchool, this.idSubject).subscribe(exam => { this.exam = exam; window.location.reload(); }) } } }

src/app/add-exam-component.html


<div style="margin: auto; width: 100%; border: 3px solid #73AD21;"> <mat-card> <mat-card-header> <mat-card-title>Add a new exam</mat-card-title> </mat-card-header> <mat-card-content><br> <mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar> <form> <mat-form-field style="width: 100%;"> <mat-label>Please choose a subject</mat-label> <select matNativeControl required (change)="onSelecSubject($event)"> <option selected disabled>Subjects</option> <option *ngFor="let s of subjects" [value]="s.id" [selected]="s.name==subject.name">{{s.name}}</option> </select> </mat-form-field><br> <mat-form-field style="width: 100%;"> <input matInput type="date" name="date" min="minDate" [(ngModel)]="exam.date" #date="ngModel" required (change)="onDateTime($event)"> </mat-form-field> <br> <mat-form-field style="width: 100%;"> <mat-label>START</mat-label> <input matInput type="time" placeholder="startTime" name="start" [(ngModel)]="exam.start" #startTime="ngModel" required> </mat-form-field> <br> <mat-form-field style="width: 100%;"> <mat-label>END</mat-label> <input matInput type="time" placeholder="endTime" name="end" [(ngModel)]="exam.end" #endTime="ngModel" required> </mat-form-field> <br> <mat-form-field style="width: 100%;"> <mat-label>Enter description</mat-label> <textarea matInput placeholder="Description" name="description" [(ngModel)]="exam.description" #description="ngModel"></textarea> </mat-form-field><br> <button mat-raised-button color="primary" [disabled]="description.invalid || startTime.invalid || endTime.invalid" (click)="addExam()" style="width: 10em !important">Save</button> </form> </mat-card-content> </mat-card> </div>




Post a Comment

Previous Post Next Post


Follow us on facebook