diff --git a/jambotron-ui/src/app/main-module/main.component/main.component.html b/jambotron-ui/src/app/main-module/main.component/main.component.html index 3f83962..b0e338e 100644 --- a/jambotron-ui/src/app/main-module/main.component/main.component.html +++ b/jambotron-ui/src/app/main-module/main.component/main.component.html @@ -39,6 +39,12 @@ User tools } + @if (showModeratorBoard) { + + } + @if (hasError){ + + {{errorMessage}} + + } + @if(submitted) { +

Tutorial was submitted successfully!

+ + + } + + + + + diff --git a/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.scss b/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.scss new file mode 100644 index 0000000..183134c --- /dev/null +++ b/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.scss @@ -0,0 +1,59 @@ +.submit-form { + max-width: 400px; + margin: auto; +} + +mat-card{ + //margin: 20px; +} +mat-card-title{ + color: cyan; +} + +.example-form { + min-width: 150px; + max-width: 500px; + width: 100%; +} + + +.example-full-width { + width: 100%; +} + + +.variable-binding, +.variable-textarea { + width: 49%; +} + +.variable-textarea { + border-radius: 5px; + box-shadow: 0 1px 2px rgba(0,0,0,.07); + min-height: 420px; + padding: 8px; + transition: all 300ms ease-out; +} + +.variable-textarea:hover { + box-shadow: 0 6px 12px 3px rgba(0,0,0,.09), + 0 2px 3px 1px rgba(0,0,0,.06); +} + +.variable-binding { + display: block; + float: right; +} + +.preview { + /* display: block; + float: right;*/ +} + +.mat-mdc-card-outlined { + background-color: var(--mat-card-outlined-container-color, var(--mat-sys-surface)); + border-radius:0; + border-width: var(--mat-card-outlined-outline-width, 1px); + border-color: var(--mat-card-outlined-outline-color, var(--mat-sys-outline-variant)); + box-shadow: var(--mat-card-outlined-container-elevation, var(--mat-sys-level0)); +} diff --git a/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.spec.ts b/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.spec.ts new file mode 100644 index 0000000..0cfa641 --- /dev/null +++ b/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TutorialPreviewComponent } from './tutorial-preview.component'; + +describe('TutorialPreviewComponent', () => { + let component: TutorialPreviewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TutorialPreviewComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TutorialPreviewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.ts b/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.ts new file mode 100644 index 0000000..ae41432 --- /dev/null +++ b/jambotron-ui/src/app/moderator-module/tutorial-preview.component/tutorial-preview.component.ts @@ -0,0 +1,94 @@ +import {Component, CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'; +import {FormsModule} from "@angular/forms"; +import {MarkdownComponent} from "ngx-markdown"; +import {MatButton} from "@angular/material/button"; +import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from "@angular/material/card"; +import {MatError, MatFormField, MatInput, MatLabel} from "@angular/material/input"; +import {MatTab, MatTabGroup} from "@angular/material/tabs"; +import {ActivatedRoute, RouterLink} from "@angular/router"; +import {Tutorial} from '../../models/tutorial.model'; +import {UserApiService} from '../../user-module/user-api.service'; +import {ModeratorApiService} from '../moderator-api.service'; + +@Component({ + selector: 'app-tutorial-preview.component', + imports: [ + FormsModule, + MarkdownComponent, + MatButton, + MatCard, + MatCardActions, + MatCardContent, + MatCardHeader, + MatError, + MatFormField, + MatInput, + MatLabel, + MatTab, + MatTabGroup, + RouterLink, + MatError, + MatFormField + ], + templateUrl: './tutorial-preview.component.html', + styleUrl: './tutorial-preview.component.scss', + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) +export class TutorialPreviewComponent { + tutorial: Tutorial = new Tutorial(); + submitted = false; + hasError = false; + errorMessage = ''; + markdown = `## Markdown __rulez__! +--- + +### Syntax highlight +\`\`\`typescript +const language = 'typescript'; +\`\`\` + +### Lists +1. Ordered list +2. Another bullet point + - Unordered list + - Another unordered bullet + +### Blockquote +> Blockquote to the max`; + + private id: string | null | undefined; + + constructor(private moderatorApiService: ModeratorApiService, private route: ActivatedRoute) { + + this.route.queryParams + .subscribe(params => { + console.log(params); + this.id = params['id']; + console.log(this.id); + }); + + this.moderatorApiService.getTutorial(this.id).subscribe( + data=>{ + this.tutorial = data; + } + ); + } + + publishTutorial(): void { + this.tutorial.published = true; + this.moderatorApiService.publish(this.id, this.tutorial) + .subscribe( + response => { + console.log(response); + this.submitted = true; + this.hasError = false; + }, + error => { + console.log(error); + + this.errorMessage = error.error.message; + + this.hasError = true; + }); + } +} diff --git a/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.html b/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.html new file mode 100644 index 0000000..7d769b4 --- /dev/null +++ b/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.html @@ -0,0 +1,44 @@ + + @for (column of columnsSchema; track column){ + + + + + + } + + + +
+ {{column.label}} + + @switch (column.type) { + + @case('isEdit') { +
+ + +
+ } + @case ('boolean') { + + + + } + @case ('datetime') { + {{ element[column.key] | date: 'medium' }} + } + @default { + {{ element[column.key] }} + } + } + +
+ diff --git a/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.scss b/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.spec.ts b/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.spec.ts new file mode 100644 index 0000000..c8453de --- /dev/null +++ b/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TutorialsListComponent } from './tutorials-list.component'; + +describe('TutorialsListComponent', () => { + let component: TutorialsListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TutorialsListComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TutorialsListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.ts b/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.ts new file mode 100644 index 0000000..61322a1 --- /dev/null +++ b/jambotron-ui/src/app/moderator-module/tutorials-list.component/tutorials-list.component.ts @@ -0,0 +1,144 @@ +import { Component } from '@angular/core'; +import {DatePipe} from "@angular/common"; +import {MatButton} from "@angular/material/button"; +import { + MatCell, + MatCellDef, MatColumnDef, + MatHeaderCell, MatHeaderCellDef, + MatHeaderRow, + MatHeaderRowDef, + MatRow, + MatRowDef, MatTable, MatTableDataSource +} from "@angular/material/table"; +import {MatCheckbox} from "@angular/material/checkbox"; +import {MatSlideToggle} from "@angular/material/slide-toggle"; +import {Router, RouterLink} from "@angular/router"; +import {Tutorial} from '../../models/tutorial.model'; +import {EventData} from '../../_shared/event.class'; +import {ModeratorApiService} from '../moderator-api.service'; +import {TokenStorageService} from '../../services/token-storage.service'; +import {EventBusService} from '../../_shared/event-bus.service'; +import {AuthService} from '../../services/auth.service'; +import {HttpHeaders} from '@angular/common/http'; + +@Component({ + selector: 'app-tutorials-list.component', + imports: [ + DatePipe, + MatButton, + MatCell, + MatCellDef, + MatHeaderCell, + MatHeaderRow, + MatHeaderRowDef, + MatRow, + MatRowDef, + MatSlideToggle, + MatTable, + RouterLink, + MatColumnDef, + MatHeaderCellDef + ], + templateUrl: './tutorials-list.component.html', + styleUrl: './tutorials-list.component.scss' +}) +export class TutorialsListComponent { + displayedColumns: string[] = TutorialColumns.map((col) => col.key) + columnsSchema: any = TutorialColumns + dataSource = new MatTableDataSource() + + + + constructor(private moderatorApiService: ModeratorApiService, + private storageService: TokenStorageService, + private eventBusService: EventBusService, + private authService: AuthService, + private router: Router + ) { + this.getTutorials(); + } + getTutorials(): void { + this.moderatorApiService.getBePublishedTutorials() + .subscribe(( data:Tutorial[] ) => { + this.dataSource.data = data; + console.log(data); + }, + error => { + console.log(error); + if ( + ( + error.status === 401 + + ) + && this.storageService.isLoggedIn() + ) { + this.eventBusService.emit(new EventData('logout', null)); + } + }); + } + + + publish(element: any, checked: boolean){ + element.published = checked; + this.moderatorApiService.publish(element.id, element).subscribe( + response => { + console.log(response); + }, + error => { + console.log(error); + }); + + } + + + logout(): void { + this.authService.logout().subscribe({ + next: res => { + console.log(res); + this.storageService.clean(); + + //window.location.reload(); + this.router.navigate(['main/generate-image']).then(() => { + //window.location.reload(); + }) + + }, + error: err => { + console.log(err); + } + }); + + } +} + +export const TutorialColumns = [ + + { + key: 'title', + type: 'text', + label: 'Title', + required: true, + }, + { + key: 'published', + type: 'boolean', + label: 'Is Published', + }, + { + key: 'created', + type: 'datetime', + label: 'Created Date', + required: true, + }, + { + key: 'modified', + type: 'datetime', + label: 'Modified Date', + required: true + }, + { + key: 'isEdit', + type: 'isEdit', + label: '', + } +]; diff --git a/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.scss b/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.scss index bd7c2c2..183134c 100644 --- a/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.scss +++ b/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.scss @@ -4,7 +4,7 @@ } mat-card{ - margin: 20px; + //margin: 20px; } mat-card-title{ color: cyan; @@ -50,3 +50,10 @@ mat-card-title{ float: right;*/ } +.mat-mdc-card-outlined { + background-color: var(--mat-card-outlined-container-color, var(--mat-sys-surface)); + border-radius:0; + border-width: var(--mat-card-outlined-outline-width, 1px); + border-color: var(--mat-card-outlined-outline-color, var(--mat-sys-outline-variant)); + box-shadow: var(--mat-card-outlined-container-elevation, var(--mat-sys-level0)); +} diff --git a/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.ts b/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.ts index 301c9db..b6119e3 100644 --- a/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.ts +++ b/jambotron-ui/src/app/user-module/tutorial-edit.component/tutorial-edit.component.ts @@ -4,7 +4,6 @@ import {MatButton} from '@angular/material/button'; import {MatCard, MatCardActions, MatCardContent, MatCardHeader} from '@angular/material/card'; import {MatError, MatFormField, MatInput, MatLabel} from '@angular/material/input'; import {MatTab, MatTabGroup} from '@angular/material/tabs'; -import {NgIf} from '@angular/common'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {Tutorial} from '../../models/tutorial.model'; import {UserApiService} from '../user-api.service'; diff --git a/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.html b/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.html index dd683bf..1af8563 100644 --- a/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.html +++ b/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.html @@ -6,9 +6,6 @@ > Remove Rows - @@ -56,7 +53,9 @@ + [disabled]="column.key !== 'toBePublished'" + (change)="publish(element, $event.checked)" + > } diff --git a/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.ts b/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.ts index ba637d4..ec25a19 100644 --- a/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.ts +++ b/jambotron-ui/src/app/user-module/tutorials-list.component/tutorials-list.component.ts @@ -1,6 +1,6 @@ import {Component, CUSTOM_ELEMENTS_SCHEMA, OnInit} from '@angular/core'; import {MatList, MatListItem} from '@angular/material/list'; -import {Tutorial, TutorialColumns} from '../../models/tutorial.model'; +import {Tutorial} from '../../models/tutorial.model'; import {TutorialService} from '../../services/tutorial.service'; import {UserApiService} from '../user-api.service'; import {MatButton} from '@angular/material/button'; @@ -23,22 +23,15 @@ import { MatTable, MatTableDataSource } from '@angular/material/table'; -import {MatFormField, MatInput} from '@angular/material/input'; -import {DatePipe, NgForOf, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault} from '@angular/common'; +import {DatePipe} from '@angular/common'; import {MatCheckbox} from '@angular/material/checkbox'; -import {MatDatepicker, MatDatepickerInput, MatDatepickerToggle} from '@angular/material/datepicker'; import {MatSlideToggle} from '@angular/material/slide-toggle'; @Component({ selector: 'app-tutorials-list.component', imports: [ - MatList, - MatListItem, - MatLine, MatButton, - MatIcon, - MatOption, RouterLink, ReactiveFormsModule, MatTable, @@ -47,22 +40,12 @@ import {MatSlideToggle} from '@angular/material/slide-toggle'; MatRowDef, MatRow, FormsModule, - MatInput, - MatFormField, MatColumnDef, MatHeaderCell, MatHeaderCellDef, - NgSwitch, - NgSwitchCase, - NgSwitchDefault, MatCellDef, MatCheckbox, - MatDatepickerInput, - MatDatepickerToggle, - MatDatepicker, DatePipe, - NgIf, - NgForOf, MatCell, MatSlideToggle ], @@ -76,7 +59,7 @@ import {MatSlideToggle} from '@angular/material/slide-toggle'; displayedColumns: string[] = TutorialColumns.map((col) => col.key) columnsSchema: any = TutorialColumns dataSource = new MatTableDataSource() - valid: any = {} + constructor(private userApiService: UserApiService, private storageService: TokenStorageService, @@ -154,22 +137,16 @@ import {MatSlideToggle} from '@angular/material/slide-toggle'; }) } - editRow(row: Tutorial) { - /*if (row.id === 0) { - this.userService.addUser(row).subscribe((newUser: User) => { - row.id = newUser.id - row.isEdit = false - }) - } else { - this.userService.updateUser(row).subscribe(() => (row.isEdit = false)) - }*/ - } + publish(element: any, checked: boolean){ + element.tobepublished = checked; + this.userApiService.update(element.id, element).subscribe( + response => { + console.log(response); + }, + error => { + console.log(error); + }); - disableSubmit(id: number) { - if (this.valid[id]) { - return Object.values(this.valid[id]).some((item) => item === false) - } - return false } logout(): void { @@ -191,3 +168,47 @@ import {MatSlideToggle} from '@angular/material/slide-toggle'; } } + +export const TutorialColumns = [ + { + key: 'isSelected', + type: 'isSelected', + label: '', + }, + { + key: 'title', + type: 'text', + label: 'Title', + required: true, + }, + { + key: 'published', + type: 'boolean', + label: 'Is Published', + }, + { + key: 'created', + type: 'datetime', + label: 'Created Date', + required: true, + + }, + { + key: 'modified', + type: 'datetime', + label: 'Modified Date', + required: true + }, + { + key: 'toBePublished', + type: 'boolean', + label: 'To be published', + required: true + + }, + { + key: 'isEdit', + type: 'isEdit', + label: '', + } +]; diff --git a/jambotron-ui/src/app/user-module/user-api.service.ts b/jambotron-ui/src/app/user-module/user-api.service.ts index a26176c..2943b6c 100644 --- a/jambotron-ui/src/app/user-module/user-api.service.ts +++ b/jambotron-ui/src/app/user-module/user-api.service.ts @@ -9,16 +9,13 @@ import {HttpClient, HttpHeaders} from '@angular/common/http'; export class UserApiService { baseUrl = 'http://localhost:8080/api/user'; - httpOptions = { - headers: new HttpHeaders({ 'Content-Type': 'application/json' } ) - }; constructor(private http: HttpClient) { } getUserAllTutorials(): Observable { - return this.http.get(`${this.baseUrl}/tutorials`, this.httpOptions); + return this.http.get(`${this.baseUrl}/tutorials`); } getTutorial(id: string | null | undefined): Observable { diff --git a/src/main/java/com/jambotronGroup/jambotron/controllers/TutorialController.java b/src/main/java/com/jambotronGroup/jambotron/controllers/TutorialController.java index b897497..a3ae965 100644 --- a/src/main/java/com/jambotronGroup/jambotron/controllers/TutorialController.java +++ b/src/main/java/com/jambotronGroup/jambotron/controllers/TutorialController.java @@ -66,30 +66,6 @@ public class TutorialController { try { List tutorials = new ArrayList(); -/* Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - UserDetails userDetails = (UserDetails) authentication.getPrincipal(); - String name = authenticationFacade.getAuthentication().getName(); - - User user = userRepository.findById(((UserDetailsImpl)userDetails).getId()).get(); - if (user.getRoles().stream().anyMatch(role -> role.getName().name().equals("ROLE_ADMIN"))) {*/ -/* - if (title == null) - tutorialRepository.findAll().forEach(tutorials::add); - else - tutorialRepository.findByTitleContaining(title).forEach(tutorials::add); -*/ - -/* } else { - - // If the user is not an admin, filter tutorials by user - tutorialRepository.findByUserId(user.getId()).forEach(tutorials::add); - if (tutorials.isEmpty()) { - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - return new ResponseEntity<>(tutorials, HttpStatus.OK); - }*/ - - //all published tutorials without authentication tutorialRepository.findByPublished(true).forEach(tutorials::add); if (tutorials.isEmpty()) { @@ -102,6 +78,23 @@ public class TutorialController { } } + @GetMapping("/moderator/tutorials") + public ResponseEntity> getBePublishedTutorials(@RequestParam(required = false) String title) { + try { + List tutorials = new ArrayList(); + + tutorialRepository.findBytobepublished(true).forEach(tutorials::add); + + if (tutorials.isEmpty()) { + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + return new ResponseEntity<>(tutorials, HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); + } + } + @PostMapping("user/tutorial-add") public ResponseEntity createTutorial(@RequestBody Tutorial tutorial) { @@ -111,8 +104,18 @@ public class TutorialController { User user = userRepository.findById(((UserDetailsImpl)userDetails).getId()).get(); try { + Tutorial newTutorial =new Tutorial( + tutorial.getTitle(), + tutorial.getDescription(), + false, + false, + user, + Timestamp.valueOf(LocalDateTime.now()), + Timestamp.valueOf(LocalDateTime.now()) + ); + Tutorial _tutorial = tutorialRepository - .save(new Tutorial(tutorial.getTitle(), tutorial.getDescription(), false, user, Timestamp.valueOf(LocalDateTime.now()), Timestamp.valueOf(LocalDateTime.now()))); + .save(newTutorial); return new ResponseEntity<>(_tutorial, HttpStatus.CREATED); } catch (Exception e) { return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); @@ -131,6 +134,18 @@ public class TutorialController { } } + @GetMapping("moderator/tutorial-get/{id}") + public ResponseEntity getBePublishedTutorial(@PathVariable("id") long id) { + Optional tutorialData = tutorialRepository.findById(id); + + if (tutorialData.isPresent()) { + + return new ResponseEntity(tutorialData.get(), HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + @PutMapping("user/tutorial-update/{id}") public ResponseEntity updateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) { Optional tutorialData = tutorialRepository.findById(id); @@ -140,6 +155,31 @@ public class TutorialController { servTutorial.setTitle(tutorial.getTitle()); servTutorial.setDescription(tutorial.getDescription()); servTutorial.setPublished(tutorial.isPublished()); + servTutorial.setTobepublished(tutorial.isTobepublished()); + try { + servTutorial = tutorialRepository.save(servTutorial); + } catch (Exception e) { + + map.put("status", 0); + map.put("message", e.getMessage()); + return new ResponseEntity<>(map,HttpStatus.INTERNAL_SERVER_ERROR); + } + return new ResponseEntity<>(servTutorial, HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + } + + @PutMapping("moderator/tutorial-update/{id}") + public ResponseEntity moderatorUpdateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) { + Optional tutorialData = tutorialRepository.findById(id); + Map map = new LinkedHashMap(); + if (tutorialData.isPresent()) { + Tutorial servTutorial = tutorialData.get(); + servTutorial.setTitle(tutorial.getTitle()); + servTutorial.setDescription(tutorial.getDescription()); + servTutorial.setPublished(tutorial.isPublished()); + servTutorial.setTobepublished(tutorial.isTobepublished()); try { servTutorial = tutorialRepository.save(servTutorial); } catch (Exception e) { diff --git a/src/main/java/com/jambotronGroup/jambotron/model/Tutorial.java b/src/main/java/com/jambotronGroup/jambotron/model/Tutorial.java index 3f41dde..f8fca87 100644 --- a/src/main/java/com/jambotronGroup/jambotron/model/Tutorial.java +++ b/src/main/java/com/jambotronGroup/jambotron/model/Tutorial.java @@ -2,6 +2,7 @@ package com.jambotronGroup.jambotron.model; import jakarta.persistence.*; +import java.sql.Timestamp; @Entity @@ -21,6 +22,9 @@ public class Tutorial { @Column(name = "published") private boolean published; + @Column(name = "tobepublished") + private boolean tobepublished; + @ManyToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "userID", nullable = false) private User user; @@ -37,10 +41,11 @@ public class Tutorial { } - public Tutorial(String title, String description, boolean published, User user, java.sql.Timestamp created, java.sql.Timestamp modified) { + public Tutorial(String title, String description, boolean published, boolean tobepublished, User user, Timestamp created, Timestamp modified) { this.title = title; this.description = description; this.published = published; + this.tobepublished = tobepublished; this.user = user; this.created = created; this.modified = modified; @@ -74,6 +79,14 @@ public class Tutorial { this.published = isPublished; } + public boolean isTobepublished() { + return tobepublished; + } + + public void setTobepublished(boolean tobepublished) { + this.tobepublished = tobepublished; + } + public void setCreated(java.sql.Timestamp created) { this.created = created; } diff --git a/src/main/java/com/jambotronGroup/jambotron/model/User.java b/src/main/java/com/jambotronGroup/jambotron/model/User.java index cc0843a..ea22f3c 100644 --- a/src/main/java/com/jambotronGroup/jambotron/model/User.java +++ b/src/main/java/com/jambotronGroup/jambotron/model/User.java @@ -19,6 +19,7 @@ import java.util.Set; public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") private long id; @Column(name = "username") diff --git a/src/main/java/com/jambotronGroup/jambotron/repository/TutorialRepository.java b/src/main/java/com/jambotronGroup/jambotron/repository/TutorialRepository.java index 209b1b2..0709372 100644 --- a/src/main/java/com/jambotronGroup/jambotron/repository/TutorialRepository.java +++ b/src/main/java/com/jambotronGroup/jambotron/repository/TutorialRepository.java @@ -14,5 +14,7 @@ public interface TutorialRepository extends JpaRepository { List findByUserId(Long userId); List findByUserIdAndTitle(Long userId, String title); List findByPublished(boolean published); + List findBytobepublished(boolean tobepublished); + List findByIdAndTobepublished(Long id,boolean tobepublished); List findByTitleContaining(String title); } \ No newline at end of file diff --git a/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java b/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java index e8c0ade..9fc7e81 100644 --- a/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java +++ b/src/main/java/com/jambotronGroup/jambotron/security/WebSecurityConfig.java @@ -140,7 +140,7 @@ public class WebSecurityConfig implements WebMvcConfigurer {// extends WebSecuri .requestMatchers("/api/public/tutorials/**").permitAll() .requestMatchers("/api/user/**").permitAll() - + .requestMatchers("/api/moderator/**").permitAll() .anyRequest().authenticated() ); @@ -160,6 +160,8 @@ public class WebSecurityConfig implements WebMvcConfigurer {// extends WebSecuri config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); + + return new CorsFilter(source); } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c8429f1..0c32a32 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -50,6 +50,8 @@ app.origin=http://localhost:4200 spring.mvc.throw-exception-if-no-handler-found=true +#spring.mvc.dispatch-options-request=true + # Disable the default mappings #spring.resources.add-mappings=false diff --git a/src/main/resources/db/migration/V1__Init.sql b/src/main/resources/db/migration/V1__Init.sql index 4480b4e..9132d24 100644 --- a/src/main/resources/db/migration/V1__Init.sql +++ b/src/main/resources/db/migration/V1__Init.sql @@ -1,7 +1,9 @@ + + CREATE TABLE IF NOT EXISTS roles ( id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - name character varying(20) COLLATE pg_catalog."default" + name character varying(20) ); diff --git a/src/main/resources/db/migration/V8__tutorial_remake.sql b/src/main/resources/db/migration/V8__tutorial_remake.sql index 3c476c6..7d58047 100644 --- a/src/main/resources/db/migration/V8__tutorial_remake.sql +++ b/src/main/resources/db/migration/V8__tutorial_remake.sql @@ -4,6 +4,7 @@ CREATE TABLE tutorials ( id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ), published boolean, + tobepublished boolean, title character varying(255) COLLATE pg_catalog."default", userid bigint, created timestamp with time zone,