| @@ -42,6 +42,7 @@ import {MatOptionModule} from "@angular/material/core"; | |||||
| import {MatAutocompleteModule} from "@angular/material/autocomplete"; | import {MatAutocompleteModule} from "@angular/material/autocomplete"; | ||||
| import {MatFormFieldModule} from "@angular/material/form-field"; | import {MatFormFieldModule} from "@angular/material/form-field"; | ||||
| import {MatInputModule} from "@angular/material/input"; | import {MatInputModule} from "@angular/material/input"; | ||||
| import { NewTaskNoteComponent } from './tasks/new-task-note/new-task-note.component'; | |||||
| export function apiConfigFactory(): Configuration { | export function apiConfigFactory(): Configuration { | ||||
| const params: ConfigurationParameters = { | const params: ConfigurationParameters = { | ||||
| @@ -104,7 +105,8 @@ export function HttpLoaderFactory(http: HttpClient) { | |||||
| NewPartnerComponent, | NewPartnerComponent, | ||||
| NewDocumentComponent, | NewDocumentComponent, | ||||
| NewProductComponent, | NewProductComponent, | ||||
| NewCommentComponent | |||||
| NewCommentComponent, | |||||
| NewTaskNoteComponent | |||||
| ], | ], | ||||
| providers: [ | providers: [ | ||||
| {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}, | {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}, | ||||
| @@ -104,8 +104,8 @@ | |||||
| <h2>{{'basic.tasks' | translate}}</h2> | <h2>{{'basic.tasks' | translate}}</h2> | ||||
| <button class="btn btn-primary" (click)="openModalNewTask()">{{'basic.new-task' | translate}}</button> | <button class="btn btn-primary" (click)="openModalNewTask()">{{'basic.new-task' | translate}}</button> | ||||
| </div> | </div> | ||||
| <div class="tasks" *ngFor="let task of tasks"> | |||||
| <div class="card mb-3 p-3"> | |||||
| <div class="tasks mb-3" *ngFor="let task of tasks"> | |||||
| <div class="card p-3"> | |||||
| <div class="position-relative" data-bs-toggle="collapse" [attr.data-bs-target]="'#collapse-' + ApiConverter.extractId(task.id)" | <div class="position-relative" data-bs-toggle="collapse" [attr.data-bs-target]="'#collapse-' + ApiConverter.extractId(task.id)" | ||||
| aria-expanded="false" | aria-expanded="false" | ||||
| aria-controls="collapseExample"> | aria-controls="collapseExample"> | ||||
| @@ -125,6 +125,23 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="card ms-5" *ngFor="let taskNote of task.taskNotes"> | |||||
| <div class="card-body"> | |||||
| <div class="d-flex justify-content-between align-items-center"> | |||||
| <p>{{ taskNote.createdAt | date:'dd.MM.YYYY HH:mm' }}</p> | |||||
| <p>{{ taskNote.ownerName }}</p> | |||||
| </div> | |||||
| <div> | |||||
| <p>{{ taskNote.message }}</p> | |||||
| </div> | |||||
| <span *ngIf="taskNote.owner === user?.id" class="position-absolute bi bi-pencil p-2" | |||||
| data-type="user-tool" data-action="edit" (click)="openModalEditTaskNote(taskNote)"></span> | |||||
| </div> | |||||
| </div> | |||||
| <div class="d-flex justify-content-end mt-1"> | |||||
| <span role="button" class="badge bg-secondary p-2" (click)="openModalNewTaskNote(task)">{{'basic.comment-it' | translate}}</span> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <mat-paginator *ngIf="tasks.length > 0" class="rounded-1" | <mat-paginator *ngIf="tasks.length > 0" class="rounded-1" | ||||
| [pageSizeOptions]="[10,20,30]" | [pageSizeOptions]="[10,20,30]" | ||||
| @@ -10,7 +10,7 @@ import { | |||||
| PartnerJsonld, | PartnerJsonld, | ||||
| PartnerService, | PartnerService, | ||||
| PostJsonld, | PostJsonld, | ||||
| PostService, TaskJsonld, TaskService | |||||
| PostService, TaskJsonld, TaskNoteJsonld, TaskService | |||||
| } from "@app/core/api/v1"; | } from "@app/core/api/v1"; | ||||
| import {Subscription} from "rxjs"; | import {Subscription} from "rxjs"; | ||||
| import {environment} from "@environments/environment"; | import {environment} from "@environments/environment"; | ||||
| @@ -24,6 +24,7 @@ import {AccountService} from "@app/_services"; | |||||
| import {User} from "@app/_models"; | import {User} from "@app/_models"; | ||||
| import {NewCommentComponent} from "@app/postings/new-comment/new-comment.component"; | import {NewCommentComponent} from "@app/postings/new-comment/new-comment.component"; | ||||
| import {NewPartnerComponent} from "@app/partners/new-partner/new-partner.component"; | import {NewPartnerComponent} from "@app/partners/new-partner/new-partner.component"; | ||||
| import {NewTaskNoteComponent} from "@app/tasks/new-task-note/new-task-note.component"; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-partners-detail', | selector: 'app-partners-detail', | ||||
| @@ -244,6 +245,19 @@ export class PartnersDetailComponent implements OnInit, AfterViewInit { | |||||
| }); | }); | ||||
| } | } | ||||
| openModalNewTaskNote(task: TaskJsonld) { | |||||
| const modalRefTaskNote = this.modalService.open(NewTaskNoteComponent, this.modalOptions); | |||||
| let taskNote: TaskNoteJsonld = {} as TaskNoteJsonld; | |||||
| taskNote.task = task.id ?? null; | |||||
| modalRefTaskNote.componentInstance.taskNote = taskNote; | |||||
| modalRefTaskNote.componentInstance.submit.subscribe((modalStatus: ModalStatus) => { | |||||
| if (modalStatus === ModalStatus.Submitted) { | |||||
| modalRefTaskNote.dismiss(); | |||||
| this.getTasksData(); | |||||
| } | |||||
| }); | |||||
| } | |||||
| openModalNewPosting() { | openModalNewPosting() { | ||||
| const modalRefPosting = this.modalService.open(NewPostingComponent, this.modalOptions); | const modalRefPosting = this.modalService.open(NewPostingComponent, this.modalOptions); | ||||
| let posting: PostJsonld = {} as PostJsonld; | let posting: PostJsonld = {} as PostJsonld; | ||||
| @@ -282,6 +296,17 @@ export class PartnersDetailComponent implements OnInit, AfterViewInit { | |||||
| }); | }); | ||||
| } | } | ||||
| openModalEditTaskNote(taskNote: TaskNoteJsonld) { | |||||
| const modalRefTaskNote = this.modalService.open(NewTaskNoteComponent, this.modalOptions); | |||||
| modalRefTaskNote.componentInstance.taskNote = taskNote; | |||||
| modalRefTaskNote.componentInstance.submit.subscribe((modalStatus: ModalStatus) => { | |||||
| if (modalStatus === ModalStatus.Submitted) { | |||||
| modalRefTaskNote.dismiss(); | |||||
| this.getTasksData(); | |||||
| } | |||||
| }); | |||||
| } | |||||
| openModalEditPosting(post: PostJsonld) { | openModalEditPosting(post: PostJsonld) { | ||||
| const modalRefPostingEdit = this.modalService.open(NewPostingComponent, this.modalOptions); | const modalRefPostingEdit = this.modalService.open(NewPostingComponent, this.modalOptions); | ||||
| modalRefPostingEdit.componentInstance.posting = post; | modalRefPostingEdit.componentInstance.posting = post; | ||||
| @@ -33,9 +33,9 @@ export class NewCommentComponent implements OnInit { | |||||
| onSubmit() { | onSubmit() { | ||||
| if (this.commentForm.valid) { | if (this.commentForm.valid) { | ||||
| if (this.comment.id === null || this.comment.id === undefined) { | if (this.comment.id === null || this.comment.id === undefined) { | ||||
| // Create new post | |||||
| // Create new comment | |||||
| this.commentSub = this.commentService.commentsPost( | this.commentSub = this.commentService.commentsPost( | ||||
| this.commentForm.value as PostJsonld | |||||
| this.commentForm.value as CommentJsonld | |||||
| ).subscribe( | ).subscribe( | ||||
| data => { | data => { | ||||
| this.commentForm.reset(); | this.commentForm.reset(); | ||||
| @@ -43,10 +43,10 @@ export class NewCommentComponent implements OnInit { | |||||
| } | } | ||||
| ); | ); | ||||
| } else { | } else { | ||||
| // Edit post | |||||
| // Edit comment | |||||
| this.commentSub = this.commentService.commentsIdPatch( | this.commentSub = this.commentService.commentsIdPatch( | ||||
| ApiConverter.extractId(this.comment.id), | ApiConverter.extractId(this.comment.id), | ||||
| this.commentForm.value as PostJsonld | |||||
| this.commentForm.value as CommentJsonld | |||||
| ).subscribe( | ).subscribe( | ||||
| data => { | data => { | ||||
| this.commentForm.reset(); | this.commentForm.reset(); | ||||
| @@ -57,7 +57,7 @@ export class NewProductComponent implements OnInit { | |||||
| submitForm() { | submitForm() { | ||||
| if (this.productForm.valid) { | if (this.productForm.valid) { | ||||
| if (this.product.id === null || this.product.id === undefined) { | if (this.product.id === null || this.product.id === undefined) { | ||||
| // Create new post | |||||
| // Create new product | |||||
| this.productSub = this.productService.productsPost( | this.productSub = this.productService.productsPost( | ||||
| this.productForm.value as ProductJsonld | this.productForm.value as ProductJsonld | ||||
| ).subscribe( | ).subscribe( | ||||
| @@ -67,7 +67,7 @@ export class NewProductComponent implements OnInit { | |||||
| } | } | ||||
| ); | ); | ||||
| } else { | } else { | ||||
| // Edit post | |||||
| // Edit product | |||||
| this.productSub = this.productService.productsIdPatch( | this.productSub = this.productService.productsIdPatch( | ||||
| ApiConverter.extractId(this.product.id), | ApiConverter.extractId(this.product.id), | ||||
| this.productForm.value as ProductJsonld | this.productForm.value as ProductJsonld | ||||
| @@ -0,0 +1,16 @@ | |||||
| <h2 *ngIf="!taskNote.id">{{'basic.new-comment' | translate}}</h2> | |||||
| <h2 *ngIf="taskNote.id">{{'basic.edit-comment' | translate}}</h2> | |||||
| <div class="spt-form"> | |||||
| <form [formGroup]="taskNoteForm" (ngSubmit)="onSubmit()"> | |||||
| <div class="mb-3"> | |||||
| <label for="message" class="form-label">{{'form.comment' | translate}}:</label> | |||||
| <input type="text" class="form-control" id="message" formControlName="message" /> | |||||
| <div class="form-text" *ngIf="taskNoteForm.get('message')?.invalid && taskNoteForm.get('message')?.touched"> | |||||
| {{'form.comment' | translate}} {{'form.mandatory' | translate}}. | |||||
| </div> | |||||
| </div> | |||||
| <button type="submit" class="btn btn-primary" [disabled]="taskNoteForm.invalid">{{'form.send' | translate}}</button> | |||||
| </form> | |||||
| </div> | |||||
| @@ -0,0 +1,23 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { NewTaskNoteComponent } from './new-task-note.component'; | |||||
| describe('NewTaskNoteComponent', () => { | |||||
| let component: NewTaskNoteComponent; | |||||
| let fixture: ComponentFixture<NewTaskNoteComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [NewTaskNoteComponent] | |||||
| }) | |||||
| .compileComponents(); | |||||
| fixture = TestBed.createComponent(NewTaskNoteComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,59 @@ | |||||
| import {Component, EventEmitter, Input, Output} from '@angular/core'; | |||||
| import {TaskJsonld, TaskNoteJsonld, TaskNoteService} from "@app/core/api/v1"; | |||||
| import {ModalStatus} from "@app/_helpers/modal.states"; | |||||
| import {FormGroup} from "@angular/forms"; | |||||
| import {Subscription} from "rxjs"; | |||||
| import {FormGroupInitializer} from "@app/_helpers/formgroup.initializer"; | |||||
| import {ApiConverter} from "@app/_helpers/api.converter"; | |||||
| import {taskNoteForm} from "@app/_forms/apiForms"; | |||||
| @Component({ | |||||
| selector: 'app-new-task-note', | |||||
| templateUrl: './new-task-note.component.html', | |||||
| styleUrl: './new-task-note.component.scss' | |||||
| }) | |||||
| export class NewTaskNoteComponent { | |||||
| @Input() public taskNote!: TaskNoteJsonld; | |||||
| @Output() public submit: EventEmitter<ModalStatus> = new EventEmitter<ModalStatus>(); | |||||
| protected taskNoteForm: FormGroup; | |||||
| protected taskNoteSub: Subscription; | |||||
| constructor( | |||||
| private taskNoteService: TaskNoteService | |||||
| ) { | |||||
| this.taskNoteForm = taskNoteForm; | |||||
| this.taskNoteSub = new Subscription(); | |||||
| } | |||||
| ngOnInit(): void { | |||||
| this.taskNoteForm = FormGroupInitializer.initFormGroup(this.taskNoteForm, this.taskNote); | |||||
| } | |||||
| onSubmit() { | |||||
| if (this.taskNoteForm.valid) { | |||||
| if (this.taskNote.id === null || this.taskNote.id === undefined) { | |||||
| // Create new taskNote | |||||
| this.taskNoteSub = this.taskNoteService.taskNotesPost( | |||||
| this.taskNoteForm.value as TaskNoteJsonld | |||||
| ).subscribe( | |||||
| data => { | |||||
| this.taskNoteForm.reset(); | |||||
| this.submit.emit(ModalStatus.Submitted); | |||||
| } | |||||
| ); | |||||
| } else { | |||||
| // Edit taskNote | |||||
| this.taskNoteSub = this.taskNoteService.taskNotesIdPatch( | |||||
| ApiConverter.extractId(this.taskNote.id), | |||||
| this.taskNoteForm.value as TaskNoteJsonld | |||||
| ).subscribe( | |||||
| data => { | |||||
| this.taskNoteForm.reset(); | |||||
| this.submit.emit(ModalStatus.Submitted); | |||||
| } | |||||
| ); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -76,7 +76,7 @@ export class NewTaskComponent implements OnInit { | |||||
| onSubmit() { | onSubmit() { | ||||
| if (this.taskForm.valid) { | if (this.taskForm.valid) { | ||||
| if (this.task.id === null || this.task.id === undefined) { | if (this.task.id === null || this.task.id === undefined) { | ||||
| // Create new post | |||||
| // Create new task | |||||
| this.taskSub = this.taskService.tasksPost( | this.taskSub = this.taskService.tasksPost( | ||||
| this.taskForm.value as TaskJsonld | this.taskForm.value as TaskJsonld | ||||
| ).subscribe( | ).subscribe( | ||||
| @@ -86,7 +86,7 @@ export class NewTaskComponent implements OnInit { | |||||
| } | } | ||||
| ); | ); | ||||
| } else { | } else { | ||||
| // Edit post | |||||
| // Edit task | |||||
| this.taskSub = this.taskService.tasksIdPatch( | this.taskSub = this.taskService.tasksIdPatch( | ||||
| ApiConverter.extractId(this.task.id), | ApiConverter.extractId(this.task.id), | ||||
| this.taskForm.value as TaskJsonld | this.taskForm.value as TaskJsonld | ||||