| @@ -5591,6 +5591,11 @@ components: | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| contactName: | |||
| readOnly: true | |||
| type: | |||
| - string | |||
| - 'null' | |||
| sale: | |||
| type: | |||
| - string | |||
| @@ -5740,6 +5745,11 @@ components: | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| contactName: | |||
| readOnly: true | |||
| type: | |||
| - string | |||
| - 'null' | |||
| sale: | |||
| type: | |||
| - string | |||
| @@ -5896,6 +5906,11 @@ components: | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| contactName: | |||
| readOnly: true | |||
| type: | |||
| - string | |||
| - 'null' | |||
| sale: | |||
| type: | |||
| - string | |||
| @@ -57,6 +57,13 @@ | |||
| </div> | |||
| </a> | |||
| </li> | |||
| <li class="nav-item mb-3"> | |||
| <a class="card" routerLink="/user" routerLinkActive="active"> | |||
| <div class="card-body position-relative bi bi-journals"> | |||
| <h3 class="position-absolute m-0">{{'basic.users' | translate}}</h3> | |||
| </div> | |||
| </a> | |||
| </li> | |||
| </ul> | |||
| </div> | |||
| <div class="col-10 pb-5"> | |||
| @@ -290,6 +290,7 @@ export const postForm = new FormGroup({ | |||
| product: new FormControl(null, []), | |||
| productName: new FormControl(null, []), | |||
| contact: new FormControl(null, []), | |||
| contactName: new FormControl(null, []), | |||
| sale: new FormControl(null, []), | |||
| comments: new FormControl(null, []), | |||
| createdAt: new FormControl(null, []) | |||
| @@ -321,6 +322,7 @@ export const postJsonhalForm = new FormGroup({ | |||
| product: new FormControl(null, []), | |||
| productName: new FormControl(null, []), | |||
| contact: new FormControl(null, []), | |||
| contactName: new FormControl(null, []), | |||
| sale: new FormControl(null, []), | |||
| comments: new FormControl(null, []), | |||
| createdAt: new FormControl(null, []) | |||
| @@ -347,6 +349,7 @@ export const postJsonldForm = new FormGroup({ | |||
| product: new FormControl(null, []), | |||
| productName: new FormControl(null, []), | |||
| contact: new FormControl(null, []), | |||
| contactName: new FormControl(null, []), | |||
| sale: new FormControl(null, []), | |||
| comments: new FormControl(null, []), | |||
| createdAt: new FormControl(null, []) | |||
| @@ -8,7 +8,6 @@ import { | |||
| import {Subscription} from "rxjs"; | |||
| import {environment} from "@environments/environment"; | |||
| import {AppHelperService} from "@app/_helpers/app-helper.service"; | |||
| import {ModalStatus} from "@app/_helpers/modal.states"; | |||
| import {AccountService} from "@app/_services"; | |||
| import {User} from "@app/_models"; | |||
| import {NewPartnerComponent} from "@app/_views/partners/new-partner/new-partner.component"; | |||
| @@ -17,7 +16,6 @@ import {PostListComponent} from "@app/_views/posts/post-list/post-list.component | |||
| import {ContactListComponent} from "@app/_views/contacts/contact-list/contact-list.component"; | |||
| import {TaskListComponent} from "@app/_views/tasks/task-list/task-list.component"; | |||
| import {ProductListComponent} from "@app/_views/products/product-list/product-list.component"; | |||
| import {NewTaskComponent} from "@app/_views/tasks/new-task/new-task.component"; | |||
| @Component({ | |||
| selector: 'app-partners-detail', | |||
| @@ -47,7 +45,6 @@ export class PartnersDetailComponent implements OnInit, AfterViewInit { | |||
| constructor( | |||
| private accountService: AccountService, | |||
| private modalService: NgbModal, | |||
| private route: ActivatedRoute, | |||
| private partnerService: PartnerService, | |||
| private partnerFollowService: PartnerFollowService, | |||
| @@ -10,7 +10,8 @@ | |||
| <div class="card-body"> | |||
| <div class="d-flex justify-content-between align-items-center"> | |||
| <h3 class="m-0"><a href="/{{post.partnerType}}/{{this.appHelperService.extractId(post.partner)}}">{{post.partnerName}}</a></h3> | |||
| <h3 class="m-0" *ngIf="post.contact"><a href="/contact/{{this.appHelperService.extractId(post.contact)}}">{{contact.firstName}} {{contact.lastName}}</a></h3> | |||
| <h3 class="m-0" *ngIf="post.contact"><a href="/contact/{{this.appHelperService.extractId(post.contact)}}">{{post.contactName}}</a></h3> | |||
| <h3 class="m-0"><a href="/product/{{this.appHelperService.extractId(post.product)}}">{{post.productName}}</a></h3> | |||
| <p>{{ post.createdAt | date:'dd.MM.YYYY' }}</p> | |||
| <p>{{ post.ownerName }}</p> | |||
| </div> | |||
| @@ -33,16 +33,11 @@ export class SalesDetailComponent implements OnInit, AfterViewInit { | |||
| protected dataSource; | |||
| protected commentsVisibility: Map<string, boolean>; | |||
| protected modalOptions: NgbModalOptions = { | |||
| centered: true | |||
| }; | |||
| constructor( | |||
| private accountService: AccountService, | |||
| private saleService: SaleService, | |||
| private route: ActivatedRoute, | |||
| private postService: PostService, | |||
| private modalService: NgbModal, | |||
| protected appHelperService: AppHelperService | |||
| ) { | |||
| this.user = this.accountService.userValue; | |||
| @@ -1,4 +1,4 @@ | |||
| <div class="spt-container"> | |||
| <div *ngIf="user" class="spt-container"> | |||
| <div class="card"> | |||
| <div class="card-body row"> | |||
| <div class="col-4"> | |||
| @@ -16,58 +16,59 @@ | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <ng-container *ngIf="user"> | |||
| <app-toggle #togglePosts [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.posts' | translate)"> | |||
| <app-post-list *ngIf="togglePosts.isOpened" #postListComponent | |||
| [user]="user" | |||
| > | |||
| </app-post-list> | |||
| </app-toggle> | |||
| <app-toggle #togglePosts [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.posts' | translate)"> | |||
| <app-post-list *ngIf="togglePosts.isOpened" #postListComponent | |||
| [user]="user" | |||
| > | |||
| </app-post-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleTasks [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.tasks' | translate)"> | |||
| <app-task-list *ngIf="toggleTasks.isOpened" #taskListComponent | |||
| [user]="user" | |||
| > | |||
| </app-task-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleTasks [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.tasks' | translate)"> | |||
| <app-task-list *ngIf="toggleTasks.isOpened" #taskListComponent | |||
| [user]="user" | |||
| > | |||
| </app-task-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleSales [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.sales' | translate)"> | |||
| <app-sale-summary *ngIf="toggleSales.isOpened" #saleSummaryComponent | |||
| [user]="user" | |||
| > | |||
| </app-sale-summary> | |||
| <app-sale-list *ngIf="toggleSales.isOpened" #saleListComponent | |||
| [user]="user" | |||
| > | |||
| </app-sale-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleSales [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.sales' | translate)"> | |||
| <app-sale-summary *ngIf="toggleSales.isOpened" #saleSummaryComponent | |||
| [user]="user" | |||
| > | |||
| </app-sale-summary> | |||
| <app-sale-list *ngIf="toggleSales.isOpened" #saleListComponent | |||
| [user]="user" | |||
| > | |||
| </app-sale-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleProducts [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.products' | translate)"> | |||
| <app-product-list *ngIf="toggleProducts.isOpened" #productListComponent | |||
| [user]="user"> | |||
| </app-product-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleProducts [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.products' | translate)"> | |||
| <app-product-list *ngIf="toggleProducts.isOpened" #productListComponent | |||
| [user]="user"> | |||
| </app-product-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleCustomers [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.customer' | translate)"> | |||
| <app-partner-list *ngIf="toggleCustomers.isOpened" #customerListComponent | |||
| [user]="user" | |||
| [partnerType]="'customer'" | |||
| > | |||
| </app-partner-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleCustomers [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.customer' | translate)"> | |||
| <app-partner-list *ngIf="toggleCustomers.isOpened" #customerListComponent | |||
| [user]="user" | |||
| [partnerType]="'customer'" | |||
| > | |||
| </app-partner-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleSuppliers [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.supplier' | translate)"> | |||
| <app-partner-list *ngIf="toggleSuppliers.isOpened" #suppliersListComponent | |||
| [user]="user" | |||
| [partnerType]="'supplier'" | |||
| > | |||
| </app-partner-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleSuppliers [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.supplier' | translate)"> | |||
| <app-partner-list *ngIf="toggleSuppliers.isOpened" #suppliersListComponent | |||
| [user]="user" | |||
| [partnerType]="'supplier'" | |||
| > | |||
| </app-partner-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleServices [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.service' | translate)"> | |||
| <app-partner-list *ngIf="toggleServices.isOpened" #servicesListComponent | |||
| [user]="user" | |||
| [partnerType]="'service'" | |||
| > | |||
| </app-partner-list> | |||
| </app-toggle> | |||
| <app-toggle #toggleServices [headline]="(isCurrentUser ? (('user.my' | translate) + ' ') : '') + ('basic.service' | translate)"> | |||
| <app-partner-list *ngIf="toggleServices.isOpened" #servicesListComponent | |||
| [user]="user" | |||
| [partnerType]="'service'" | |||
| > | |||
| </app-partner-list> | |||
| </app-toggle> | |||
| </ng-container> | |||
| @@ -11,6 +11,7 @@ import {ProductListComponent} from "@app/_views/products/product-list/product-li | |||
| import {PartnerListComponent} from "@app/_views/partners/partner-list/partner-list.component"; | |||
| import {PostListComponent} from "@app/_views/posts/post-list/post-list.component"; | |||
| import {SaleSummaryComponent} from "@app/_views/sales/sale-summary/sale-summary.component"; | |||
| import {ActivatedRoute} from "@angular/router"; | |||
| @Component({ | |||
| selector: 'app-user-detail', | |||
| @@ -38,42 +39,43 @@ export class UserDetailComponent implements OnInit, AfterViewInit { | |||
| protected userSub: Subscription; | |||
| protected isCurrentUser: boolean; | |||
| protected userId!: string; | |||
| constructor( | |||
| private accountService: AccountService, | |||
| private userService: UserService, | |||
| protected appHelperService: AppHelperService | |||
| protected appHelperService: AppHelperService, | |||
| private route: ActivatedRoute, | |||
| ) { | |||
| this.userSub = new Subscription(); | |||
| this.isCurrentUser = false; | |||
| if (this.accountService.userValue?.userResource) { | |||
| let user = this.accountService.userValue?.userResource; | |||
| this.isCurrentUser = user?.id === user?.id; | |||
| } | |||
| } | |||
| ngOnInit() { | |||
| this.route.params.subscribe(params => { | |||
| this.userId = params['id']; | |||
| }); | |||
| console.log(this.userId); | |||
| } | |||
| ngAfterViewInit(): void { | |||
| if (this.accountService.userValue?.userResource) { | |||
| let user = this.accountService.userValue?.userResource; | |||
| this.isCurrentUser = this.userId == user?.id; | |||
| } | |||
| this.getData(); | |||
| } | |||
| getData() { | |||
| console.log(this.user); | |||
| if (this.user === undefined) { | |||
| const user = this.accountService.userValue; | |||
| if (user?.id !== null && user?.id !== undefined) { | |||
| this.userSub = this.userService.usersIdGet( | |||
| this.appHelperService.extractId(user.id) | |||
| ).subscribe( | |||
| data => { | |||
| this.user = data; | |||
| } | |||
| ); | |||
| this.userSub = this.userService.usersIdGet( | |||
| this.userId | |||
| ).subscribe( | |||
| data => { | |||
| this.user = data; | |||
| } | |||
| } | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,58 @@ | |||
| <div class="spt-container"> | |||
| <app-paging #pagingComponent | |||
| [getDataFunction]="getData" | |||
| [dataSource]="dataSource" | |||
| > | |||
| <table mat-table [dataSource]="dataSource" matSort (matSortChange)="onSortChange($event)" class="mat-elevation-z8 mb-3"> | |||
| <ng-container matColumnDef="pos"> | |||
| <th mat-header-cell *matHeaderCellDef> | |||
| {{ 'overview.number' | translate }} | |||
| </th> | |||
| <td mat-cell | |||
| *matCellDef="let element">{{ pagingComponent.getPageSize() * (pagingComponent.getPageIndex()-1) + dataSource.filteredData.indexOf(element) + 1 }} | |||
| </td> | |||
| </ng-container> | |||
| <ng-container matColumnDef="image"> | |||
| <th mat-header-cell *matHeaderCellDef> | |||
| {{ 'overview.image' | translate }} | |||
| </th> | |||
| <td mat-cell *matCellDef="let element"> | |||
| <img role="button" src="{{ element.imageUrl }}" (click)="navigateToUserDetails(element)" width="40" | |||
| height="40" /> | |||
| </td> | |||
| </ng-container> | |||
| <ng-container matColumnDef="firstName"> | |||
| <th mat-header-cell *matHeaderCellDef mat-sort-header> | |||
| {{ 'overview.firstName' | translate }} | |||
| </th> | |||
| <td mat-cell *matCellDef="let element"> | |||
| <span role="button" (click)="navigateToUserDetails(element)">{{ element.firstName }}</span> | |||
| </td> | |||
| </ng-container> | |||
| <ng-container matColumnDef="lastName"> | |||
| <th mat-header-cell *matHeaderCellDef mat-sort-header> | |||
| {{ 'overview.lastName' | translate }} | |||
| </th> | |||
| <td mat-cell *matCellDef="let element"> | |||
| <span role="button" (click)="navigateToUserDetails(element)">{{ element.lastName }}</span> | |||
| </td> | |||
| </ng-container> | |||
| <ng-container matColumnDef="email"> | |||
| <th mat-header-cell *matHeaderCellDef mat-sort-header> | |||
| {{ 'overview.email' | translate }} | |||
| </th> | |||
| <td mat-cell *matCellDef="let element"> | |||
| <span role="button" (click)="navigateToUserDetails(element)">{{ element.email }}</span> | |||
| </td> | |||
| </ng-container> | |||
| <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> | |||
| <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> | |||
| </table> | |||
| </app-paging> | |||
| </div> | |||
| @@ -0,0 +1,23 @@ | |||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||
| import { UserListComponent } from './user-list.component'; | |||
| describe('UserListComponent', () => { | |||
| let component: UserListComponent; | |||
| let fixture: ComponentFixture<UserListComponent>; | |||
| beforeEach(async () => { | |||
| await TestBed.configureTestingModule({ | |||
| declarations: [UserListComponent] | |||
| }) | |||
| .compileComponents(); | |||
| fixture = TestBed.createComponent(UserListComponent); | |||
| component = fixture.componentInstance; | |||
| fixture.detectChanges(); | |||
| }); | |||
| it('should create', () => { | |||
| expect(component).toBeTruthy(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,81 @@ | |||
| import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core'; | |||
| import {MatSort, Sort} from "@angular/material/sort"; | |||
| import {PagingComponent} from "@app/_components/paging/paging.component"; | |||
| import {Subscription} from "rxjs"; | |||
| import {UserJsonld, UserService} from "@app/core/api/v1"; | |||
| import {MatTableDataSource} from "@angular/material/table"; | |||
| import {OrderFilter} from "@app/_models/orderFilter"; | |||
| import {Router} from "@angular/router"; | |||
| import {AppHelperService} from "@app/_helpers/app-helper.service"; | |||
| @Component({ | |||
| selector: 'app-user-list', | |||
| templateUrl: './user-list.component.html', | |||
| styleUrl: './user-list.component.scss' | |||
| }) | |||
| export class UserListComponent implements OnInit, AfterViewInit { | |||
| @ViewChild(MatSort) sort; | |||
| @ViewChild("pagingComponent", { static: false }) pagingComponent!: PagingComponent; | |||
| protected usersSub: Subscription; | |||
| protected users: Array<UserJsonld>; | |||
| protected dataSource; | |||
| protected displayedColumns!: string[]; | |||
| constructor( | |||
| private userService: UserService, | |||
| private router: Router, | |||
| protected appHelperService: AppHelperService, | |||
| ) { | |||
| this.displayedColumns = ['pos', 'image', 'firstName', 'lastName', 'email']; | |||
| this.sort = new MatSort(); | |||
| this.sort = new MatSort(); | |||
| this.usersSub = new Subscription(); | |||
| this.users = []; | |||
| this.dataSource = new MatTableDataSource<UserJsonld>(this.users); | |||
| } | |||
| ngOnInit() { | |||
| } | |||
| ngAfterViewInit() { | |||
| this.dataSource.sort = this.sort; | |||
| this.dataSource.paginator = this.pagingComponent.paginator; | |||
| this.pagingComponent.getData(); | |||
| } | |||
| getData = () => { | |||
| this.usersSub = this.userService.usersGetCollection( | |||
| this.pagingComponent.getPageIndex(), | |||
| this.pagingComponent.getPageSize(), | |||
| ).subscribe( | |||
| data => { | |||
| this.users = data["hydra:member"]; | |||
| this.dataSource = new MatTableDataSource<UserJsonld>(this.users); | |||
| this.pagingComponent.dataLength = Number(data["hydra:totalItems"]); | |||
| } | |||
| ); | |||
| } | |||
| onSortChange = (sortState: Sort) => { | |||
| this.pagingComponent.resetPageIndex() | |||
| let order: OrderFilter; | |||
| if (sortState.direction === "") { | |||
| order = OrderFilter.Undefined; | |||
| } else { | |||
| order = sortState.direction; | |||
| } | |||
| this.pagingComponent.getData(); | |||
| } | |||
| navigateToUserDetails(element: any) { | |||
| const user: UserJsonld = element as UserJsonld; | |||
| this.router.navigate(['/user', this.appHelperService.extractId(user.id)]); | |||
| } | |||
| } | |||
| @@ -1,13 +1,6 @@ | |||
| <div class="spt-container"> | |||
| <div class="card"> | |||
| <div class="card-body row"> | |||
| <div class="col-4"> | |||
| <h1>{{ user.firstName }} {{ user.lastName }}</h1> | |||
| <dl> | |||
| <dt>Email:</dt> | |||
| <dd>{{ user.email }}</dd> | |||
| </dl> | |||
| </div> | |||
| </div> | |||
| <div class="d-flex justify-content-between align-items-start"> | |||
| <h2>{{ 'basic.users' | translate }}</h2> | |||
| </div> | |||
| <app-user-list></app-user-list> | |||
| </div> | |||
| @@ -16,6 +16,7 @@ import {ProfileComponent} from "@app/_views/profile/profile.component"; | |||
| import {UserDetailComponent} from "@app/_views/user/user-detail/user-detail.component"; | |||
| import {userGuard} from "@app/_guards/user.guard"; | |||
| import {adminGuard} from "@app/_guards/admin.guard"; | |||
| import {UsersComponent} from "@app/_views/user/users.component"; | |||
| const accountModule = () => import('@app/_views/account/account.module').then(x => x.AccountModule); | |||
| @@ -105,6 +106,7 @@ const routes: Routes = [ | |||
| component: TwoColumnComponent, | |||
| canActivate: [userGuard, adminGuard], | |||
| children: [ | |||
| {path: '', component: UsersComponent}, | |||
| {path: ':id', component: UserDetailComponent}, | |||
| ] | |||
| }, | |||
| @@ -60,6 +60,7 @@ import { SaleListComponent } from './_views/sales/sale-list/sale-list.component' | |||
| import { SaleSummaryComponent } from './_views/sales/sale-summary/sale-summary.component'; | |||
| import { UsersComponent } from './_views/user/users.component'; | |||
| import { UserDetailComponent } from './_views/user/user-detail/user-detail.component'; | |||
| import { UserListComponent } from './_views/user/user-list/user-list.component'; | |||
| export function apiConfigFactory(): Configuration { | |||
| @@ -143,6 +144,7 @@ export function HttpLoaderFactory(http: HttpClient) { | |||
| SaleSummaryComponent, | |||
| UsersComponent, | |||
| UserDetailComponent, | |||
| UserListComponent, | |||
| ], | |||
| providers: [ | |||
| {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}, | |||
| @@ -26,6 +26,7 @@ export interface Post { | |||
| product?: string | null; | |||
| readonly productName?: string | null; | |||
| contact?: string | null; | |||
| readonly contactName?: string | null; | |||
| sale?: string | null; | |||
| /** | |||
| * array<int, CommentApi> | |||
| @@ -28,6 +28,7 @@ export interface PostJsonhal { | |||
| product?: string | null; | |||
| readonly productName?: string | null; | |||
| contact?: string | null; | |||
| readonly contactName?: string | null; | |||
| sale?: string | null; | |||
| /** | |||
| * array<int, CommentApi> | |||
| @@ -30,6 +30,7 @@ export interface PostJsonld { | |||
| product?: string | null; | |||
| readonly productName?: string | null; | |||
| contact?: string | null; | |||
| readonly contactName?: string | null; | |||
| sale?: string | null; | |||
| /** | |||
| * array<int, CommentApi> | |||
| @@ -25,6 +25,7 @@ | |||
| "contacts": "Kontakte", | |||
| "posts": "Notizen", | |||
| "comments": "Kommentare", | |||
| "users": "Benutzer", | |||
| "new": "Neuer", | |||
| "new-product": "Neues Produkt", | |||
| "new-document": "Neues Dokument", | |||
| @@ -80,7 +81,10 @@ | |||
| "turnover": "Umsatz", | |||
| "profit": "Gewinn", | |||
| "comment": "Kommentar", | |||
| "createdAt": "erstellt am" | |||
| "createdAt": "erstellt am", | |||
| "firstName": "Vorname", | |||
| "lastName": "Vorname", | |||
| "email": "Email" | |||
| }, | |||
| "form": | |||
| { | |||