| @@ -38,6 +38,10 @@ import { NewPartnerComponent } from './partners/new-partner/new-partner.componen | |||
| import { NewDocumentComponent } from './documents/new-document/new-document.component'; | |||
| import { NewProductComponent } from './products/new-product/new-product.component'; | |||
| import { NewCommentComponent } from './postings/new-comment/new-comment.component'; | |||
| import {MatOptionModule} from "@angular/material/core"; | |||
| import {MatAutocompleteModule} from "@angular/material/autocomplete"; | |||
| import {MatFormFieldModule} from "@angular/material/form-field"; | |||
| import {MatInputModule} from "@angular/material/input"; | |||
| export function apiConfigFactory(): Configuration { | |||
| const params: ConfigurationParameters = { | |||
| @@ -76,7 +80,11 @@ export function HttpLoaderFactory(http: HttpClient) { | |||
| DocumentsComponent, | |||
| MatPaginatorModule, | |||
| MatSortModule, | |||
| MatTableModule | |||
| MatTableModule, | |||
| MatOptionModule, | |||
| MatAutocompleteModule, | |||
| MatFormFieldModule, | |||
| MatInputModule | |||
| ], | |||
| declarations: [ | |||
| AppComponent, | |||
| @@ -6,7 +6,6 @@ import {ActivatedRoute} from "@angular/router"; | |||
| import {MatPaginator, MatPaginatorIntl, PageEvent} from "@angular/material/paginator"; | |||
| import {MatTableDataSource} from "@angular/material/table"; | |||
| import {NewPostingComponent} from "@app/postings/new-posting/new-posting.component"; | |||
| import {ModalComponent} from "@app/_components/modal/modal.component"; | |||
| import {NgbModal, NgbModalOptions} from "@ng-bootstrap/ng-bootstrap"; | |||
| import {NewContactComponent} from "@app/contacts/new-contact/new-contact.component"; | |||
| import {ModalStatus} from "@app/_helpers/modal.states"; | |||
| @@ -120,7 +120,8 @@ | |||
| <div class="pt-3 pe-5 position-relative"> | |||
| <p class="m-0">{{task.description}}</p> | |||
| <p>Zugewiesen an: {{task.assignedTo}}</p> | |||
| <span class="position-absolute bi bi-pencil p-2" data-type="user-tool" data-action="edit"></span> | |||
| <span *ngIf="task.createdBy === user?.id" class="position-absolute bi bi-pencil p-2" | |||
| data-type="user-tool" data-action="edit" (click)="openModalEditTask(task)"></span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -177,9 +177,8 @@ export class PartnersDetailComponent implements OnInit, AfterViewInit { | |||
| this.tasksSub = this.taskService.tasksGetCollection( | |||
| this.tasksPageIndex + 1, | |||
| this.tasksPageSize, | |||
| // TODO: Partner ID muss übergeben werden können, damit man nur die Partner-Tasks bekommt | |||
| // TODO: User-ID muss übergeben werden können, damit man nur die Tasks bekommt, die einem User zugewiesen sind | |||
| // this.id | |||
| this.id | |||
| ).subscribe( | |||
| data => { | |||
| this.tasks = data["hydra:member"]; | |||
| @@ -234,7 +233,8 @@ export class PartnersDetailComponent implements OnInit, AfterViewInit { | |||
| const modalRefTask = this.modalService.open(NewTaskComponent, this.modalOptions); | |||
| let task: TaskJsonld = {} as TaskJsonld; | |||
| task.partner = this.partner.id ?? null; | |||
| modalRefTask.componentInstance.posting = task; | |||
| task.completed = false; | |||
| modalRefTask.componentInstance.task = task; | |||
| modalRefTask.componentInstance.submit.subscribe((modalStatus: ModalStatus) => { | |||
| if (modalStatus === ModalStatus.Submitted) { | |||
| modalRefTask.dismiss(); | |||
| @@ -269,6 +269,17 @@ export class PartnersDetailComponent implements OnInit, AfterViewInit { | |||
| }); | |||
| } | |||
| openModalEditTask(task: TaskJsonld) { | |||
| const modalRefTaskEdit = this.modalService.open(NewTaskComponent, this.modalOptions); | |||
| modalRefTaskEdit.componentInstance.task = task; | |||
| modalRefTaskEdit.componentInstance.submit.subscribe((modalStatus: ModalStatus) => { | |||
| if (modalStatus === ModalStatus.Submitted) { | |||
| modalRefTaskEdit.dismiss(); | |||
| this.getPostsData(); | |||
| } | |||
| }); | |||
| } | |||
| openModalEditPosting(post: PostJsonld) { | |||
| const modalRefPostingEdit = this.modalService.open(NewPostingComponent, this.modalOptions); | |||
| modalRefPostingEdit.componentInstance.posting = post; | |||
| @@ -18,6 +18,39 @@ | |||
| </div> | |||
| </div> | |||
| <div class="mb-3"> | |||
| <label for="assignedTo" class="form-label">{{'form.assign-to' | translate}}:</label> | |||
| <input type="text" class="form-control" id="assignedTo" [ngbTypeahead]="search" [inputFormatter]="formatter" | |||
| [resultFormatter]="formatter" [editable]="false" (selectItem)="onAssignedToSelect($event)" /> | |||
| <input type="hidden" formControlName="assignedTo" /> | |||
| <div class="form-text" *ngIf="taskForm.get('assignedTo')?.invalid && taskForm.get('assignedTo')?.touched"> | |||
| {{'form.assign-to' | translate}} {{'form.mandatory' | translate}}. | |||
| </div> | |||
| </div> | |||
| <div class="mb-3"> | |||
| <label for="dueAt" class="form-label">{{'form.due-date' | translate}}:</label> | |||
| <input type="date" class="form-control" id="dueAt" formControlName="dueAt" /> | |||
| <div class="form-text" *ngIf="taskForm.get('dueAt')?.invalid && taskForm.get('dueAt')?.touched"> | |||
| {{'form.due-date' | translate}} {{'form.mandatory' | translate}}. | |||
| </div> | |||
| </div> | |||
| <div class="mb-3"> | |||
| <label for="prio" class="form-label">{{'form.prio' | translate}}:</label> | |||
| <select class="form-control" id="prio" formControlName="prio"> | |||
| <option value="low" selected>{{'form.prio-low' | translate}}</option> | |||
| <option value="medium">{{'form.prio-medium' | translate}}</option> | |||
| <option value="high">{{'form.prio-high' | translate}}</option> | |||
| </select> | |||
| <div class="form-text" *ngIf="taskForm.get('prio')?.invalid && taskForm.get('prio')?.touched"> | |||
| {{'form.prio' | translate}} {{'form.mandatory' | translate}}. | |||
| </div> | |||
| </div> | |||
| <button type="submit" class="btn btn-primary" [disabled]="taskForm.invalid">{{'form.send' | translate}}</button> | |||
| </form> | |||
| </div> | |||
| @@ -1,36 +1,85 @@ | |||
| import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; | |||
| import {TaskJsonld} from "@app/core/api/v1"; | |||
| import {TaskJsonld, TaskService} from "@app/core/api/v1"; | |||
| import {ModalStatus} from "@app/_helpers/modal.states"; | |||
| import {FormGroupInitializer} from "@app/_helpers/formgroup.initializer"; | |||
| import {FormGroup} from "@angular/forms"; | |||
| import {Subscription} from "rxjs"; | |||
| import {debounceTime, distinctUntilChanged, Observable, OperatorFunction, Subscription} from "rxjs"; | |||
| import {taskForm} from "@app/_forms/apiForms"; | |||
| import {ApiConverter} from "@app/_helpers/api.converter"; | |||
| import {filter, map} from "rxjs/operators"; | |||
| @Component({ | |||
| selector: 'app-new-task', | |||
| templateUrl: './new-task.component.html', | |||
| styleUrl: './new-task.component.scss' | |||
| selector: 'app-new-task', | |||
| templateUrl: './new-task.component.html', | |||
| styleUrl: './new-task.component.scss' | |||
| }) | |||
| export class NewTaskComponent implements OnInit { | |||
| @Input() public task!: TaskJsonld; | |||
| @Output() public submit: EventEmitter<ModalStatus> = new EventEmitter<ModalStatus>(); | |||
| @Input() public task!: TaskJsonld; | |||
| @Output() public submit: EventEmitter<ModalStatus> = new EventEmitter<ModalStatus>(); | |||
| protected taskForm: FormGroup; | |||
| protected taskSub: Subscription; | |||
| protected taskForm: FormGroup; | |||
| protected taskSub: Subscription; | |||
| constructor( | |||
| protected users = [ | |||
| { id: '/api/users/1', name: 'Daniel Knudsen' }, | |||
| { id: '/api/users/2', name: 'Florian Eisenmenger' }, | |||
| { id: '/api/users/3', name: 'Francis Donelly' }, | |||
| { id: '/api/users/4', name: 'Jaylen Schmitt' }, | |||
| ]; | |||
| ) { | |||
| this.taskForm = taskForm; | |||
| this.taskSub = new Subscription(); | |||
| } | |||
| protected formatter = (apiData: any) => apiData.name; | |||
| ngOnInit(): void { | |||
| this.taskForm = FormGroupInitializer.initFormGroup(this.taskForm, this.task); | |||
| } | |||
| protected search: OperatorFunction<string, readonly { id: any; name: any }[]> = (text$: Observable<string>) => | |||
| text$.pipe( | |||
| debounceTime(200), | |||
| distinctUntilChanged(), | |||
| filter((term) => term.length >= 2), | |||
| map((term) => this.users.filter((state) => new RegExp(term, 'mi').test(state.name)).slice(0, 10)), | |||
| ); | |||
| onSubmit() { | |||
| constructor( | |||
| private taskService: TaskService | |||
| ) { | |||
| this.taskForm = taskForm; | |||
| this.taskSub = new Subscription(); | |||
| } | |||
| } | |||
| ngOnInit(): void { | |||
| console.log(this.task); | |||
| this.taskForm = FormGroupInitializer.initFormGroup(this.taskForm, this.task); | |||
| } | |||
| onAssignedToSelect(selectedItem: any): void { | |||
| this.taskForm.get('assignedTo')?.setValue(selectedItem.item.id); | |||
| console.log(selectedItem); | |||
| console.log(this.taskForm); | |||
| } | |||
| onSubmit() { | |||
| if (this.taskForm.valid) { | |||
| if (this.task.id === null || this.task.id === undefined) { | |||
| // Create new post | |||
| this.taskSub = this.taskService.tasksPost( | |||
| this.taskForm.value as TaskJsonld | |||
| ).subscribe( | |||
| data => { | |||
| this.taskForm.reset(); | |||
| this.submit.emit(ModalStatus.Submitted); | |||
| } | |||
| ); | |||
| } else { | |||
| // Edit post | |||
| this.taskSub = this.taskService.tasksIdPatch( | |||
| ApiConverter.extractId(this.task.id), | |||
| this.taskForm.value as TaskJsonld | |||
| ).subscribe( | |||
| data => { | |||
| this.taskForm.reset(); | |||
| this.submit.emit(ModalStatus.Submitted); | |||
| } | |||
| ); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -79,6 +79,12 @@ | |||
| "headline": "Überschrift", | |||
| "message": "Nachricht", | |||
| "comment": "Kommentar", | |||
| "assign-to": "Zuweisen an", | |||
| "due-date": "Fälligkeitsdatum", | |||
| "prio": "Priorität", | |||
| "prio-low": "niedrig", | |||
| "prio-medium": "mittel", | |||
| "prio-high": "hoch", | |||
| "send": "Abschicken" | |||
| } | |||
| } | |||