Marcin Jaborski 3 anni fa
parent
commit
485ab13c28
38 ha cambiato i file con 690 aggiunte e 236 eliminazioni
  1. 0 0
      IWA-angular/src/app/app-heroes/app-routing.module.ts
  2. 0 0
      IWA-angular/src/app/app-heroes/app.component.css
  3. 28 0
      IWA-angular/src/app/app-heroes/app.component.html
  4. 31 0
      IWA-angular/src/app/app-heroes/app.component.spec.ts
  5. 32 0
      IWA-angular/src/app/app-heroes/app.component.ts
  6. 50 0
      IWA-angular/src/app/app-heroes/app.module.ts
  7. 15 26
      IWA-angular/src/app/app.component.html
  8. 3 3
      IWA-angular/src/app/app.component.spec.ts
  9. 1 23
      IWA-angular/src/app/app.component.ts
  10. 14 33
      IWA-angular/src/app/app.module.ts
  11. 0 0
      IWA-angular/src/app/home/home.component.css
  12. 1 0
      IWA-angular/src/app/home/home.component.html
  13. 25 0
      IWA-angular/src/app/home/home.component.spec.ts
  14. 15 0
      IWA-angular/src/app/home/home.component.ts
  15. 7 0
      IWA-angular/src/app/students/student.model.spec.ts
  16. 15 0
      IWA-angular/src/app/students/student.model.ts
  17. 16 0
      IWA-angular/src/app/students/student.service.spec.ts
  18. 124 0
      IWA-angular/src/app/students/student.service.ts
  19. 0 0
      IWA-angular/src/app/students/students.component.css
  20. 59 0
      IWA-angular/src/app/students/students.component.html
  21. 25 0
      IWA-angular/src/app/students/students.component.spec.ts
  22. 115 0
      IWA-angular/src/app/students/students.component.ts
  23. BIN
      IWA/lib/javaee.jar
  24. 7 7
      IWA/pom.xml
  25. 15 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/SpringBootJspIwaApplication.java
  26. 1 0
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/HelloController.java
  27. 8 4
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/StudentController.java
  28. 18 16
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/StudentRESTController.java
  29. 0 84
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/TeamController.java
  30. 7 4
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/Account.java
  31. 6 3
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/Address.java
  32. 8 2
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/Student.java
  33. 3 13
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/Team.java
  34. 9 3
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/repository/StudentRepository.java
  35. 1 1
      IWA/src/main/java/pl/dmcs/springbootjsp_iwa/repository/TeamRepository.java
  36. 4 2
      IWA/src/main/webapp/WEB-INF/views/hello.jsp
  37. 14 12
      IWA/src/main/webapp/WEB-INF/views/student.jsp
  38. 13 0
      IWA/src/test/java/pl/dmcs/springbootjsp_iwa/SpringBootJspIwaApplicationTests.java

+ 0 - 0
IWA-angular/src/app/app-routing.module.ts → IWA-angular/src/app/app-heroes/app-routing.module.ts


+ 0 - 0
IWA-angular/src/app/app-heroes/app.component.css


+ 28 - 0
IWA-angular/src/app/app-heroes/app.component.html

@@ -0,0 +1,28 @@
+<!--<form class="ui large form segment">-->
+<!--  <h3 class="ui header">Add a link</h3>-->
+<!--  <div class="field">-->
+<!--    <label for="title">Title:</label>-->
+<!--    <input type="text" id="title" name="title" #newTitle>-->
+<!--  </div>-->
+<!--  <div class="field">-->
+<!--    <label for="link">Link:</label>-->
+<!--    <input type="text" id="link" name="link" #newLink>-->
+<!--  </div>-->
+<!--  <button (click)="addArticle(newTitle, newLink)" class="ui positive right floated button">Submit link</button>-->
+<!--</form>-->
+
+<!--<div class="ui grid posts">-->
+<!--  <app-article *ngFor="let article of sortedArticles()" [article]="article"></app-article>-->
+<!--</div>-->
+
+
+<h1>{{title}}</h1>
+<nav>
+  <a routerLink="/dashboard">Dashboard</a>
+  <a routerLink="/heroes">Heroes</a>
+</nav>
+<router-outlet></router-outlet>
+<app-messages></app-messages>
+
+
+<!--<app-fibonacci></app-fibonacci>-->

+ 31 - 0
IWA-angular/src/app/app-heroes/app.component.spec.ts

@@ -0,0 +1,31 @@
+import { TestBed } from '@angular/core/testing';
+import { AppComponent } from './app.component';
+
+describe('AppComponent', () => {
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [
+        AppComponent
+      ],
+    }).compileComponents();
+  });
+
+  it('should create the app', () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    const app = fixture.componentInstance;
+    expect(app).toBeTruthy();
+  });
+
+  it(`should have as title 'IWA-angular'`, () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    const app = fixture.componentInstance;
+    expect(app.title).toEqual('IWA-angular');
+  });
+
+  it('should render title', () => {
+    const fixture = TestBed.createComponent(AppComponent);
+    fixture.detectChanges();
+    const compiled = fixture.nativeElement as HTMLElement;
+    expect(compiled.querySelector('.content span')?.textContent).toContain('IWA-angular app is running!');
+  });
+});

+ 32 - 0
IWA-angular/src/app/app-heroes/app.component.ts

@@ -0,0 +1,32 @@
+import { Component } from '@angular/core';
+import {Article} from "./article";
+
+@Component({
+  selector: 'app-root',
+  templateUrl: './app.component.html',
+  styleUrls: ['./app.component.css']
+})
+export class AppComponent {
+  title: string = 'Tour of heroes';
+  articles: Article[];
+
+  constructor() {
+    this.articles = [
+      new Article('Angular', 'https://angular.io', 3),
+      new Article('Fullstack', 'https://fullstack.io', 2),
+      new Article('Angular Homepage', 'https://angular.io', 1),
+    ]
+  }
+
+  addArticle(title: HTMLInputElement, link: HTMLInputElement): boolean {
+    console.log(`Adding article title: ${title.value} and link: ${link.value}`);
+    this.articles.push(new Article(title.value, link.value, 0));
+    title.value = '';
+    link.value = '';
+    return false;
+  }
+
+  sortedArticles() : Article[] {
+    return this.articles.sort((a: Article, b: Article) => b.votes - a.votes);
+  }
+}

+ 50 - 0
IWA-angular/src/app/app-heroes/app.module.ts

@@ -0,0 +1,50 @@
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { FormsModule } from "@angular/forms";
+import { HttpClientModule } from '@angular/common/http';
+import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';
+import { InMemoryDataService } from './in-memory-data.service';
+
+import { AppComponent } from './app.component';
+import { StudentComponentComponent } from './student-component/student-component.component';
+import { HelloWorldComponent } from './hello-world/hello-world.component';
+import { UserItemComponent } from './user-item/user-item.component';
+import { UserListComponent } from './user-list/user-list.component';
+import { ArticleComponent } from './article/article.component';
+import { HeroesComponent } from './heroes/heroes.component';
+import { FibonacciComponent } from './fibonacci/fibonacci.component';
+import { HeroDetailComponent } from './hero-detail/hero-detail.component';
+import { MessagesComponent } from './messages/messages.component';
+import { AppRoutingModule } from './app-routing.module';
+import { DashboardComponent } from './dashboard/dashboard.component';
+import { HeroSearchComponent } from './hero-search/hero-search.component';
+
+
+@NgModule({
+  declarations: [
+    AppComponent,
+    StudentComponentComponent,
+    HelloWorldComponent,
+    UserItemComponent,
+    UserListComponent,
+    ArticleComponent,
+    HeroesComponent,
+    FibonacciComponent,
+    HeroDetailComponent,
+    MessagesComponent,
+    DashboardComponent,
+    HeroSearchComponent
+  ],
+  imports: [
+    BrowserModule,
+    FormsModule,
+    AppRoutingModule,
+    HttpClientModule,
+    HttpClientInMemoryWebApiModule.forRoot(
+      InMemoryDataService, { dataEncapsulation: false }
+    )
+  ],
+  providers: [],
+  bootstrap: [AppComponent]
+})
+export class AppModule { }

+ 15 - 26
IWA-angular/src/app/app.component.html

@@ -1,28 +1,17 @@
-<!--<form class="ui large form segment">-->
-<!--  <h3 class="ui header">Add a link</h3>-->
-<!--  <div class="field">-->
-<!--    <label for="title">Title:</label>-->
-<!--    <input type="text" id="title" name="title" #newTitle>-->
-<!--  </div>-->
-<!--  <div class="field">-->
-<!--    <label for="link">Link:</label>-->
-<!--    <input type="text" id="link" name="link" #newLink>-->
-<!--  </div>-->
-<!--  <button (click)="addArticle(newTitle, newLink)" class="ui positive right floated button">Submit link</button>-->
-<!--</form>-->
+<div class="page-header">
+  <div class="container">
+    <h1>Router Sample</h1>
+    <div class="navLinks">
+      <a [routerLink]="['/home']">Home</a>
+      <br>
+      <a [routerLink]="['/students']">Students</a>
+    </div>
+  </div>
+</div>
 
-<!--<div class="ui grid posts">-->
-<!--  <app-article *ngFor="let article of sortedArticles()" [article]="article"></app-article>-->
-<!--</div>-->
+<div id="content">
+  <div class="container">
+    <router-outlet></router-outlet>
+  </div>
+</div>
 
-
-<h1>{{title}}</h1>
-<nav>
-  <a routerLink="/dashboard">Dashboard</a>
-  <a routerLink="/heroes">Heroes</a>
-</nav>
-<router-outlet></router-outlet>
-<app-messages></app-messages>
-
-
-<!--<app-fibonacci></app-fibonacci>-->

+ 3 - 3
IWA-angular/src/app/app.component.spec.ts

@@ -16,16 +16,16 @@ describe('AppComponent', () => {
     expect(app).toBeTruthy();
   });
 
-  it(`should have as title 'IWA-angular'`, () => {
+  it(`should have as title 'angular13-iwa2022-http-students'`, () => {
     const fixture = TestBed.createComponent(AppComponent);
     const app = fixture.componentInstance;
-    expect(app.title).toEqual('IWA-angular');
+    expect(app.title).toEqual('angular13-iwa2022-http-students');
   });
 
   it('should render title', () => {
     const fixture = TestBed.createComponent(AppComponent);
     fixture.detectChanges();
     const compiled = fixture.nativeElement as HTMLElement;
-    expect(compiled.querySelector('.content span')?.textContent).toContain('IWA-angular app is running!');
+    expect(compiled.querySelector('.content span')?.textContent).toContain('angular13-iwa2022-http-students app is running!');
   });
 });

+ 1 - 23
IWA-angular/src/app/app.component.ts

@@ -1,5 +1,4 @@
 import { Component } from '@angular/core';
-import {Article} from "./article";
 
 @Component({
   selector: 'app-root',
@@ -7,26 +6,5 @@ import {Article} from "./article";
   styleUrls: ['./app.component.css']
 })
 export class AppComponent {
-  title: string = 'Tour of heroes';
-  articles: Article[];
-
-  constructor() {
-    this.articles = [
-      new Article('Angular', 'https://angular.io', 3),
-      new Article('Fullstack', 'https://fullstack.io', 2),
-      new Article('Angular Homepage', 'https://angular.io', 1),
-    ]
-  }
-
-  addArticle(title: HTMLInputElement, link: HTMLInputElement): boolean {
-    console.log(`Adding article title: ${title.value} and link: ${link.value}`);
-    this.articles.push(new Article(title.value, link.value, 0));
-    title.value = '';
-    link.value = '';
-    return false;
-  }
-
-  sortedArticles() : Article[] {
-    return this.articles.sort((a: Article, b: Article) => b.votes - a.votes);
-  }
+  title = 'angular13-iwa2022-http-students';
 }

+ 14 - 33
IWA-angular/src/app/app.module.ts

@@ -1,48 +1,29 @@
 import { NgModule } from '@angular/core';
 import { BrowserModule } from '@angular/platform-browser';
-import { FormsModule } from "@angular/forms";
-import { HttpClientModule } from '@angular/common/http';
-import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';
-import { InMemoryDataService } from './in-memory-data.service';
-
 import { AppComponent } from './app.component';
-import { StudentComponentComponent } from './student-component/student-component.component';
-import { HelloWorldComponent } from './hello-world/hello-world.component';
-import { UserItemComponent } from './user-item/user-item.component';
-import { UserListComponent } from './user-list/user-list.component';
-import { ArticleComponent } from './article/article.component';
-import { HeroesComponent } from './heroes/heroes.component';
-import { FibonacciComponent } from './fibonacci/fibonacci.component';
-import { HeroDetailComponent } from './hero-detail/hero-detail.component';
-import { MessagesComponent } from './messages/messages.component';
-import { AppRoutingModule } from './app-routing.module';
-import { DashboardComponent } from './dashboard/dashboard.component';
-import { HeroSearchComponent } from './hero-search/hero-search.component';
+import { HomeComponent } from './home/home.component';
+import { StudentsComponent } from './students/students.component';
+import {RouterModule, Routes} from "@angular/router";
+import {HttpClientModule} from "@angular/common/http";
+import {FormsModule} from "@angular/forms";
 
+const routes: Routes = [
+  { path: 'home', component: HomeComponent },
+  { path: 'students', component: StudentsComponent }
+];
 
 @NgModule({
   declarations: [
     AppComponent,
-    StudentComponentComponent,
-    HelloWorldComponent,
-    UserItemComponent,
-    UserListComponent,
-    ArticleComponent,
-    HeroesComponent,
-    FibonacciComponent,
-    HeroDetailComponent,
-    MessagesComponent,
-    DashboardComponent,
-    HeroSearchComponent
+    HomeComponent,
+    StudentsComponent
   ],
   imports: [
     BrowserModule,
-    FormsModule,
-    AppRoutingModule,
+    // import HttpClientModule after BrowserModule.
     HttpClientModule,
-    HttpClientInMemoryWebApiModule.forRoot(
-      InMemoryDataService, { dataEncapsulation: false }
-    )
+    FormsModule,
+    RouterModule.forRoot(routes)
   ],
   providers: [],
   bootstrap: [AppComponent]

+ 0 - 0
IWA-angular/src/app/home/home.component.css


+ 1 - 0
IWA-angular/src/app/home/home.component.html

@@ -0,0 +1 @@
+<p>home component works!</p>

+ 25 - 0
IWA-angular/src/app/home/home.component.spec.ts

@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HomeComponent } from './home.component';
+
+describe('HomeComponent', () => {
+  let component: HomeComponent;
+  let fixture: ComponentFixture<HomeComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ HomeComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(HomeComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 15 - 0
IWA-angular/src/app/home/home.component.ts

@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-home',
+  templateUrl: './home.component.html',
+  styleUrls: ['./home.component.css']
+})
+export class HomeComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit(): void {
+  }
+
+}

+ 7 - 0
IWA-angular/src/app/students/student.model.spec.ts

@@ -0,0 +1,7 @@
+import { Student } from './student.model';
+
+describe('Student', () => {
+  it('should create an instance', () => {
+    expect(new Student()).toBeTruthy();
+  });
+});

+ 15 - 0
IWA-angular/src/app/students/student.model.ts

@@ -0,0 +1,15 @@
+export class Student {
+  id?: number;
+  firstname: string;
+  lastname: string;
+  email: string;
+  telephone: string;
+
+  constructor(firstname: string, lastname: string, email: string, telephone: string) {
+    this.firstname = firstname;
+    this.lastname = lastname;
+    this.email = email;
+    this.telephone = telephone;
+  }
+
+}

+ 16 - 0
IWA-angular/src/app/students/student.service.spec.ts

@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { StudentService } from './student.service';
+
+describe('StudentService', () => {
+  let service: StudentService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(StudentService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});

+ 124 - 0
IWA-angular/src/app/students/student.service.ts

@@ -0,0 +1,124 @@
+import {Injectable} from '@angular/core';
+import {HttpClient, HttpHeaders} from "@angular/common/http";
+import {BehaviorSubject, catchError, Observable, of, tap} from "rxjs";
+import {Student} from "./student.model";
+
+const httpOptions = {
+  headers: new HttpHeaders({'Content-Type': 'application/json'})
+};
+
+@Injectable({
+  providedIn: 'root'
+})
+export class StudentService {
+
+  private studentsUrl = 'http://localhost:8080/students';
+
+  constructor(private http: HttpClient) {
+  }
+
+  // for automatic update of number of students in parent component
+  public totalItems: BehaviorSubject<number> = new BehaviorSubject<number>(0);
+
+  getCartItems() {
+    return this.totalItems.asObservable();
+  }
+
+  /** GET students from the server */
+  getStudents(): Observable<Student[]> {
+    return this.http.get<Student[]>(this.studentsUrl);
+  }
+
+  /** POST: add a new student to the server */
+  addStudent(student: Student): Observable<Student> {
+    return this.http.post<Student>(this.studentsUrl, student, httpOptions).pipe(
+      tap((studentAdded: Student) => this.log(`added student id=${studentAdded.id}`)),
+      catchError(this.handleError<Student>('addStudent'))
+    );
+  }
+
+  /** GET student by id. Will 404 if id not found */
+  getStudent(id: number): Observable<Student> {
+    const url = `${this.studentsUrl}/${id}`;
+    return this.http.get<Student>(url).pipe(
+      tap(_ => this.log(`fetched student id=${id}`)),
+      catchError(this.handleError<Student>(`getStudent id=${id}`))
+    );
+  }
+
+  /** DELETE: delete the student from the server */
+  deleteStudent(student: Student | number): Observable<Student> {
+    const id = typeof student === 'number' ? student : student.id;
+    const url = `${this.studentsUrl}/${id}`;
+    return this.http.delete<Student>(url, httpOptions).pipe(
+      tap(_ => this.log(`deleted student id=${id}`)),
+      catchError(this.handleError<Student>('deleteStudent'))
+    );
+  }
+
+  deleteAllStudents(): Observable<any> {
+    return this.http.delete<any>(this.studentsUrl, httpOptions).pipe(
+      tap(_ => this.log('deleted all students')),
+      catchError(this.handleError<any>('deleteAllStudents'))
+    )
+  }
+
+  /** PUT: update the student on the server */
+  updateStudent(student: Student): Observable<any> {
+    const url = `${this.studentsUrl}/${student.id}`;
+    return this.http.put(url, student, httpOptions).pipe(
+      tap(_ => this.log(`updated student id=${student.id}`)),
+      catchError(this.handleError<any>('updateStudent'))
+    );
+  }
+
+  updateAllStudents(students: Student[]): Observable<any> {
+    return this.http.put(this.studentsUrl, students, httpOptions).pipe(
+      tap(_ => this.log('updated all students')),
+      catchError(this.handleError<any>('updateAllStudents'))
+    )
+  }
+
+  partialUpdateStudent(student: Student): Observable<any> {
+    const url = `${this.studentsUrl}/${student.id}`;
+    return this.http.patch(url, student, httpOptions).pipe(
+      tap(_ => this.log(`partially updated student id=${student.id}`)),
+      catchError(this.handleError<any>('partialUpdateStudent'))
+    )
+  }
+
+  /**
+   * Handle Http operation that failed.
+   * Let the app continue.
+   * @param operation - name of the operation that failed
+   * @param result - optional value to return as the observable result
+   */
+  private handleError<T>(operation = 'operation', result?: T) {
+    return (error: any): Observable<T> => {
+
+      // TODO: send the error to remote logging infrastructure
+      console.error(error); // log to console instead
+
+      // TODO: better job of transforming error for user consumption
+      this.log(`${operation} failed: ${error.message}`);
+
+      // Let the app keep running by returning an empty result.
+      return of(result as T);
+    };
+  }
+
+  /** Log a StudentService message with the MessageService */
+  private log(message: string) {
+    console.log('StudentService: ' + message);
+  }
+
+  /** GET number of students from the server */
+  getStudentsCounter(): Observable<number> {
+    const url = `${this.studentsUrl}/counter`;
+    return this.http.get<number>(url);
+  }
+
+  //updatedCounter(dataAsParams) {
+  //  this.totalItems.next(dataAsParams);
+  //}
+}

+ 0 - 0
IWA-angular/src/app/students/students.component.css


+ 59 - 0
IWA-angular/src/app/students/students.component.html

@@ -0,0 +1,59 @@
+<h2>Students</h2>
+
+<div>
+  <label>Get student by ID:
+    <input #studentID/>
+  </label>
+  <button (click)="printStudent(studentID.value);">
+    Print to console
+  </button>
+</div>
+
+<div>
+  <button (click)="deleteAll()">
+    delete all
+  </button>
+  <button
+    (click)="updateAll([newStudent(studentFirstName.value, studentLastName.value, studentEmail.value, studentTelephone.value)])">
+    update all
+  </button>
+  <br>
+  <label>Student firstname:
+    <input #studentFirstName/>
+  </label>
+  <br>
+  <label>Student lastname:
+    <input #studentLastName/>
+  </label>
+  <br>
+  <label>Student email:
+    <input #studentEmail/>
+  </label>
+  <br>
+  <label>Student telephone:
+    <input #studentTelephone/>
+  </label>
+  <br>
+  <!-- (click) passes input value to add() and then clears the input -->
+  <button (click)="add(studentFirstName.value, studentLastName.value, studentEmail.value, studentTelephone.value);
+                  studentFirstName.value=''; studentLastName.value=''; studentEmail.value=''; studentTelephone.value=''">
+    add
+  </button>
+</div>
+
+<ul>
+  <li *ngFor="let student of studentList">
+    <span
+      class="badge">{{student.id}}</span> {{ student.firstname }} {{ student.lastname }} {{ student.email }} {{ student.telephone }}
+    <button title="delete" (click)="delete(student)">delete</button>
+    <button title="update"
+            (click)="update(student, studentFirstName.value, studentLastName.value, studentEmail.value, studentTelephone.value)">
+      update
+    </button>
+    <button title="patch"
+            (click)="patch(student, studentFirstName.value, studentLastName.value, studentEmail.value, studentTelephone.value)">
+      patch
+    </button>
+  </li>
+</ul>
+

+ 25 - 0
IWA-angular/src/app/students/students.component.spec.ts

@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { StudentsComponent } from './students.component';
+
+describe('StudentsComponent', () => {
+  let component: StudentsComponent;
+  let fixture: ComponentFixture<StudentsComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ StudentsComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(StudentsComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 115 - 0
IWA-angular/src/app/students/students.component.ts

@@ -0,0 +1,115 @@
+import { Component, OnInit } from '@angular/core';
+import {Student} from "./student.model";
+import {StudentService} from "./student.service";
+
+@Component({
+  selector: 'app-students',
+  templateUrl: './students.component.html',
+  styleUrls: ['./students.component.css']
+})
+export class StudentsComponent implements OnInit {
+  studentList?: Student[];
+  student?: Student;
+
+  constructor(private studentService: StudentService) { }
+
+  ngOnInit() { this.getStudents();   }
+
+  newStudent(firstname: string, lastname: string, email: string, telephone: string): Student {
+    return new Student(firstname, lastname, email, telephone);
+  }
+
+  getStudents(): void {
+    this.studentService.getStudents()
+      .subscribe(studentList => this.studentList = studentList);
+  }
+
+  printStudent(ID: string) : void {
+    this.studentService.getStudent(parseInt(ID)).subscribe((student) => {
+      console.log(student);
+    })
+  }
+
+  add(firstname: string, lastname: string, email: string, telephone: string): void {
+    firstname = firstname.trim();
+    lastname = lastname.trim();
+    email = email.trim();
+    telephone = telephone.trim();
+    this.studentService.addStudent({ firstname, lastname, email, telephone } as Student)
+      .subscribe({
+        next: (student: Student) => { this.studentList?.push(student); },
+        error: () => {},
+        complete: () => {
+          if (this.studentList != undefined) {
+            this.studentService.totalItems.next(this.studentList.length);
+            console.log(this.studentList.length);
+          }
+        }
+  });
+  }
+
+  delete(student: Student): void {
+    this.studentList = this.studentList?.filter(c => c !== student);
+    this.studentService.deleteStudent(student).subscribe(() => {
+        // for automatic update of number of students in parent component
+      if(this.studentList != undefined) {
+        this.studentService.totalItems.next(this.studentList.length);
+        console.log(this.studentList.length);
+      }
+      }
+    );
+  }
+
+  deleteAll(): void {
+    this.studentList = [];
+    this.studentService.deleteAllStudents().subscribe(() => {
+        if(this.studentList != undefined) {
+          this.studentService.totalItems.next(this.studentList.length);
+          console.log(this.studentList.length);
+        }
+      }
+    );
+  }
+
+  update(student: Student, firstname: string, lastname: string, email: string, telephone: string): void {
+    student.firstname = firstname;
+    student.lastname = lastname;
+    student.email = email;
+    student.telephone = telephone;
+    this.studentService.updateStudent(student).subscribe(() => {
+      console.log('student updated');
+    });
+  }
+
+  updateAll(students: Student[]): void {
+    this.studentList = students;
+    this.studentService.updateAllStudents(students).subscribe(() => {
+      console.log('updated all students');
+    });
+  }
+
+  patch(student: Student, firstname: string, lastname: string, email: string, telephone: string): void {
+    let changed: string = '';
+    if (firstname !== '') {
+      student.firstname = firstname;
+      changed += 'firstname, ';
+    }
+    if (lastname !== '') {
+      student.lastname = lastname;
+      changed += 'lastname, ';
+    }
+    if (email !== '') {
+      student.email = email;
+      changed += 'email, ';
+    }
+    if (telephone !== '') {
+      student.telephone = telephone;
+      changed += 'telephone, ';
+    }
+    this.studentService.partialUpdateStudent(student).subscribe(() => {
+      console.log(`Changed following data: ${changed}`);
+    });
+  }
+
+}
+

BIN
IWA/lib/javaee.jar


+ 7 - 7
IWA/pom.xml

@@ -11,8 +11,8 @@
     <groupId>pl.dmcs</groupId>
     <artifactId>SpringBootJsp_IWA</artifactId>
     <version>0.0.1-SNAPSHOT</version>
-    <name>IWA</name>
-    <description>IWA</description>
+    <name>SpringBootJsp_IWA</name>
+    <description>SpringBootJsp_IWA</description>
     <properties>
         <java.version>17</java.version>
     </properties>
@@ -30,11 +30,6 @@
             <artifactId>jstl</artifactId>
             <version>1.2</version>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
@@ -54,6 +49,11 @@
             <artifactId>jackson-dataformat-xml</artifactId>
             <version>2.13.1</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>

+ 15 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/SpringBootJspIwaApplication.java

@@ -0,0 +1,15 @@
+package pl.dmcs.springbootjsp_iwa;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringBootJspIwaApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(SpringBootJspIwaApplication.class, args);
+    }
+
+}
+
+

+ 1 - 0
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/HelloController.java

@@ -11,3 +11,4 @@ public class HelloController {
         return "hello";
     }
 }
+

+ 8 - 4
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/StudentController.java

@@ -12,16 +12,20 @@ public class StudentController {
 
     @RequestMapping("/student")
     public String student(Model model) {
-        model.addAttribute("message", "Simple String from Student Controller.");
+        model.addAttribute("message","Simple String from StudentController.");
         Student newStudent = new Student();
-        model.addAttribute("student", newStudent);
+        model.addAttribute("student",newStudent);
         return "student";
     }
 
     @RequestMapping(value = "/addStudent.html", method = RequestMethod.POST)
     public String addStudent(@ModelAttribute("student") Student student) {
-        System.out.println(student.getFirstname() + " " + student.getLastname() + " " + student.getEmail() +
-                " " + student.getTelephone());
+
+        System.out.println(student.getFirstname() + " " + student.getLastname() +
+                " " + student.getEmail() + " " + student.getTelephone());
+
         return "redirect:student";
     }
+
 }
+

+ 18 - 16
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/StudentRESTController.java

@@ -7,21 +7,19 @@ import org.springframework.web.bind.annotation.*;
 import pl.dmcs.springbootjsp_iwa.model.Student;
 import pl.dmcs.springbootjsp_iwa.repository.AddressRepository;
 import pl.dmcs.springbootjsp_iwa.repository.StudentRepository;
-
 import java.util.List;
 import java.util.Map;
 
 @RestController
+@CrossOrigin(origins = "http://localhost:4200")
 @RequestMapping("/students")
 public class StudentRESTController {
 
     private final StudentRepository studentRepository;
-    private final AddressRepository addressRepository;
 
     @Autowired
-    public StudentRESTController(StudentRepository studentRepository, AddressRepository addressRepository) {
+    public StudentRESTController(StudentRepository studentRepository) {
         this.studentRepository = studentRepository;
-        this.addressRepository = addressRepository;
     }
 
     @GetMapping
@@ -34,24 +32,27 @@ public class StudentRESTController {
         Student student = studentRepository.findById(id);
         if (student == null) {
             System.out.println("Student not found!");
-            return new ResponseEntity<Student>(HttpStatus.NOT_FOUND);
+            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
         }
-        return new ResponseEntity<Student>(student, HttpStatus.FOUND);
+        return new ResponseEntity<>(student, HttpStatus.OK);
     }
 
     @PostMapping
     public ResponseEntity<Student> addStudent(@RequestBody Student student) {
-        if (student.getAddress().getId() <= 0) {
+        /*
+        // Commented out due to simplify http requests sent from angular app
+        if (student.getAddress().getId() <= 0 )
+        {
             addressRepository.save(student.getAddress());
-        }
+        }*/
         studentRepository.save(student);
-        return new ResponseEntity<Student>(student, HttpStatus.CREATED);
+        return new ResponseEntity<>(student, HttpStatus.CREATED);
     }
 
     @DeleteMapping
     public ResponseEntity<Student> deleteAllStudents() {
         studentRepository.deleteAll();
-        return new ResponseEntity<Student>(HttpStatus.NO_CONTENT);
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
     @DeleteMapping("/{id}")
@@ -59,24 +60,24 @@ public class StudentRESTController {
         Student student = studentRepository.findById(id);
         if (student == null) {
             System.out.println("Student not found!");
-            return new ResponseEntity<Student>(HttpStatus.NOT_FOUND);
+            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
         }
         studentRepository.deleteById(id);
-        return new ResponseEntity<Student>(HttpStatus.NO_CONTENT);
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
     @PutMapping
     public ResponseEntity<Student> updateAllStudents(@RequestBody List<Student> students) {
         studentRepository.deleteAll();
         studentRepository.saveAll(students);
-        return new ResponseEntity<Student>(HttpStatus.NO_CONTENT);
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
     }
 
     @PutMapping("/{id}")
     public ResponseEntity<Student> updateStudent(@RequestBody Student student, @PathVariable("id") long id) {
         student.setId(id);
         studentRepository.save(student);
-        return new ResponseEntity<Student>(HttpStatus.NO_CONTENT);
+        return new ResponseEntity<>(student,HttpStatus.NO_CONTENT);
     }
 
     @PatchMapping("/{id}")
@@ -84,10 +85,10 @@ public class StudentRESTController {
         Student student = studentRepository.findById(id);
         if (student == null) {
             System.out.println("Student not found!");
-            return new ResponseEntity<Student>(HttpStatus.NOT_FOUND);
+            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
         }
         partialUpdate(student, updates);
-        return new ResponseEntity<Student>(HttpStatus.NO_CONTENT);
+        return new ResponseEntity<>(HttpStatus.OK);
     }
 
     private void partialUpdate(Student student, Map<String, Object> updates) {
@@ -105,4 +106,5 @@ public class StudentRESTController {
         }
         studentRepository.save(student);
     }
+
 }

+ 0 - 84
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/controllers/TeamController.java

@@ -1,84 +0,0 @@
-package pl.dmcs.springbootjsp_iwa.controllers;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-import pl.dmcs.springbootjsp_iwa.model.Student;
-import pl.dmcs.springbootjsp_iwa.model.Team;
-import pl.dmcs.springbootjsp_iwa.repository.StudentRepository;
-import pl.dmcs.springbootjsp_iwa.repository.TeamRepository;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/teams")
-public class TeamController {
-    private final TeamRepository teamRepository;
-    private final StudentRepository studentRepository;
-
-    @Autowired
-    public TeamController(TeamRepository teamRepository, StudentRepository studentRepository) {
-        this.teamRepository = teamRepository;
-        this.studentRepository = studentRepository;
-    }
-
-    @GetMapping
-    public List<Team> findAllTeams() {
-        return teamRepository.findAll();
-    }
-
-    @GetMapping("/{id}")
-    public ResponseEntity<Team> findTeamById(@PathVariable("id") long id) {
-        Team team = teamRepository.findById(id);
-        if (team == null) {
-            System.out.println("Team not found");
-            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
-        }
-        return new ResponseEntity<>(team, HttpStatus.FOUND);
-    }
-
-    @PostMapping
-    public ResponseEntity<Team> addTeam(@RequestBody Team team) {
-        teamRepository.save(team);
-        return new ResponseEntity<>(team, HttpStatus.CREATED);
-    }
-
-    @DeleteMapping
-    public ResponseEntity<Team> deleteAllTeams() {
-        teamRepository.deleteAll();
-        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
-    }
-
-    @DeleteMapping("/{id}")
-    public ResponseEntity<Team> deleteTeam(@PathVariable("id") long id) {
-        Team team = teamRepository.findById(id);
-        if (team == null) {
-            System.out.println("Team not found");
-            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
-        }
-        List<Student> studentsInTeam = studentRepository.getStudentsByTeamListContains(team);
-        for (Student student : studentsInTeam) {
-            List<Team> old = student.getTeamList();
-            old.remove(team);
-            student.setTeamList(old);
-            studentRepository.save(student);
-        }
-        teamRepository.deleteById(id);
-        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
-    }
-
-    @PutMapping
-    public ResponseEntity<Team> updateAllTeams(@RequestBody List<Team> teams) {
-        teamRepository.deleteAll();
-        teamRepository.saveAll(teams);
-        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
-    }
-
-    @PutMapping("/{id}")
-    public ResponseEntity<Team> updateTeam(@RequestBody Team team, @PathVariable("id") long id) {
-        team.setId(id);
-        teamRepository.save(team);
-        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
-    }
-}

+ 7 - 4
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/Account.java

@@ -1,7 +1,6 @@
 package pl.dmcs.springbootjsp_iwa.model;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
-
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
@@ -15,9 +14,10 @@ public class Account {
     private long id;
     private String accountName;
 
-    @JsonIgnore
-    @OneToOne(mappedBy = "account")
-    private Student student;
+    //@JsonIgnore
+    // Commented out due to simplify http requests sent from angular app
+    //@OneToOne(mappedBy = "account")
+    //private Student student;
 
     public long getId() {
         return id;
@@ -35,6 +35,8 @@ public class Account {
         this.accountName = accountName;
     }
 
+/*
+    // Commented out due to simplify http requests sent from angular app
     public Student getStudent() {
         return student;
     }
@@ -42,4 +44,5 @@ public class Account {
     public void setStudent(Student student) {
         this.student = student;
     }
+*/
 }

+ 6 - 3
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/Address.java

@@ -2,7 +2,6 @@ package pl.dmcs.springbootjsp_iwa.model;
 
 import com.fasterxml.jackson.annotation.JsonBackReference;
 import com.fasterxml.jackson.annotation.JsonManagedReference;
-
 import javax.persistence.*;
 import java.util.List;
 
@@ -18,11 +17,13 @@ public class Address {
     private String number;
     private String postalCode;
 
+    /*
+    // Commented out due to simplify http requests sent from angular app
     @JsonManagedReference
     @OneToMany(mappedBy = "address", fetch = FetchType.EAGER)
     //@JoinTable(name="student_address",joinColumns = @JoinColumn(name="student_id"),inverseJoinColumns = @JoinColumn(name="address_id"))
     private List<Student> studentList;
-
+*/
     public long getId() {
         return id;
     }
@@ -63,11 +64,13 @@ public class Address {
         this.postalCode = postalCode;
     }
 
+    /*
+    // Commented out due to simplify http requests sent from angular app
     public List<Student> getStudentList() {
         return studentList;
     }
 
     public void setStudentList(List<Student> studentList) {
         this.studentList = studentList;
-    }
+    }*/
 }

+ 8 - 2
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/Student.java

@@ -15,6 +15,10 @@ public class Student {
     private String email;
     private String telephone;
 
+    private String status;
+
+    /*
+    // Commented out due to simplify http requests sent from angular app
     @OneToOne(cascade = CascadeType.ALL)
     private Account account;
 
@@ -23,7 +27,7 @@ public class Student {
     private Address address;
 
     @ManyToMany(cascade = CascadeType.PERSIST)
-    private List<Team> teamList;
+    private List<Team> teamList;*/
 
     public long getId() {
         return id;
@@ -65,6 +69,8 @@ public class Student {
         this.telephone = telephone;
     }
 
+    /*
+    // Commented out due to simplify http requests sent from angular app
     public Account getAccount() {
         return account;
     }
@@ -87,7 +93,7 @@ public class Student {
 
     public void setTeamList(List<Team> teamList) {
         this.teamList = teamList;
-    }
+    }*/
 }
 
 

+ 3 - 13
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/model/Team.java

@@ -1,7 +1,8 @@
 package pl.dmcs.springbootjsp_iwa.model;
 
-import javax.persistence.*;
-import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
 
 @Entity
 public class Team {
@@ -11,9 +12,6 @@ public class Team {
     private long id;
     private String teamName;
 
-//    @ManyToMany(cascade = CascadeType.PERSIST)
-//    private List<Student> students;
-
     public long getId() {
         return id;
     }
@@ -29,12 +27,4 @@ public class Team {
     public void setTeamName(String teamName) {
         this.teamName = teamName;
     }
-
-//    public List<Student> getStudents() {
-//        return students;
-//    }
-//
-//    public void setStudents(List<Student> students) {
-//        this.students = students;
-//    }
 }

+ 9 - 3
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/repository/StudentRepository.java

@@ -1,14 +1,20 @@
 package pl.dmcs.springbootjsp_iwa.repository;
 
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
 import pl.dmcs.springbootjsp_iwa.model.Student;
-import pl.dmcs.springbootjsp_iwa.model.Team;
 
 import java.util.List;
 
 @Repository
-public interface StudentRepository extends JpaRepository<Student, Long> {
+public interface StudentRepository extends JpaRepository<Student,Long>{
     Student findById(long id);
-    List<Student> getStudentsByTeamListContains(Team team);
+
+    /*
+    // Commented out due to simplify http requests sent from angular app
+    @Query(value = "SELECT s FROM Student s INNER JOIN s.teamList t ON t.id = 151")
+    List<Student> findteamname();,,666666666666666
+*/
 }
+

+ 1 - 1
IWA/src/main/java/pl/dmcs/springbootjsp_iwa/repository/TeamRepository.java

@@ -6,5 +6,5 @@ import pl.dmcs.springbootjsp_iwa.model.Team;
 
 @Repository
 public interface TeamRepository extends JpaRepository<Team, Long> {
-    Team findById(long id);
+
 }

+ 4 - 2
IWA/src/main/webapp/WEB-INF/views/hello.jsp

@@ -4,6 +4,8 @@
     <title>Hello world!</title>
 </head>
 <body>
-Hello World!
+Hello world!
 </body>
-</html>
+</html>
+
+

+ 14 - 12
IWA/src/main/webapp/WEB-INF/views/student.jsp

@@ -1,29 +1,31 @@
-<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
-<!DOCTYPE html>
-<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+         pageEncoding="UTF-8"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
 <html>
 <head>
-    <meta http-equiv="Content-type" content="text/html; charset=UTF-8">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     <title>Add student</title>
 </head>
 <body>
+
 <h1>${message}</h1>
+
 <h2>Student</h2>
-<%--@elvariable id="student" type="java"--%>
 <form:form method="post" action="addStudent.html" modelAttribute="student">
-    <form:label path="firstname">FirstName</form:label>
-    <form:input path="firstname"/>
+    <form:label path="firstname">Firstname</form:label>
+    <form:input path="firstname" />
     <br>
     <form:label path="lastname">Lastname</form:label>
-    <form:input path="lastname"/>
+    <form:input path="lastname" />
     <br>
     <form:label path="email">Email</form:label>
-    <form:input path="email"/>
+    <form:input path="email" />
     <br>
     <form:label path="telephone">Telephone</form:label>
-    <form:input path="telephone"/>
+    <form:input path="telephone" />
     <br>
-    <input type="submit" value="Add student">
+    <input type="submit" value="Add Student"/>
 </form:form>
 </body>
-</html>
+</html>

+ 13 - 0
IWA/src/test/java/pl/dmcs/springbootjsp_iwa/SpringBootJspIwaApplicationTests.java

@@ -0,0 +1,13 @@
+package pl.dmcs.springbootjsp_iwa;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class SpringBootJspIwaApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}