Sfoglia il codice sorgente

Documents WIP Tasks show and hide

master
Florian Eisenmenger 1 anno fa
parent
commit
2b007e1b0f
14 ha cambiato i file con 427 aggiunte e 125 eliminazioni
  1. +5
    -5
      matsen-tool/src/app/documents/documents.component.html
  2. +57
    -50
      matsen-tool/src/app/documents/documents.component.ts
  3. +12
    -1
      matsen-tool/src/app/documents/new-document/new-document.component.html
  4. +62
    -2
      matsen-tool/src/app/documents/new-document/new-document.component.ts
  5. +41
    -27
      matsen-tool/src/app/partners/partners-detail/partners-detail.component.html
  6. +15
    -0
      matsen-tool/src/app/partners/partners-detail/partners-detail.component.ts
  7. +5
    -5
      matsen-tool/src/app/partners/partners.component.ts
  8. +2
    -2
      matsen-tool/src/app/products/products.component.html
  9. +10
    -10
      matsen-tool/src/app/products/products.component.ts
  10. +2
    -2
      matsen-tool/src/app/tasks/new-task-note/new-task-note.component.html
  11. +11
    -0
      matsen-tool/src/app/tasks/new-task/new-task.component.html
  12. +62
    -5
      matsen-tool/src/app/tasks/tasks.component.html
  13. +138
    -16
      matsen-tool/src/app/tasks/tasks.component.ts
  14. +5
    -0
      matsen-tool/src/assets/i18n/de.json

+ 5
- 5
matsen-tool/src/app/documents/documents.component.html Vedi File

@@ -3,7 +3,7 @@
<h2>{{ 'basic.documents' | translate }}</h2>
<button class="btn btn-primary" (click)="openModalNewDocument()">{{'basic.new-document' | translate}}</button>
</div>
<table mat-table [dataSource]="dataSource" matSort (matSortChange)="onSortChange($event)"
<table mat-table [dataSource]="documentsDataSource" matSort (matSortChange)="onSortChange($event)"
class="mat-elevation-z8 mb-3">

<ng-container matColumnDef="pos">
@@ -11,7 +11,7 @@
{{ 'overview.number' | translate }}
</th>
<td mat-cell
*matCellDef="let element">{{ (pageSize * pageIndex) + dataSource.filteredData.indexOf(element) + 1 }}
*matCellDef="let element">{{ (documentsPageSize * documentsPageIndex) + documentsDataSource.filteredData.indexOf(element) + 1 }}
</td>
</ng-container>

@@ -44,10 +44,10 @@
</table>
<mat-paginator class="rounded-1"
[pageSizeOptions]="[10,25,50]"
[length]="length"
[length]="documentsLength"
(page)="handlePageEvent($event)"
[pageSize]="pageSize"
[pageIndex]="pageIndex"
[pageSize]="documentsPageSize"
[pageIndex]="documentsPageIndex"
showFirstLastButtons>
</mat-paginator>
</div>

+ 57
- 50
matsen-tool/src/app/documents/documents.component.ts Vedi File

@@ -2,15 +2,17 @@ import {ChangeDetectorRef, Component, ViewChild} from '@angular/core';
import {MatSort, MatSortModule, Sort} from "@angular/material/sort";
import {MatPaginator, MatPaginatorIntl, MatPaginatorModule, PageEvent} from "@angular/material/paginator";
import {Subscription} from "rxjs";
import {PartnerJsonld} from "@app/core/api/v1";
import {DocumentJsonldDocumentObjectRead, DocumentService, PartnerJsonld, ProductJsonld} from "@app/core/api/v1";
import {Router, RouterLink, RouterLinkActive} from "@angular/router";
import {MatTableDataSource, MatTableModule} from "@angular/material/table";
import {OrderFilter} from "@app/_models/orderFilter";
import {NgIf} from "@angular/common";
import {ModalComponent} from "@app/_components/modal/modal.component";
import {NgbModal} from "@ng-bootstrap/ng-bootstrap";
import {NgbModal, NgbModalOptions} from "@ng-bootstrap/ng-bootstrap";
import {NewDocumentComponent} from "@app/documents/new-document/new-document.component";
import {TranslateModule} from "@ngx-translate/core";
import {NewProductComponent} from "@app/products/new-product/new-product.component";
import {ModalStatus} from "@app/_helpers/modal.states";

@Component({
selector: 'app-documents',
@@ -21,71 +23,67 @@ import {TranslateModule} from "@ngx-translate/core";
})
export class DocumentsComponent {
@ViewChild(MatSort) sort;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatPaginator) documentsPaginator: MatPaginator;

protected documentsSub: Subscription;
protected documents: Array<PartnerJsonld>;
protected dataType!: string;

protected dataSource;
protected displayedColumns: string[];

protected length: number;
protected pageEvent: PageEvent;
protected pageSize: number;
protected pageIndex: number;
protected documentsSub: Subscription;
protected documents: Array<DocumentJsonldDocumentObjectRead>;
protected documentsDataSource;
protected documentsLength: number;
protected documentsPageEvent: PageEvent;
protected documentsPageSize: number;
protected documentsPageIndex: number;

protected modalOptions: NgbModalOptions = {
centered: true
};

constructor(
private router: Router,
private modalService: NgbModal
private modalService: NgbModal,
private documentService: DocumentService
) {
this.sort = new MatSort();
this.paginator = new MatPaginator(new MatPaginatorIntl(), ChangeDetectorRef.prototype);
this.dataSource = new MatTableDataSource; //<DocumentJsonld>(this.documents)
this.displayedColumns = ['pos', 'name', 'type', 'date'];

this.documentsSub = new Subscription();
this.documents = [];

this.length = 0;
this.pageEvent = new PageEvent();
this.pageSize = 10;
this.pageIndex = 0;
this.documentsPaginator = new MatPaginator(new MatPaginatorIntl(), ChangeDetectorRef.prototype);
this.documentsDataSource = new MatTableDataSource<DocumentJsonldDocumentObjectRead>(this.documents);
this.documentsLength = 0;
this.documentsPageEvent = new PageEvent();
this.documentsPageSize = 10;
this.documentsPageIndex = 0;
}

ngOnInit() {
this.getData();
this.getDocumentsData();
}

ngAfterViewInit() {
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
this.documentsDataSource.sort = this.sort;
this.documentsDataSource.paginator = this.documentsPaginator;
}

getData() {
// this.documentsSub = this.documentService.documentsGetCollection(
// this.pageIndex + 1,
// this.pageSize,
// this.dataType,
// undefined,
// this.nameOrderAsc,
// this.storageOrderAsc,
// this.numberOrderAsc
// ).subscribe(
// data => {
// this.documents = data["hydra:member"];
// this.dataSource = new MatTableDataSource<DocumentJsonld>(this.documents);
// console.log(data);
// this.length = Number(data["hydra:totalItems"]);
// this.paginator.length = this.length;
// }
// );
getDocumentsData() {
this.documentsSub = this.documentService.documentsGetCollection(
this.documentsPageIndex + 1,
this.documentsPageSize
).subscribe(
data => {
this.documents = data["hydra:member"];
this.documentsDataSource = new MatTableDataSource<DocumentJsonldDocumentObjectRead>(this.documents);
this.documentsLength = Number(data["hydra:totalItems"]);
this.documentsPaginator.length = this.documentsLength;
}
);
}

/** Announce the change in sort state for assistive technology. */
onSortChange(sortState: Sort) {
// Reset page index to first page
this.pageIndex = 0;
this.documentsPageIndex = 0;

let order: OrderFilter;
if (sortState.direction === "") {
@@ -108,15 +106,15 @@ export class DocumentsComponent {
// this.websiteOrderAsc = order;
// break;
// }
this.getData();
this.getDocumentsData();
}

handlePageEvent(e: PageEvent) {
this.pageEvent = e;
this.length = e.length;
this.pageIndex = e.pageIndex.valueOf();
this.pageSize = e.pageSize.valueOf();
this.getData();
this.documentsPageEvent = e;
this.documentsLength = e.length;
this.documentsPageIndex = e.pageIndex.valueOf();
this.documentsPageSize = e.pageSize.valueOf();
this.getDocumentsData();
}

navigateToDocumentFile(element: any) {
@@ -127,7 +125,16 @@ export class DocumentsComponent {
}

openModalNewDocument() {
const modalRef = this.modalService.open(ModalComponent);
modalRef.componentInstance.dynamicComponent = NewDocumentComponent;
const modalRefDocument = this.modalService.open(NewDocumentComponent, this.modalOptions);
// TODO: Warum muss ich einen leeren String übergeben, damit es funktioniert?
let document: ProductJsonld = {} as ProductJsonld;
document.name = "";
modalRefDocument.componentInstance.document = document;
modalRefDocument.componentInstance.submit.subscribe((modalStatus: ModalStatus) => {
if (modalStatus === ModalStatus.Submitted) {
modalRefDocument.dismiss();
this.getDocumentsData();
}
});
}
}

+ 12
- 1
matsen-tool/src/app/documents/new-document/new-document.component.html Vedi File

@@ -1 +1,12 @@
<p>new-document works!</p>
<h2 *ngIf="!document.id">{{'basic.new-document' | translate}}</h2>
<h2 *ngIf="document.id">{{'basic.edit-document' | translate}}</h2>
<div class="spt-form">
<form [formGroup]="documentForm" (ngSubmit)="onSubmit()">
<div class="mb-3">
<label for="image" class="form-label">{{'form.upload-image' | translate}}:</label>
<input type="file" class="form-control" id="image" (change)="onFileSelected($event)" accept="image/*" />
</div>

<button type="submit" class="btn btn-primary" [disabled]="documentForm.invalid">{{'form.send' | translate}}</button>
</form>
</div>

+ 62
- 2
matsen-tool/src/app/documents/new-document/new-document.component.ts Vedi File

@@ -1,10 +1,70 @@
import { Component } from '@angular/core';
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {
DocumentJsonldDocumentObjectRead,
DocumentService,
MediaService,
ProductJsonld,
ProductService
} from "@app/core/api/v1";
import {ModalStatus} from "@app/_helpers/modal.states";
import {FormGroup} from "@angular/forms";
import {Subscription} from "rxjs";
import {TranslateService} from "@ngx-translate/core";
import {FormGroupInitializer} from "@app/_helpers/formgroup.initializer";
import {ApiConverter} from "@app/_helpers/api.converter";
import {documentDocumentObjectReadForm} from "@app/_forms/apiForms";

@Component({
selector: 'app-new-document',
templateUrl: './new-document.component.html',
styleUrl: './new-document.component.scss'
})
export class NewDocumentComponent {
export class NewDocumentComponent implements OnInit {
@Input() public document!: DocumentJsonldDocumentObjectRead;
@Output() public submit: EventEmitter<ModalStatus> = new EventEmitter<ModalStatus>();

protected documentForm: FormGroup;
protected documentSub: Subscription;

protected selectedImage: File | null;
protected mediaSub: Subscription;

constructor(
private documentService: DocumentService,
private mediaService: MediaService,
private translateService: TranslateService
) {
this.documentForm = documentDocumentObjectReadForm;
this.documentSub = new Subscription();

this.selectedImage = null;
this.mediaSub = new Subscription();
}

ngOnInit(): void {
this.documentForm = FormGroupInitializer.initFormGroup(this.documentForm, this.document);
}

onSubmit() {
// if (this.documentForm.valid) {
// if (this.document.id === null || this.document.id === undefined) {
// // Create new product
// this.documentSub = this.documentService.documentsPost(
// this.documentForm.value as DocumentJsonldDocumentObjectRead
// ).subscribe(
// data => {
// this.documentForm.reset();
// this.submit.emit(ModalStatus.Submitted);
// }
// );
// }
// }
}

onFileSelected(event: any) {
const file: File = event.target.files[0];
if (file) {
this.selectedImage = file;
}
}
}

+ 41
- 27
matsen-tool/src/app/partners/partners-detail/partners-detail.component.html Vedi File

@@ -26,8 +26,9 @@
</dl>
</div>
<div class="col-4">
<img *ngIf="partner.logoUrl !== null && partner.logoUrl !== undefined" src="{{partner.logoUrl}}" width="247"
height="94" alt="{{partner.name}}" title="{{partner.name}}" />
<img *ngIf="partner.logoUrl !== null && partner.logoUrl !== undefined" src="{{partner.logoUrl}}"
width="247"
height="94" alt="{{partner.name}}" title="{{partner.name}}"/>
</div>
<span class="position-absolute bi bi-pencil p-2" data-type="user-tool" data-action="edit"
(click)="openModalEditPartner()"></span>
@@ -37,8 +38,9 @@
<div class="spt-container">
<div class="contacts">
<div class="d-flex justify-content-between align-items-start">
<h2>{{'basic.contacts' | translate}}</h2>
<button class="btn btn-primary" (click)="openModalNewContact()">{{'basic.new-contact' | translate}}</button>
<h2>{{ 'basic.contacts' | translate }}</h2>
<button class="btn btn-primary" (click)="openModalNewContact()">{{ 'basic.new-contact' | translate }}
</button>
</div>
<div class="row">
<div class="col-4" *ngFor="let contact of contacts">
@@ -59,7 +61,8 @@
</div>
</div>
<div class="d-flex justify-content-end mt-1 mb-4">
<span role="button" (click)="navigateToContactDetails(contact)" class="badge bg-secondary p-2">{{'basic.details' | translate}}</span>
<span role="button" (click)="navigateToContactDetails(contact)"
class="badge bg-secondary p-2">{{ 'basic.details' | translate }}</span>
</div>
</div>
</div>
@@ -101,46 +104,55 @@
<div class="spt-container">
<div class="spt-accordion">
<div class="d-flex justify-content-between align-items-start">
<h2>{{'basic.tasks' | translate}}</h2>
<button class="btn btn-primary" (click)="openModalNewTask()">{{'basic.new-task' | translate}}</button>
<h2>{{ 'basic.tasks' | translate }}</h2>
<button class="btn btn-primary" (click)="openModalNewTask()">{{ 'basic.new-task' | translate }}</button>
</div>
<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-controls="collapseExample">
<h3 class="m-0">{{task.partner}}</h3>
<h3 class="m-0">{{ task.partnerName }}</h3>
<span class="info d-flex position-absolute">
<span class="due-date">{{ task.dueAt | date:'dd.MM.YYYY HH:mm':'GMT+0000' }}</span>
<span class="importance" [attr.data-importance]="task.prio"></span>
</span>
<h2 class="m-0">{{task.headline}}</h2>
<h2 class="m-0">{{ task.headline }}</h2>
</div>
<div class="collapse" id="collapse-{{ApiConverter.extractId(task.id)}}">
<div class="pt-3 pe-5 position-relative">
<p class="m-0">{{task.description}}</p>
<p>Zugewiesen an: {{task.assignedTo}}</p>
<p class="m-0">{{ task.description }}</p>
<p>Zugewiesen an: {{ task.assignedToName }}</p>
<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>
<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 *ngIf="task.id && taskNotesVisibility.get(task.id)">
<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>
<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>
<span *ngIf="task.taskNotes?.length !== 0" role="button" class="badge bg-secondary p-2 me-2"
(click)="showTaskNotes(task)">
<ng-container *ngIf="task.id && taskNotesVisibility.get(task.id)">{{ 'basic.hide-comments' | translate }}</ng-container>
<ng-container *ngIf="task.id && !taskNotesVisibility.get(task.id)">{{ 'basic.show-comments' | translate }}</ng-container>
</span>
<span role="button" class="badge bg-secondary p-2"
(click)="openModalNewTaskNote(task)">{{ 'basic.comment-it' | translate }}</span>
</div>
</div>
<mat-paginator *ngIf="tasks.length > 0" class="rounded-1"
@@ -156,8 +168,8 @@
<div class="spt-container">
<div class="posts">
<div class="d-flex justify-content-between align-items-start">
<h2>{{'basic.posts' | translate}}</h2>
<button class="btn btn-primary" (click)="openModalNewPosting()">{{'basic.new-post' | translate}}</button>
<h2>{{ 'basic.posts' | translate }}</h2>
<button class="btn btn-primary" (click)="openModalNewPosting()">{{ 'basic.new-post' | translate }}</button>
</div>
<div class="post mb-3" *ngFor="let post of posts">
<div class="card">
@@ -170,7 +182,8 @@
<h3>{{ post.headline }}</h3>
<p>{{ post.message }}</p>
</div>
<span *ngIf="post.owner === user?.id" class="position-absolute bi bi-pencil p-2" data-type="user-tool"
<span *ngIf="post.owner === user?.id" class="position-absolute bi bi-pencil p-2"
data-type="user-tool"
data-action="edit" (click)="openModalEditPosting(post)"></span>
</div>
</div>
@@ -189,7 +202,8 @@
</div>

<div class="d-flex justify-content-end mt-1">
<span role="button" class="badge bg-secondary p-2" (click)="openModalNewComment(post)">{{'basic.comment-it' | translate}}</span>
<span role="button" class="badge bg-secondary p-2"
(click)="openModalNewComment(post)">{{ 'basic.comment-it' | translate }}</span>
</div>
</div>
<mat-paginator *ngIf="posts.length > 0" class="rounded-1"


+ 15
- 0
matsen-tool/src/app/partners/partners-detail/partners-detail.component.ts Vedi File

@@ -61,6 +61,8 @@ export class PartnersDetailComponent implements OnInit, AfterViewInit {
protected tasksPageSize: number;
protected tasksPageIndex: number;

protected taskNotesVisibility: Map<string, boolean>;

protected postsSub: Subscription;
protected posts: Array<PostJsonld>;
protected postsDataSource;
@@ -108,6 +110,7 @@ export class PartnersDetailComponent implements OnInit, AfterViewInit {
this.tasksPageEvent = new PageEvent();
this.tasksPageSize = 10;
this.tasksPageIndex = 0;
this.taskNotesVisibility = new Map<string, boolean>();

this.postsSub = new Subscription();
this.posts = [];
@@ -184,6 +187,11 @@ export class PartnersDetailComponent implements OnInit, AfterViewInit {
data => {
this.tasks = data["hydra:member"];
this.tasksLength = Number(data["hydra:totalItems"]);
this.tasks.forEach(task => {
if (task.id) {
this.taskNotesVisibility.set(task.id, false);
}
});
console.log(this.tasks);
}
);
@@ -339,4 +347,11 @@ export class PartnersDetailComponent implements OnInit, AfterViewInit {
}
});
}

showTaskNotes(task: TaskJsonld) {
if (task.id) {
const currentVisibility = this.taskNotesVisibility.get(task.id);
this.taskNotesVisibility.set(task.id, !currentVisibility);
}
}
}

+ 5
- 5
matsen-tool/src/app/partners/partners.component.ts Vedi File

@@ -84,7 +84,7 @@ export class PartnersComponent implements OnInit, AfterViewInit {
this.translateService.get('basic.' + this.dataType + 'One').subscribe((translation: string) => {
this.partnerNameOne = translation;
});
this.getData();
this.getPartnersData();
}

ngAfterViewInit() {
@@ -92,7 +92,7 @@ export class PartnersComponent implements OnInit, AfterViewInit {
this.dataSource.paginator = this.paginator;
}

getData() {
getPartnersData() {
this.partnersSub = this.partnerService.partnersGetCollection(
this.pageIndex + 1,
this.pageSize,
@@ -138,7 +138,7 @@ export class PartnersComponent implements OnInit, AfterViewInit {
this.websiteOrderAsc = order;
break;
}
this.getData();
this.getPartnersData();
}

handlePageEvent(e: PageEvent) {
@@ -146,7 +146,7 @@ export class PartnersComponent implements OnInit, AfterViewInit {
this.length = e.length;
this.pageIndex = e.pageIndex.valueOf();
this.pageSize = e.pageSize.valueOf();
this.getData();
this.getPartnersData();
}

navigateToPartnerDetails(element: any) {
@@ -163,7 +163,7 @@ export class PartnersComponent implements OnInit, AfterViewInit {
modalRefContact.componentInstance.submit.subscribe((modalStatus: ModalStatus) => {
if (modalStatus === ModalStatus.Submitted) {
modalRefContact.dismiss();
this.getData();
this.getPartnersData();
}
});
}


+ 2
- 2
matsen-tool/src/app/products/products.component.html Vedi File

@@ -11,7 +11,7 @@
{{ 'overview.number' | translate }}
</th>
<td mat-cell
*matCellDef="let element">{{ (productsPageSize * productPageIndex) + productsDataSource.filteredData.indexOf(element) + 1 }}
*matCellDef="let element">{{ (productsPageSize * productsPageIndex) + productsDataSource.filteredData.indexOf(element) + 1 }}
</td>
</ng-container>

@@ -61,7 +61,7 @@
[length]="productsLength"
(page)="handlePageEvent($event)"
[pageSize]="productsPageSize"
[pageIndex]="productPageIndex"
[pageIndex]="productsPageIndex"
showFirstLastButtons>
</mat-paginator>
</div>

+ 10
- 10
matsen-tool/src/app/products/products.component.ts Vedi File

@@ -32,7 +32,7 @@ export class ProductsComponent implements OnInit, AfterViewInit {
protected productsLength: number;
protected productsPageEvent: PageEvent;
protected productsPageSize: number;
protected productPageIndex: number;
protected productsPageIndex: number;

protected modalOptions: NgbModalOptions = {
centered: true
@@ -53,11 +53,11 @@ export class ProductsComponent implements OnInit, AfterViewInit {
this.productsLength = 0;
this.productsPageEvent = new PageEvent();
this.productsPageSize = 10;
this.productPageIndex = 0;
this.productsPageIndex = 0;
}

ngOnInit() {
this.getProductData();
this.getProductsData();
}

ngAfterViewInit() {
@@ -65,9 +65,9 @@ export class ProductsComponent implements OnInit, AfterViewInit {
this.productsDataSource.paginator = this.productsPaginator;
}

getProductData() {
getProductsData() {
this.productsSub = this.productService.productsGetCollection(
this.productPageIndex + 1,
this.productsPageIndex + 1,
this.productsPageSize
).subscribe(
data => {
@@ -82,7 +82,7 @@ export class ProductsComponent implements OnInit, AfterViewInit {
/** Announce the change in sort state for assistive technology. */
onSortChange(sortState: Sort) {
// Reset page index to first page
this.productPageIndex = 0;
this.productsPageIndex = 0;

let order: OrderFilter;
if (sortState.direction === "") {
@@ -105,15 +105,15 @@ export class ProductsComponent implements OnInit, AfterViewInit {
// this.websiteOrderAsc = order;
// break;
// }
this.getProductData();
this.getProductsData();
}

handlePageEvent(e: PageEvent) {
this.productsPageEvent = e;
this.productsLength = e.length;
this.productPageIndex = e.pageIndex.valueOf();
this.productsPageIndex = e.pageIndex.valueOf();
this.productsPageSize = e.pageSize.valueOf();
this.getProductData();
this.getProductsData();
}

navigateToProductDetails(element: any) {
@@ -130,7 +130,7 @@ export class ProductsComponent implements OnInit, AfterViewInit {
modalRefProduct.componentInstance.submit.subscribe((modalStatus: ModalStatus) => {
if (modalStatus === ModalStatus.Submitted) {
modalRefProduct.dismiss();
this.getProductData();
this.getProductsData();
}
});
}


+ 2
- 2
matsen-tool/src/app/tasks/new-task-note/new-task-note.component.html Vedi File

@@ -1,5 +1,5 @@
<h2 *ngIf="!taskNote.id">{{'basic.new-comment' | translate}}</h2>
<h2 *ngIf="taskNote.id">{{'basic.edit-comment' | translate}}</h2>
<h2 *ngIf="!taskNote.id">{{'basic.new-task-note' | translate}}</h2>
<h2 *ngIf="taskNote.id">{{'basic.edit-task-note' | translate}}</h2>
<div class="spt-form">
<form [formGroup]="taskNoteForm" (ngSubmit)="onSubmit()">
<div class="mb-3">


+ 11
- 0
matsen-tool/src/app/tasks/new-task/new-task.component.html Vedi File

@@ -18,6 +18,17 @@
</div>
</div>

<div class="mb-3" *ngIf="task.partner == null">
<label for="partner" class="form-label">{{'form.partner' | translate}}:</label>
<select class="form-control" id="partner" formControlName="partner">
<!-- ALLE PARTNER LADEN ODER BESSER: ELASTIC SEARCH -->
<option value="/api/partners/101">CatalystX SAS</option>
</select>
<div class="form-text" *ngIf="taskForm.get('partner')?.invalid && taskForm.get('partner')?.touched">
{{'form.partner' | translate}} {{'form.mandatory' | translate}}.
</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"


+ 62
- 5
matsen-tool/src/app/tasks/tasks.component.html Vedi File

@@ -1,5 +1,62 @@
<div class="d-flex justify-content-between align-items-start">
<h2>{{'basic.tasks' | translate}}</h2>
<button class="btn btn-primary" (click)="openModalNewTask()">{{'basic.new-product' | translate}}</button>
</div>
<p>tasks works!</p>
<div class="spt-container">
<div class="spt-accordion">
<div class="d-flex justify-content-between align-items-start">
<h2>{{'basic.tasks' | translate}}</h2>
<button class="btn btn-primary" (click)="openModalNewTask()">{{'basic.new-task' | translate}}</button>
</div>
<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)"
aria-expanded="false"
aria-controls="collapseExample">
<h3 class="m-0">{{task.partnerName}}</h3>
<span class="info d-flex position-absolute">
<span class="due-date">{{ task.dueAt | date:'dd.MM.YYYY HH:mm':'GMT+0000' }}</span>
<span class="importance" [attr.data-importance]="task.prio"></span>
</span>
<h2 class="m-0">{{task.headline}}</h2>
</div>
<div class="collapse" id="collapse-{{ApiConverter.extractId(task.id)}}">
<div class="pt-3 pe-5 position-relative">
<p class="m-0">{{task.description}}</p>
<p>Zugewiesen an: {{task.assignedToName}}</p>
<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>
<div *ngIf="task.id && taskNotesVisibility.get(task.id)">
<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>

<div class="d-flex justify-content-end mt-1">
<span *ngIf="task.taskNotes?.length !== 0" role="button" class="badge bg-secondary p-2 me-2"
(click)="showTaskNotes(task)">
<ng-container *ngIf="task.id && taskNotesVisibility.get(task.id)">{{ 'basic.hide-comments' | translate }}</ng-container>
<ng-container *ngIf="task.id && !taskNotesVisibility.get(task.id)">{{ 'basic.show-comments' | translate }}</ng-container>
</span>
<span role="button" class="badge bg-secondary p-2" (click)="openModalNewTaskNote(task)">{{'basic.comment-it' | translate}}</span>
</div>
</div>
<mat-paginator *ngIf="tasks.length > 0" class="rounded-1"
[pageSizeOptions]="[10,20,30]"
[length]="tasksLength"
(page)="tasksHandlePageEvent($event)"
[pageSize]="tasksPageSize"
[pageIndex]="tasksPageIndex"
showFirstLastButtons>
</mat-paginator>
</div>
</div>

+ 138
- 16
matsen-tool/src/app/tasks/tasks.component.ts Vedi File

@@ -1,27 +1,149 @@
import {Component, OnInit} from '@angular/core';
import {AfterViewInit, ChangeDetectorRef, Component, OnInit, ViewChild} from '@angular/core';
import {NewTaskComponent} from "@app/tasks/new-task/new-task.component";
import {NgbModal} from "@ng-bootstrap/ng-bootstrap";
import {NgbModal, NgbModalOptions} from "@ng-bootstrap/ng-bootstrap";
import {ModalComponent} from "@app/_components/modal/modal.component";
import {ApiConverter} from "@app/_helpers/api.converter";
import {Subscription} from "rxjs";
import {TaskJsonld, TaskNoteJsonld, TaskService} from "@app/core/api/v1";
import {MatPaginator, MatPaginatorIntl, PageEvent} from "@angular/material/paginator";
import {MatTableDataSource} from "@angular/material/table";
import {User} from "@app/_models";
import {AccountService} from "@app/_services";
import {ModalStatus} from "@app/_helpers/modal.states";
import {NewTaskNoteComponent} from "@app/tasks/new-task-note/new-task-note.component";

@Component({
selector: 'app-tasks',
templateUrl: './tasks.component.html',
styleUrl: './tasks.component.scss'
selector: 'app-tasks',
templateUrl: './tasks.component.html',
styleUrl: './tasks.component.scss'
})
export class TasksComponent implements OnInit {
export class TasksComponent implements OnInit, AfterViewInit {
@ViewChild(MatPaginator) tasksPaginator: MatPaginator;

constructor(
private modalService: NgbModal
) {
protected user: User | null;
protected readonly ApiConverter = ApiConverter;

}
protected tasksSub: Subscription;
protected tasks: Array<TaskJsonld>;
protected tasksDataSource;
protected tasksLength: number;
protected tasksPageEvent: PageEvent;
protected tasksPageSize: number;
protected tasksPageIndex: number;

ngOnInit() {
protected taskNotesVisibility: Map<string, boolean>;

}
protected modalOptions: NgbModalOptions = {
centered: true
};

openModalNewTask() {
const modalRef = this.modalService.open(ModalComponent);
modalRef.componentInstance.dynamicComponent = NewTaskComponent;
}
constructor(
private modalService: NgbModal,
private accountService: AccountService,
private taskService: TaskService
) {
this.user = this.accountService.userValue;

this.tasksSub = new Subscription();
this.tasks = [];
this.tasksPaginator = new MatPaginator(new MatPaginatorIntl(), ChangeDetectorRef.prototype);
this.tasksDataSource = new MatTableDataSource<TaskJsonld>(this.tasks);
this.tasksLength = 0;
this.tasksPageEvent = new PageEvent();
this.tasksPageSize = 10;
this.tasksPageIndex = 0;
this.taskNotesVisibility = new Map<string, boolean>();
}

ngOnInit() {
this.getTasksData();
}

ngAfterViewInit() {
this.tasksDataSource.paginator = this.tasksPaginator;
}

getTasksData() {
this.tasksSub = this.taskService.tasksGetCollection(
this.tasksPageIndex + 1,
this.tasksPageSize,
// TODO: User-ID muss übergeben werden können, damit man nur die Tasks bekommt, die einem User zugewiesen sind
).subscribe(
data => {
this.tasks = data["hydra:member"];
this.tasksLength = Number(data["hydra:totalItems"]);
this.tasks.forEach(task => {
if (task.id) {
this.taskNotesVisibility.set(task.id, false);
}
});
console.log(this.tasks);
}
);
}

tasksHandlePageEvent(e: PageEvent) {
this.tasksPageEvent = e;
this.tasksLength = e.length;
this.tasksPageIndex = e.pageIndex.valueOf();
this.tasksPageSize = e.pageSize.valueOf();
this.getTasksData();
}

openModalNewTask() {
const modalRefTask = this.modalService.open(NewTaskComponent, this.modalOptions);
let task: TaskJsonld = {} as TaskJsonld;
task.partner = null;
task.completed = false;
modalRefTask.componentInstance.task = task;
modalRefTask.componentInstance.submit.subscribe((modalStatus: ModalStatus) => {
if (modalStatus === ModalStatus.Submitted) {
modalRefTask.dismiss();
this.getTasksData();
}
});
}

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();
}
});
}

openModalEditTask(task: TaskJsonld) {
const modalRefTaskEdit = this.modalService.open(NewTaskComponent, this.modalOptions);
modalRefTaskEdit.componentInstance.task = task;
modalRefTaskEdit.componentInstance.dueAtValue = ApiConverter.convertDate(task.dueAt);
modalRefTaskEdit.componentInstance.submit.subscribe((modalStatus: ModalStatus) => {
if (modalStatus === ModalStatus.Submitted) {
modalRefTaskEdit.dismiss();
this.getTasksData();
}
});
}

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();
}
});
}

showTaskNotes(task: TaskJsonld) {
if (task.id) {
const currentVisibility = this.taskNotesVisibility.get(task.id);
this.taskNotesVisibility.set(task.id, !currentVisibility);
}
}
}

+ 5
- 0
matsen-tool/src/assets/i18n/de.json Vedi File

@@ -26,6 +26,7 @@
"new-contact": "Neuer Kontakt",
"new-post": "Neue Notiz",
"new-comment": "Neuer Kommentar",
"new-task-note": "Neue Anmerkung",
"edit-before": "",
"edit-after": "bearbeiten",
"edit-product": "Produkt bearbeiten",
@@ -34,8 +35,11 @@
"edit-contact": "Kontakt bearbeiten",
"edit-post": "Notiz bearbeiten",
"edit-comment": "Kommentar bearbeiten",
"edit-task-note": "Anmerkung bearbeiten",
"details": "Details",
"comment-it": "Kommentieren",
"show-comments": "Kommentare anzeigen",
"hide-comments": "Kommentare ausblenden",
"back": "Zurück"
},
"user":
@@ -85,6 +89,7 @@
"prio-low": "niedrig",
"prio-medium": "mittel",
"prio-high": "hoch",
"partner": "Partner",
"send": "Abschicken"
}
}

Caricamento…
Annulla
Salva