uikit / add new files

This commit is contained in:
Mehmet Çetin
2024-12-31 12:58:33 +03:00
parent f760886f54
commit 22c1cd9a3a
6 changed files with 941 additions and 4 deletions

View File

@@ -0,0 +1,58 @@
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { MessageService } from 'primeng/api';
import { ButtonModule } from 'primeng/button';
import { FileUploadModule } from 'primeng/fileupload';
import { ToastModule } from 'primeng/toast';
@Component({
standalone:true,
imports:[CommonModule, FileUploadModule,ToastModule,ButtonModule],
template: `<div class="grid grid-cols-12 gap-8">
<div class="col-span-full lg:col-span-6">
<div class="card">
<div class="font-semibold text-xl mb-4">Advanced</div>
<p-fileupload name="demo[]" (onUpload)="onUpload($event)" [multiple]="true" accept="image/*" maxFileSize="1000000" mode="advanced">
<ng-template #empty>
<div>Drag and drop files to here to upload.</div>
</ng-template>
<ng-template #content>
<ul *ngIf="uploadedFiles.length">
<li *ngFor="let file of uploadedFiles">{{ file.name }} - {{ file.size }} bytes</li>
</ul>
</ng-template>
</p-fileupload>
<div class="col-span-full lg:col-span-6">
<div class="card">
<div class="font-semibold text-xl mb-4">Basic</div>
<div class="card flex flex-col gap-6 items-center justify-center">
<p-toast />
<p-fileupload #fu mode="basic" chooseLabel="Choose" chooseIcon="pi pi-upload" name="demo[]" url="https://www.primefaces.org/cdn/api/upload.php" accept="image/*" maxFileSize="1000000" (onUpload)="onUpload($event)" />
<p-button label="Upload" (onClick)="fu.upload()" severity="secondary" />
</div>
</div>
</div>
</div>
</div>
</div>`,
providers: [MessageService]
})
export class FileDoc {
uploadedFiles: any[] = [];
constructor(private messageService: MessageService) {}
onUpload(event: any) {
for (const file of event.files) {
this.uploadedFiles.push(file);
}
this.messageService.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded' });
}
onBasicUpload() {
this.messageService.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded with Basic Mode' });
}
}

View File

@@ -169,20 +169,20 @@ import {NodeService} from "../../app/demo/service/node.service";
<div class="font-semibold text-xl">MultiSelect</div>
<p-multiselect [(ngModel)]="multiselectValue" [options]="multiselectValues" optionLabel="name" placeholder="Select Countries" [filter]="true">
<template #selecteditems let-countries>
<ng-template #selecteditems let-countries>
@for (country of countries; track country.code) {
<div class="inline-flex items-center py-1 px-2 bg-primary text-primary-contrast rounded-border mr-2">
<span [class]="'mr-2 flag flag-' + country.code.toLowerCase()" style="width: 18px; height: 12px"></span>
<div>{{ country.name }}</div>
</div>
}
</template>
<template #item let-country>
</ng-template>
<ng-template #item let-country>
<div class="flex items-center">
<span [class]="'mr-2 flag flag-' + country.option.code.toLowerCase()" style="width: 18px; height: 12px"></span>
<div>{{ country.option.name }}</div>
</div>
</template>
</ng-template>
</p-multiselect>
<div class="font-semibold text-xl">TreeSelect</div>

132
src/views/uikit/mediadoc.ts Normal file
View File

@@ -0,0 +1,132 @@
import { Product } from '@/src/app/demo/api/product';
import { PhotoService } from '@/src/app/demo/service/photo.service';
import { ProductService } from '@/src/app/demo/service/product.service';
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { ButtonModule } from 'primeng/button';
import { CarouselModule } from 'primeng/carousel';
import { GalleriaModule } from 'primeng/galleria';
import { ImageModule } from 'primeng/image';
import { TagModule } from 'primeng/tag';
@Component({
standalone:true,
imports:[CommonModule, CarouselModule,ButtonModule,GalleriaModule, ImageModule, TagModule],
template: `<div class="grid p-fluid">
<div class="col-12">
<div class="card">
<h5>Carousel</h5>
<p-carousel [value]="products" [numVisible]="3" [numScroll]="3" [circular]="false" [responsiveOptions]="carouselResponsiveOptions">
<ng-template let-product #item>
<div class="border border-surface rounded-border m-2 p-4">
<div class="mb-4">
<div class="relative mx-auto">
<img src="assets/demo/images/product/{{product.image}}" [alt]="product.name" class="shadow-4" width="50%"/>
<p-tag [value]="product.inventoryStatus" [severity]="getSeverity(product.inventoryStatus)" class="absolute" styleClass="dark:!bg-surface-900" [ngStyle]="{ 'left.px': 5, 'top.px': 5 }" />
</div>
</div>
<div class="mb-4 font-medium">{{ product.name }}</div>
<div class="flex justify-between items-center">
<div class="mt-0 font-semibold text-xl">{{ '$' + product.price }}</div>
<span>
<p-button icon="pi pi-heart" severity="secondary" [outlined]="true" />
<p-button icon="pi pi-shopping-cart" styleClass="ml-2" />
</span>
</div>
</div>
</ng-template>
</p-carousel>
</div>
</div>
<div class="col-12">
<div class="card">
<h5>Image</h5>
<div class="flex justify-content-center">
<p-image src="assets/demo/images/galleria/galleria10.jpg" alt="Image" width="250" [preview]="true"></p-image>
</div>
</div>
</div>
<div class="col-12">
<div class="card">
<h5>Galleria</h5>
<p-galleria [value]="images" [responsiveOptions]="galleriaResponsiveOptions" [containerStyle]="{ 'max-width': '640px' }" [numVisible]="5">
<ng-template #item let-item>
<img [src]="item.itemImageSrc" style="width:100%" />
</ng-template>
<ng-template #thumbnail let-item>
<img [src]="item.thumbnailImageSrc" />
</ng-template>
</p-galleria>
</div>
</div>
</div>`,
})
export class MediaDoc implements OnInit {
products!: Product[];
images!: any[];
galleriaResponsiveOptions: any[] = [
{
breakpoint: '1024px',
numVisible: 5
},
{
breakpoint: '960px',
numVisible: 4
},
{
breakpoint: '768px',
numVisible: 3
},
{
breakpoint: '560px',
numVisible: 1
}
];
carouselResponsiveOptions: any[] = [
{
breakpoint: '1024px',
numVisible: 3,
numScroll: 3
},
{
breakpoint: '768px',
numVisible: 2,
numScroll: 2
},
{
breakpoint: '560px',
numVisible: 1,
numScroll: 1
}
];
constructor(private productService: ProductService, private photoService: PhotoService) { }
ngOnInit() {
this.productService.getProductsSmall().then(products => {
this.products = products;
});
this.photoService.getImages().then(images => {
this.images = images;
});
}
getSeverity(status: string) {
switch (status) {
case 'INSTOCK':
return 'success';
case 'LOWSTOCK':
return 'warn';
case 'OUTOFSTOCK':
return 'danger';
}
}
}

View File

@@ -0,0 +1,100 @@
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import {MessageService } from 'primeng/api';
import { ButtonModule } from 'primeng/button';
import { InputTextModule } from 'primeng/inputtext';
import { ToastModule } from 'primeng/toast';
import { MessageModule } from 'primeng/message';
import { FormsModule } from '@angular/forms';
@Component({
standalone: true,
imports:[CommonModule,ToastModule,ButtonModule,InputTextModule,MessageModule,FormsModule],
template:`
<div class="flex flex-col md:flex-row gap-8">
<div class="md:w-1/2">
<div class="card">
<div class="font-semibold text-xl mb-4">Toast</div>
<div class="flex flex-wrap gap-2">
<p-button (click)="showSuccessViaToast()" label="Success" severity="success" />
<p-button (click)="showInfoViaToast()" label="Info" severity="info" />
<p-button (click)="showWarnViaToast()" label="Warn" severity="warn" />
<p-button (click)="showErrorViaToast()" label="Error" severity="danger" />
</div>
<div class="font-semibold text-xl mt-4 mb-4">Inline</div>
<div class="flex flex-wrap mb-4 gap-2">
<input pInputText [(ngModel)]="username" placeholder="Username" aria-label="username" class="ng-dirty ng-invalid"/>
<p-message severity="error">Username is required</p-message>
</div>
<div class="flex flex-wrap gap-2">
<input pInputText [(ngModel)]="email" placeholder="Email" aria-label="email" class="ng-dirty ng-invalid" />
<p-message severity="error" icon="pi pi-times-circle" />
</div>
</div>
</div>
<div class="md:w-1/2">
<div class="card">
<div class="font-semibold text-xl mb-4">Message</div>
<div class="flex flex-col gap-4 mb-4">
<p-message severity="success">Success Message</p-message>
<p-message severity="info">Info Message</p-message>
<p-message severity="warn">Warn Message</p-message>
<p-message severity="error">Error Message</p-message>
<p-message severity="secondary">Secondary Message</p-message>
<p-message severity="contrast">Contrast Message</p-message>
</div>
<!-- <p-message *ngFor="let msg of message" [severity]="msg.severity">{{ msg.content }}</p-message> -->
</div>
</div>
</div>
`,
providers: [MessageService]
})
export class MessagesDoc {
msgs = [];
username: string | undefined
email: string | undefined
constructor(private service: MessageService) { }
showInfoViaToast() {
this.service.add({ key: 'tst', severity: 'info', summary: 'Info Message', detail: 'PrimeNG rocks' });
}
showWarnViaToast() {
this.service.add({ key: 'tst', severity: 'warn', summary: 'Warn Message', detail: 'There are unsaved changes' });
}
showErrorViaToast() {
this.service.add({ key: 'tst', severity: 'error', summary: 'Error Message', detail: 'Validation failed' });
}
showSuccessViaToast() {
this.service.add({ key: 'tst', severity: 'success', summary: 'Success Message', detail: 'Message sent' });
}
showInfoViaMessages() {
this.msgs = [];
this.msgs.push({ severity: 'info', summary: 'Info Message', detail: 'PrimeNG rocks' });
}
showWarnViaMessages() {
this.msgs = [];
this.msgs.push({ severity: 'warn', summary: 'Warn Message', detail: 'There are unsaved changes' });
}
showErrorViaMessages() {
this.msgs = [];
this.msgs.push({ severity: 'error', summary: 'Error Message', detail: 'Validation failed' });
}
showSuccessViaMessages() {
this.msgs = [];
this.msgs.push({ severity: 'success', summary: 'Success Message', detail: 'Message sent' });
}
}

View File

@@ -0,0 +1,191 @@
import { Product } from '@/src/app/demo/api/product';
import { ProductService } from '@/src/app/demo/service/product.service';
import { Component, OnInit } from '@angular/core';
import { ConfirmationService, MessageService } from 'primeng/api';
import { ButtonModule } from 'primeng/button';
import { DialogModule } from 'primeng/dialog';
import { ToastModule } from 'primeng/toast';
import { DrawerModule } from 'primeng/drawer';
import { PopoverModule } from 'primeng/popover';
import { ConfirmPopupModule } from 'primeng/confirmpopup';
@Component({
standalone: true,
imports:[ToastModule,DialogModule,ButtonModule,DrawerModule, PopoverModule, ConfirmPopupModule],
template:`
<div class="flex flex-col md:flex-row gap-8">
<div class="md:w-1/2">
<div class="card">
<div class="font-semibold text-xl mb-4">Dialog</div>
<p-dialog header="Dialog" [(visible)]="display" [breakpoints]="{ '960px': '75vw' }" [style]="{ width: '30vw' }" [modal]="true">
<p class="leading-normal m-0">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<ng-template #footer>
<p-button label="Save" (click)="close()" />
</ng-template>
</p-dialog>
<p-button label="Show" [style]="{width: 'auto'}" (click)="open()" />
</div>
<div class="card">
<div class="font-semibold text-xl mb-4">Popover</div>
<div class="flex flex-wrap gap-2">
<p-button type="button" label="Show" (click)="toggleDataTable()" />
<p-popover ref="op2" id="overlay_panel" [style]="{width: '450px'}">
<!-- TABLE -->
</p-popover>
</div>
</div>
<div class="card">
<div class="font-semibold text-xl mb-4">Tooltip</div>
<div class="inline-flex gap-4">
<input pInputText type="text" placeholder="Username" pTooltip="Your username" />
<p-button type="button" label="Save" pTooltip="Click to proceed" />
</div>
</div>
</div>
<div class="md:w-1/2">
<div class="card">
<div class="font-semibold text-xl mb-4">Drawer</div>
<p-drawer [(visible)]="visibleLeft" header="Drawer">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
</p>
</p-drawer>
<p-drawer [(visible)]="visibleRight" header="Drawer" position="right">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
</p>
</p-drawer>
<p-drawer [(visible)]="visibleTop" header="Drawer" position="top">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
</p>
</p-drawer>
<p-drawer [(visible)]="visibleBottom" header="Drawer" position="bottom">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
</p>
</p-drawer>
<p-drawer [(visible)]="visibleFull" header="Drawer" position="full">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
</p>
</p-drawer>
<p-button icon="pi pi-arrow-right" (click)="visibleLeft = true" [style]="{marginRight: '0.25em'}" />
<p-button icon="pi pi-arrow-left" (click)="visibleRight = true" [style]="{marginRight: '0.25em'}" />
<p-button icon="pi pi-arrow-down" (click)="visibleTop = true" [style]="{marginRight: '0.25em'}" />
<p-button icon="pi pi-arrow-up" (click)="visibleBottom = true" [style]="{marginRight: '0.25em'}" />
<p-button icon="pi pi-external-link" (click)="visibleFull = true" />
</div>
<div class="card">
<div class="font-semibold text-xl mb-4">ConfirmPopup</div>
<p-confirmpopup></p-confirmpopup>
<p-button ref="popup" (click)="confirm($event)" icon="pi pi-check" label="Confirm" class="mr-2"></p-button>
</div>
<div class="card">
<div class="font-semibold text-xl mb-4">ConfirmDialog</div>
<p-button label="Delete" icon="pi pi-trash" severity="danger" [style]="{ width: 'auto' }" (click)="openConfirmation()" />
<p-dialog header="Confirmation" [(visible)]="displayConfirmation" [style]="{ width: '350px' }" [modal]="true">
<div class="flex items-center justify-center">
<i class="pi pi-exclamation-triangle mr-4" style="font-size: 2rem" > </i>
<span>Are you sure you want to proceed?</span>
</div>
<ng-template #footer>
<p-button label="No" icon="pi pi-times" (click)="closeConfirmation()" text severity="secondary" />
<p-button label="Yes" icon="pi pi-check" (click)="closeConfirmation()" severity="danger" outlined autofocus />
</ng-template>
</p-dialog>
</div>
</div>
</div>`,
providers: [ConfirmationService, MessageService]
})
export class OverlayDoc implements OnInit {
images: any[] = [];
display: boolean = false;
products: Product[] = [];
selectedProduct: Product = {};
visibleLeft: boolean = false;
visibleRight: boolean = false;
visibleTop: boolean = false;
visibleBottom: boolean = false;
visibleFull: boolean = false;
displayConfirmation: boolean = false;
constructor(private productService: ProductService, private confirmationService: ConfirmationService, private messageService: MessageService) { }
ngOnInit() {
this.productService.getProductsSmall().then(products => this.products = products);
this.images = [];
this.images.push({
source: 'assets/demo/images/sopranos/sopranos1.jpg',
thumbnail: 'assets/demo/images/sopranos/sopranos1_small.jpg', title: 'Sopranos 1'
});
this.images.push({
source: 'assets/demo/images/sopranos/sopranos2.jpg',
thumbnail: 'assets/demo/images/sopranos/sopranos2_small.jpg', title: 'Sopranos 2'
});
this.images.push({
source: 'assets/demo/images/sopranos/sopranos3.jpg',
thumbnail: 'assets/demo/images/sopranos/sopranos3_small.jpg', title: 'Sopranos 3'
});
this.images.push({
source: 'assets/demo/images/sopranos/sopranos4.jpg',
thumbnail: 'assets/demo/images/sopranos/sopranos4_small.jpg', title: 'Sopranos 4'
});
}
confirm1() {
this.confirmationService.confirm({
key: 'confirm1',
message: 'Are you sure to perform this action?'
});
}
confirm2(event: Event) {
this.confirmationService.confirm({
key: 'confirm2',
target: event.target || new EventTarget,
message: 'Are you sure that you want to proceed?',
icon: 'pi pi-exclamation-triangle',
accept: () => {
this.messageService.add({ severity: 'info', summary: 'Confirmed', detail: 'You have accepted' });
},
reject: () => {
this.messageService.add({ severity: 'error', summary: 'Rejected', detail: 'You have rejected' });
}
});
}
formatCurrency(value: number) {
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
}
}

456
src/views/uikit/tabledoc.ts Normal file
View File

@@ -0,0 +1,456 @@
import { Product } from '@/src/app/demo/api/product';
import { ProductService } from '@/src/app/demo/service/product.service';
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { ConfirmationService, MessageService } from 'primeng/api';
import { InputTextModule } from 'primeng/inputtext';
import { MultiSelectModule } from 'primeng/multiselect';
import { SelectModule } from 'primeng/select';
import { SliderModule } from 'primeng/slider';
import { Table, TableModule } from 'primeng/table';
import { ProgressBarModule } from 'primeng/progressbar';
import { ToggleButtonModule } from 'primeng/togglebutton';
import { ToastModule } from 'primeng/toast';
import { Customer, Representative } from '@/src/app/demo/api/customer';
import { CustomerService } from '@/src/app/demo/service/customer.service';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ButtonModule } from 'primeng/button';
import { RatingModule } from 'primeng/rating';
interface expandedRows {
[key: string]: boolean;
}
@Component({
standalone: true,
imports:[TableModule, MultiSelectModule, SelectModule, InputTextModule, SliderModule,ProgressBarModule,ToggleButtonModule,ToastModule, CommonModule, FormsModule,ButtonModule,RatingModule],
template:`
<div class="grid">
<div class="col-12">
<div class="card">
<h5>Filter Menu</h5>
<p-table #dt1 [value]="customers1" dataKey="id" [rows]="10" [loading]="loading" [rowHover]="true" styleClass="p-datatable-gridlines" [paginator]="true" [globalFilterFields]="['name','country.name','representative.name','status']" responsiveLayout="scroll">
<ng-template pTemplate="caption">
<div class="flex justify-content-between flex-column sm:flex-row">
<button pButton label="Clear" class="p-button-outlined mb-2" icon="pi pi-filter-slash" (click)="clear(dt1)"></button>
<span class="p-input-icon-left mb-2">
<i class="pi pi-search"></i>
<input pInputText type="text" #filter (input)="onGlobalFilter(dt1, $event)" placeholder="Search Keyword" class="w-full"/>
</span>
</div>
</ng-template>
<ng-template #header>
<tr>
<th style="min-width: 12rem">
<div class="flex justify-content-between align-items-center">
Name
<p-columnFilter type="text" field="name" display="menu" placeholder="Search by name"></p-columnFilter>
</div>
</th>
<th style="min-width: 12rem">
<div class="flex justify-content-between align-items-center">
Country
<p-columnFilter type="text" field="country.name" display="menu" placeholder="Search by country"></p-columnFilter>
</div>
</th>
<th style="min-width: 14rem">
<div class="flex justify-content-between align-items-center">
Agent
<p-columnFilter field="representative" matchMode="in" display="menu" [showMatchModes]="false" [showOperator]="false" [showAddButton]="false">
<ng-template #header>
<div class="px-3 pt-3 pb-0">
<span class="font-bold">Agent Picker</span>
</div>
</ng-template>
<ng-template #filter let-value let-filter="filterCallback">
<p-multiselect [ngModel]="value" [options]="representatives" placeholder="Any" (onChange)="filter($event.value)" optionLabel="name">
<ng-template let-option #item>
<div class="p-multiselect-representative-option">
<img [alt]="option.label" src="assets/demo/images/avatar/{{option.image}}" width="32" style="vertical-align: middle" />
<span class="ml-2">{{option.name}}</span>
</div>
</ng-template>
</p-multiselect>
</ng-template>
</p-columnFilter>
</div>
</th>
<th style="min-width: 10rem">
<div class="flex justify-content-between align-items-center">
Date
<p-columnFilter type="date" field="date" display="menu" placeholder="mm/dd/yyyy"></p-columnFilter>
</div>
</th>
<th style="min-width: 10rem">
<div class="flex justify-content-between align-items-center">
Balance
<p-columnFilter type="numeric" field="balance" display="menu" currency="USD"></p-columnFilter>
</div>
</th>
<th style="min-width: 12rem">
<div class="flex justify-content-between align-items-center">
Status
<p-columnFilter field="status" matchMode="equals" display="menu">
<ng-template #filter let-value let-filter="filterCallback">
<p-select [ngModel]="value" [options]="statuses" (onChange)="filter($event.value)" placeholder="Any" [style]="{'min-width': '12rem'}" >
<ng-template let-option #item>
<span [class]="'customer-badge status-' + option.value">{{option.label}}</span>
</ng-template>
</p-select>
</ng-template>
</p-columnFilter>
</div>
</th>
<th style="min-width: 12rem">
<div class="flex justify-content-between align-items-center">
Activity
<p-columnFilter field="activity" matchMode="between" display="menu" [showMatchModes]="false" [showOperator]="false" [showAddButton]="false">
<ng-template #filter let-filter="filterCallback">
<p-slider [ngModel]="activityValues" [range]="true" (onSlideEnd)="filter($event.values)" styleClass="m-3" [style]="{'min-width': '12rem'}" ></p-slider>
<div class="flex align-items-center justify-content-between px-2">
<span>{{activityValues[0]}}</span>
<span>{{activityValues[1]}}</span>
</div>
</ng-template>
</p-columnFilter>
</div>
</th>
<th style="min-width: 8rem">
<div class="flex justify-content-between align-items-center">
Verified
<p-columnFilter type="boolean" field="verified" display="menu"></p-columnFilter>
</div>
</th>
</tr>
</ng-template>
<ng-template #body let-customer>
<tr>
<td>
{{customer.name}}
</td>
<td>
<img src="assets/demo/images/flag/flag_placeholder.png" [class]="'flag flag-' + customer.country.code" width="30">
<span class="image-text ml-2">{{customer.country.name}}</span>
</td>
<td>
<img [alt]="customer.representative.name" src="assets/demo/images/avatar/{{customer.representative.image}}" width="32" style="vertical-align: middle"/>
<span class="image-text ml-2">{{customer.representative.name}}</span>
</td>
<td>
{{customer.date | date: 'MM/dd/yyyy'}}
</td>
<td>
{{customer.balance | currency:'USD':'symbol'}}
</td>
<td>
<span [class]="'customer-badge status-' + customer.status">{{customer.status}}</span>
</td>
<td>
<p-progressbar [value]="customer.activity" [showValue]="false" [style]="{'height': '0.5rem'}" />
</td>
<td class="text-center">
<i class="pi" [ngClass]="{'true-icon pi-check-circle text-green-500': customer.verified, 'false-icon pi-times-circle text-pink-500': !customer.verified}"></i>
</td>
</tr>
</ng-template>
<ng-template #emptymessage>
<tr>
<td colspan="8">No customers found.</td>
</tr>
</ng-template>
<ng-template #loadingbody>
<tr>
<td colspan="8">Loading customers data. Please wait.</td>
</tr>
</ng-template>
</p-table>
</div>
</div>
<div class="col-12">
<div class="card">
<h5>Frozen Columns</h5>
<p-togglebutton [(ngModel)]="idFrozen" [onIcon]="'pi pi-lock'" offIcon="pi pi-lock-open" [onLabel]="'Unfreeze Id'" offLabel="Freeze Id" [style]="{'width': '12rem'}"></p-togglebutton>
<p-table [value]="customers3" scrollDirection="both" [scrollable]="true" scrollHeight="400px" styleClass="mt-3" responsiveLayout="scroll">
<ng-template pTemplate="header">
<tr>
<th style="width:200px" pFrozenColumn>Name</th>
<th style="width:200px" alignFrozen="left" pFrozenColumn [frozen]="idFrozen">Id</th>
<th style="width:200px">Country</th>
<th style="width:200px">Date</th>
<th style="width:200px">Company</th>
<th style="width:200px">Status</th>
<th style="width:200px">Activity</th>
<th style="width:200px">Representative</th>
<th style="width:200px" pFrozenColumn alignFrozen="right">Balance</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-customer>
<tr>
<td style="width:200px" pFrozenColumn class="font-bold">{{customer.name}}</td>
<td style="width:200px" alignFrozen="left" pFrozenColumn [frozen]="idFrozen" [ngClass]="{'font-bold': idFrozen}">{{customer.id}}</td>
<td style="width:200px">
<img src="assets/demo/images/flag/flag_placeholder.png" [class]="'flag flag-' + customer.country.code" width="30">
<span class="image-text ml-2">{{customer.country.name}}</span>
</td>
<td style="width:200px">{{customer.date}}</td>
<td style="width:200px">{{customer.company}}</td>
<td style="width:200px">
<span [class]="'customer-badge status-' + customer.status">{{customer.status}}</span>
</td>
<td style="width:200px">{{customer.activity}}</td>
<td style="width:200px">
<img [alt]="customer.representative.name" src="assets/demo/images/avatar/{{customer.representative.image}}" width="32" style="vertical-align: middle"/>
<span class="image-text ml-2">{{customer.representative.name}}</span>
</td>
<td style="width:200px" pFrozenColumn class="font-bold" alignFrozen="right">{{formatCurrency(customer.balance)}}</td>
</tr>
</ng-template>
</p-table>
</div>
</div>
<div class="col-12">
<div class="card">
<h5>Row Expand</h5>
<p-toast></p-toast>
<p-table [value]="products" dataKey="name" [expandedRowKeys]="expandedRows" responsiveLayout="scroll">
<ng-template #caption>
<button pButton icon="pi pi-fw {{isExpanded ? 'pi-minus' : 'pi-plus'}}" label="{{isExpanded ? 'Collapse All' : 'Expand All'}}" (click)="expandAll()"></button>
<div class="flex table-header">
</div>
</ng-template>
<ng-template #header>
<tr>
<th style="width: 3rem"></th>
<th pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th>
<th>Image</th>
<th pSortableColumn="price">Price <p-sortIcon field="price"></p-sortIcon></th>
<th pSortableColumn="category">Category <p-sortIcon field="category"></p-sortIcon></th>
<th pSortableColumn="rating">Reviews <p-sortIcon field="rating"></p-sortIcon></th>
<th pSortableColumn="inventoryStatus">Status <p-sortIcon field="inventoryStatus"></p-sortIcon></th>
</tr>
</ng-template>
<ng-template #body let-product let-expanded="expanded">
<tr>
<td>
<button type="button" pButton pRipple [pRowToggler]="product" class="p-button-text p-button-rounded p-button-plain" [icon]="expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'"></button>
</td>
<td style="min-width: 12rem;">{{product.name}}</td>
<td><img [src]="'assets/demo/images/product/' + product.image" [alt]="product.name" width="100" class="shadow-4" /></td>
<td style="min-width: 8rem;">{{product.price | currency:'USD'}}</td>
<td style="min-width: 10rem;">{{product.category}}</td>
<td style="min-width: 10rem;"><p-rating [ngModel]="product.rating" [readonly]="true"></p-rating></td>
<td><span [class]="'product-badge status-' + product.inventoryStatus.toLowerCase()">{{product.inventoryStatus}}</span></td>
</tr>
</ng-template>
<ng-template #rowexpansion let-product>
<tr>
<td colspan="7">
<div class="p-3">
<p-table [value]="product.orders" dataKey="id" responsiveLayout="scroll">
<ng-template pTemplate="header">
<tr>
<th pSortableColumn="id">Id <p-sortIcon field="price"></p-sortIcon></th>
<th pSortableColumn="customer">Customer <p-sortIcon field="customer"></p-sortIcon></th>
<th pSortableColumn="date">Date <p-sortIcon field="date"></p-sortIcon></th>
<th pSortableColumn="amount">Amount <p-sortIcon field="amount"></p-sortIcon></th>
<th pSortableColumn="stats">Status <p-sortIcon field="status"></p-sortIcon></th>
<th style="width: 4rem"></th>
</tr>
</ng-template>
<ng-template #body let-order>
<tr>
<td>{{order.id}}</td>
<td>{{order.customer}}</td>
<td>{{order.date}}</td>
<td>{{order.amount | currency:'USD'}}</td>
<td><span [class]="'order-badge order-' + order.status.toLowerCase()">{{order.status}}</span></td>
<td><p-button type="button" icon="pi pi-search"></p-button></td>
</tr>
</ng-template>
<ng-template #emptymessage>
<tr>
<td colspan="6">There are no order for this product yet.</td>
</tr>
</ng-template>
</p-table>
</div>
</td>
</tr>
</ng-template>
</p-table>
</div>
</div>
<div class="col-12">
<div class="card">
<h5>Subheader Grouping</h5>
<p-table [value]="customers3" rowGroupMode="subheader" groupRowsBy="representative.name" sortField="representative.name" sortMode="single" (onSort)="onSort()" responsiveLayout="scroll" [scrollable]="true" scrollHeight="400px">
<ng-template #header>
<tr>
<th>Name</th>
<th>Country</th>
<th>Company</th>
<th>Status</th>
<th>Date</th>
</tr>
</ng-template>
<ng-template #body let-customer let-rowIndex="rowIndex">
<tr pRowGroupHeader *ngIf="rowGroupMetadata[customer.representative.name].index === rowIndex">
<td colspan="5" style="min-width: 200px;">
<img [alt]="customer.representative.name" src="assets/demo/images/avatar/{{customer.representative.image}}" width="32" style="vertical-align: middle" />
<span class="font-bold ml-2">{{customer.representative.name}}</span>
</td>
</tr>
<tr>
<td style="min-width: 200px;">
{{customer.name}}
</td>
<td style="min-width: 200px;">
<img src="assets/demo/images/flag/flag_placeholder.png" [class]="'flag flag-' + customer.country.code" width="30">
<span class="image-text" style="margin-left: .5em">{{customer.country.name}}</span>
</td>
<td style="min-width: 200px;">
{{customer.company}}
</td>
<td style="min-width: 200px;">
<span [class]="'customer-badge status-' + customer.status">{{customer.status}}</span>
</td>
<td style="min-width: 200px;">
{{customer.date}}
</td>
</tr>
</ng-template>
</p-table>
</div>
</div>
</div>
`,
providers: [ConfirmationService, MessageService]
})
export class TableDoc implements OnInit {
customers1: Customer[] = [];
customers2: Customer[] = [];
customers3: Customer[] = [];
selectedCustomers1: Customer[] = [];
selectedCustomer: Customer = {};
representatives: Representative[] = [];
statuses: any[] = [];
products: Product[] = [];
rowGroupMetadata: any;
expandedRows: expandedRows = {};
activityValues: number[] = [0, 100];
isExpanded: boolean = false;
idFrozen: boolean = false;
loading: boolean = true;
@ViewChild('filter') filter!: ElementRef;
constructor(private customerService: CustomerService, private productService: ProductService) { }
ngOnInit() {
this.customerService.getCustomersLarge().then(customers => {
this.customers1 = customers;
this.loading = false;
// @ts-ignore
this.customers1.forEach(customer => customer.date = new Date(customer.date));
});
this.customerService.getCustomersMedium().then(customers => this.customers2 = customers);
this.customerService.getCustomersLarge().then(customers => this.customers3 = customers);
this.productService.getProductsWithOrdersSmall().then(data => this.products = data);
this.representatives = [
{ name: 'Amy Elsner', image: 'amyelsner.png' },
{ name: 'Anna Fali', image: 'annafali.png' },
{ name: 'Asiya Javayant', image: 'asiyajavayant.png' },
{ name: 'Bernardo Dominic', image: 'bernardodominic.png' },
{ name: 'Elwin Sharvill', image: 'elwinsharvill.png' },
{ name: 'Ioni Bowcher', image: 'ionibowcher.png' },
{ name: 'Ivan Magalhaes', image: 'ivanmagalhaes.png' },
{ name: 'Onyama Limba', image: 'onyamalimba.png' },
{ name: 'Stephen Shaw', image: 'stephenshaw.png' },
{ name: 'XuXue Feng', image: 'xuxuefeng.png' }
];
this.statuses = [
{ label: 'Unqualified', value: 'unqualified' },
{ label: 'Qualified', value: 'qualified' },
{ label: 'New', value: 'new' },
{ label: 'Negotiation', value: 'negotiation' },
{ label: 'Renewal', value: 'renewal' },
{ label: 'Proposal', value: 'proposal' }
];
}
onSort() {
this.updateRowGroupMetaData();
}
updateRowGroupMetaData() {
this.rowGroupMetadata = {};
if (this.customers3) {
for (let i = 0; i < this.customers3.length; i++) {
const rowData = this.customers3[i];
const representativeName = rowData?.representative?.name || '';
if (i === 0) {
this.rowGroupMetadata[representativeName] = { index: 0, size: 1 };
}
else {
const previousRowData = this.customers3[i - 1];
const previousRowGroup = previousRowData?.representative?.name;
if (representativeName === previousRowGroup) {
this.rowGroupMetadata[representativeName].size++;
}
else {
this.rowGroupMetadata[representativeName] = { index: i, size: 1 };
}
}
}
}
}
expandAll() {
if (!this.isExpanded) {
this.products.forEach(product => product && product.name ? this.expandedRows[product.name] = true : '');
} else {
this.expandedRows = {};
}
this.isExpanded = !this.isExpanded;
}
formatCurrency(value: number) {
return value.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
}
onGlobalFilter(table: Table, event: Event) {
table.filterGlobal((event.target as HTMLInputElement).value, 'contains');
}
clear(table: Table) {
table.clear();
this.filter.nativeElement.value = '';
}
}