Merge remote-tracking branch 'origin/v19' into v19

# Conflicts:
#	src/layout/applayout.ts
This commit is contained in:
Çetin
2025-01-07 11:41:11 +03:00
7 changed files with 199 additions and 182 deletions

View File

@@ -1,5 +1,4 @@
import { Component, Renderer2, ViewChild } from '@angular/core'; import { Component, Renderer2, ViewChild } from '@angular/core';
import { ToastModule } from 'primeng/toast';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { AppTopBar } from '@/src/layout/apptopbar'; import { AppTopBar } from '@/src/layout/apptopbar';
import { AppSidebar } from '@/src/layout/appsidebar'; import { AppSidebar } from '@/src/layout/appsidebar';
@@ -11,12 +10,10 @@ import { LayoutService } from '@/src/service/layout/layout.service';
@Component({ @Component({
selector: 'app-layout', selector: 'app-layout',
standalone: true, standalone: true,
imports: [CommonModule, ToastModule, AppTopBar, AppSidebar, RouterModule, AppFooter], imports: [CommonModule, AppTopBar, AppSidebar, RouterModule, AppFooter],
template: `<div class="layout-wrapper" [ngClass]="containerClass"> template: `<div class="layout-wrapper" [ngClass]="containerClass">
<app-topbar></app-topbar> <app-topbar></app-topbar>
<div class="layout-sidebar">
<app-sidebar></app-sidebar> <app-sidebar></app-sidebar>
</div>
<div class="layout-main-container"> <div class="layout-main-container">
<div class="layout-main"> <div class="layout-main">
<router-outlet></router-outlet> <router-outlet></router-outlet>
@@ -51,20 +48,6 @@ export class AppLayout {
}); });
} }
if (!this.profileMenuOutsideClickListener) {
this.profileMenuOutsideClickListener = this.renderer.listen('document', 'click', (event) => {
const isOutsideClicked = !(
this.appTopBar.menu.nativeElement.isSameNode(event.target) ||
this.appTopBar.menu.nativeElement.contains(event.target) ||
this.appTopBar.topbarMenuButton.nativeElement.isSameNode(event.target) ||
this.appTopBar.topbarMenuButton.nativeElement.contains(event.target)
);
if (isOutsideClicked) {
}
});
}
if (this.layoutService.layoutState().staticMenuMobileActive) { if (this.layoutService.layoutState().staticMenuMobileActive) {
this.blockBodyScroll(); this.blockBodyScroll();
} }
@@ -75,11 +58,12 @@ export class AppLayout {
}); });
} }
isOutsideClicked(event) { isOutsideClicked(event: MouseEvent) {
const sidebarEl = document.querySelector('.layout-sidebar'); const sidebarEl = document.querySelector('.layout-sidebar');
const topbarEl = document.querySelector('.layout-menu-button'); const topbarEl = document.querySelector('.layout-menu-button');
const eventTarget = event.target as Node;
return !(sidebarEl.isSameNode(event.target) || sidebarEl.contains(event.target) || topbarEl.isSameNode(event.target) || topbarEl.contains(event.target)); return !(sidebarEl.isSameNode(eventTarget) || sidebarEl.contains(eventTarget) || topbarEl.isSameNode(eventTarget) || topbarEl.contains(eventTarget));
} }
hideMenu() { hideMenu() {

View File

@@ -44,7 +44,6 @@ import { LayoutService } from '@/src/service/layout/layout.service';
</button> </button>
<div class="relative"> <div class="relative">
<button <button
#menubutton
class="layout-topbar-action layout-topbar-action-highlight" class="layout-topbar-action layout-topbar-action-highlight"
pStyleClass="@next" pStyleClass="@next"
enterFromClass="hidden" enterFromClass="hidden"
@@ -60,7 +59,6 @@ import { LayoutService } from '@/src/service/layout/layout.service';
</div> </div>
<button <button
#topbarmenubutton
class="layout-topbar-menu-button layout-topbar-action" class="layout-topbar-menu-button layout-topbar-action"
pStyleClass="@next" pStyleClass="@next"
enterFromClass="hidden" enterFromClass="hidden"
@@ -72,7 +70,7 @@ import { LayoutService } from '@/src/service/layout/layout.service';
<i class="pi pi-ellipsis-v"></i> <i class="pi pi-ellipsis-v"></i>
</button> </button>
<div #topbarmenu class="layout-topbar-menu hidden lg:block"> <div class="layout-topbar-menu hidden lg:block">
<div class="layout-topbar-menu-content"> <div class="layout-topbar-menu-content">
<button type="button" class="layout-topbar-action"> <button type="button" class="layout-topbar-action">
<i class="pi pi-calendar"></i> <i class="pi pi-calendar"></i>
@@ -92,17 +90,13 @@ import { LayoutService } from '@/src/service/layout/layout.service';
</div>` </div>`
}) })
export class AppTopBar { export class AppTopBar {
items!: MenuItem[]; items!: MenuItem[];
@ViewChild('menubutton') menuButton!: ElementRef;
@ViewChild('topbarmenubutton') topbarMenuButton!: ElementRef;
@ViewChild('topbarmenu') menu!: ElementRef;
constructor(public layoutService: LayoutService) {} constructor(public layoutService: LayoutService) {}
toggleDarkMode() { toggleDarkMode() {
this.layoutService.layoutConfig.update((state) => ({ ...state, darkTheme: !state.darkTheme })); this.layoutService.layoutConfig.update((state) => ({ ...state, darkTheme: !state.darkTheme }));
} }
} }

View File

@@ -1,5 +1,4 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { DataViewModule } from 'primeng/dataview'; import { DataViewModule } from 'primeng/dataview';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';

View File

@@ -51,10 +51,9 @@ import { PhotoService } from '@/src/service/demo/photo.service';
</ng-template> </ng-template>
</p-galleria> </p-galleria>
</div>`, </div>`,
providers: [ProductService, PhotoService], providers: [ProductService, PhotoService]
}) })
export class MediaDoc implements OnInit { export class MediaDoc implements OnInit {
products!: Product[]; products!: Product[];
images!: any[]; images!: any[];
@@ -96,14 +95,17 @@ export class MediaDoc implements OnInit {
} }
]; ];
constructor(private productService: ProductService, private photoService: PhotoService) { } constructor(
private productService: ProductService,
private photoService: PhotoService
) {}
ngOnInit() { ngOnInit() {
this.productService.getProductsSmall().then(products => { this.productService.getProductsSmall().then((products) => {
this.products = products; this.products = products;
}); });
this.photoService.getImages().then(images => { this.photoService.getImages().then((images) => {
this.images = images; this.images = images;
}); });
} }
@@ -120,5 +122,4 @@ export class MediaDoc implements OnInit {
return 'success'; return 'success';
} }
} }
} }

View File

@@ -14,10 +14,28 @@ import { StepperModule } from 'primeng/stepper';
import { IconField, IconFieldModule } from 'primeng/iconfield'; import { IconField, IconFieldModule } from 'primeng/iconfield';
import { InputIcon, InputIconModule } from 'primeng/inputicon'; import { InputIcon, InputIconModule } from 'primeng/inputicon';
@Component({ @Component({
standalone: true, standalone: true,
imports: [CommonModule, BreadcrumbModule, TieredMenuModule, IconFieldModule, InputIconModule, MenuModule, ButtonModule, ContextMenuModule, MegaMenuModule, PanelMenuModule, TabsModule, MenubarModule, InputTextModule, TabsModule, StepperModule, TabsModule, IconField, InputIcon], imports: [
CommonModule,
BreadcrumbModule,
TieredMenuModule,
IconFieldModule,
InputIconModule,
MenuModule,
ButtonModule,
ContextMenuModule,
MegaMenuModule,
PanelMenuModule,
TabsModule,
MenubarModule,
InputTextModule,
TabsModule,
StepperModule,
TabsModule,
IconField,
InputIcon
],
template: ` template: `
<div class="card"> <div class="card">
<div class="font-semibold text-xl mb-4">Menubar</div> <div class="font-semibold text-xl mb-4">Menubar</div>
@@ -25,11 +43,9 @@ import { InputIcon, InputIconModule } from 'primeng/inputicon';
<ng-template #end> <ng-template #end>
<p-iconfield> <p-iconfield>
<p-inputicon class="pi pi-search" /> <p-inputicon class="pi pi-search" />
<input type="text" pInputText placeholder="Search"> <input type="text" pInputText placeholder="Search" />
</p-iconfield> </p-iconfield>
</ng-template> </ng-template>
</p-menubar> </p-menubar>
</div> </div>
@@ -69,7 +85,7 @@ import { InputIcon, InputIconModule } from 'primeng/inputicon';
<div class="md:w-1/3"> <div class="md:w-1/3">
<div class="card"> <div class="card">
<div class="font-semibold text-xl mb-4">Tiered Menu</div> <div class="font-semibold text-xl mb-4">Tiered Menu</div>
<p-tieredMenu [model]="tieredMenuItems"></p-tieredMenu> <p-tieredmenu [model]="tieredMenuItems"></p-tieredmenu>
</div> </div>
</div> </div>
<div class="md:w-1/3"> <div class="md:w-1/3">
@@ -88,7 +104,7 @@ import { InputIcon, InputIconModule } from 'primeng/inputicon';
<div class="card" #anchor> <div class="card" #anchor>
<div class="font-semibold text-xl mb-4">Context Menu</div> <div class="font-semibold text-xl mb-4">Context Menu</div>
Right click to display. Right click to display.
<p-contextMenu [target]="anchor" [model]="contextMenuItems"></p-contextMenu> <p-contextmenu [target]="anchor" [model]="contextMenuItems"></p-contextmenu>
</div> </div>
</div> </div>
</div> </div>
@@ -97,23 +113,22 @@ import { InputIcon, InputIconModule } from 'primeng/inputicon';
<div class="md:w-1/2"> <div class="md:w-1/2">
<div class="card"> <div class="card">
<div class="font-semibold text-xl mb-4">MegaMenu | Horizontal</div> <div class="font-semibold text-xl mb-4">MegaMenu | Horizontal</div>
<p-megaMenu [model]="megaMenuItems" /> <p-megamenu [model]="megaMenuItems" />
<div class="font-semibold text-xl mb-4 mt-8">MegaMenu | Vertical</div> <div class="font-semibold text-xl mb-4 mt-8">MegaMenu | Vertical</div>
<p-megaMenu [model]="megaMenuItems" orientation="vertical" /> <p-megamenu [model]="megaMenuItems" orientation="vertical" />
</div> </div>
</div> </div>
<div class="md:w-1/2"> <div class="md:w-1/2">
<div class="card"> <div class="card">
<div class="font-semibold text-xl mb-4">PanelMenu</div> <div class="font-semibold text-xl mb-4">PanelMenu</div>
<p-panelMenu [model]="panelMenuItems" /> <p-panelmenu [model]="panelMenuItems" />
</div> </div>
</div> </div>
</div> </div>
`, `
}) })
export class MenuDoc { export class MenuDoc {
nestedMenuItems = [ nestedMenuItems = [
{ {
label: 'Customers', label: 'Customers',
@@ -521,5 +536,4 @@ export class MenuDoc {
] ]
} }
]; ];
} }

View File

@@ -20,10 +20,10 @@ import { OverlayBadgeModule } from 'primeng/overlaybadge';
<div class="font-semibold text-xl mb-4">ProgressBar</div> <div class="font-semibold text-xl mb-4">ProgressBar</div>
<div class="flex flex-col md:flex-row gap-4"> <div class="flex flex-col md:flex-row gap-4">
<div class="md:w-1/2"> <div class="md:w-1/2">
<p-progressBar [value]="value" [showValue]="true"></p-progressBar> <p-progressbar [value]="value" [showValue]="true"></p-progressbar>
</div> </div>
<div class="md:w-1/2"> <div class="md:w-1/2">
<p-progressBar [value]="50" [showValue]="false"></p-progressBar> <p-progressbar [value]="50" [showValue]="false"></p-progressbar>
</div> </div>
</div> </div>
</div> </div>
@@ -70,14 +70,14 @@ import { OverlayBadgeModule } from 'primeng/overlaybadge';
<div class="card"> <div class="card">
<div class="font-semibold text-xl mb-4">Avatar</div> <div class="font-semibold text-xl mb-4">Avatar</div>
<div class="font-semibold mb-4">Group</div> <div class="font-semibold mb-4">Group</div>
<p-avatarGroup styleClass="mb-4"> <p-avatargroup styleClass="mb-4">
<p-avatar image="https://primefaces.org/cdn/primeng/images/demo/avatar/amyelsner.png" size="large" shape="circle"></p-avatar> <p-avatar image="https://primefaces.org/cdn/primeng/images/demo/avatar/amyelsner.png" size="large" shape="circle"></p-avatar>
<p-avatar image="https://primefaces.org/cdn/primeng/images/demo/avatar/asiyajavayant.png" size="large" shape="circle"></p-avatar> <p-avatar image="https://primefaces.org/cdn/primeng/images/demo/avatar/asiyajavayant.png" size="large" shape="circle"></p-avatar>
<p-avatar image="https://primefaces.org/cdn/primeng/images/demo/avatar/onyamalimba.png" size="large" shape="circle"></p-avatar> <p-avatar image="https://primefaces.org/cdn/primeng/images/demo/avatar/onyamalimba.png" size="large" shape="circle"></p-avatar>
<p-avatar image="https://primefaces.org/cdn/primeng/images/demo/avatar/ionibowcher.png" size="large" shape="circle"></p-avatar> <p-avatar image="https://primefaces.org/cdn/primeng/images/demo/avatar/ionibowcher.png" size="large" shape="circle"></p-avatar>
<p-avatar image="https://primefaces.org/cdn/primeng/images/demo/avatar/xuxuefeng.png" size="large" shape="circle"></p-avatar> <p-avatar image="https://primefaces.org/cdn/primeng/images/demo/avatar/xuxuefeng.png" size="large" shape="circle"></p-avatar>
<p-avatar label="+2" shape="circle" size="large" [style]="{ 'background-color': '#9c27b0', color: '#ffffff' }"></p-avatar> <p-avatar label="+2" shape="circle" size="large" [style]="{ 'background-color': '#9c27b0', color: '#ffffff' }"></p-avatar>
</p-avatarGroup> </p-avatargroup>
<div class="font-semibold my-4">Label - Circle</div> <div class="font-semibold my-4">Label - Circle</div>
<p-avatar class="mr-2" label="P" size="xlarge" shape="circle"></p-avatar> <p-avatar class="mr-2" label="P" size="xlarge" shape="circle"></p-avatar>

View File

@@ -10,12 +10,12 @@ import { InputTextModule } from 'primeng/inputtext';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { TooltipModule } from 'primeng/tooltip'; import { TooltipModule } from 'primeng/tooltip';
import { Product, ProductService } from '@/src/service/demo/product.service'; import { Product, ProductService } from '@/src/service/demo/product.service';
import { TableModule } from 'primeng/table';
@Component({ @Component({
standalone: true, standalone: true,
imports:[ToastModule, DialogModule, ButtonModule, DrawerModule, PopoverModule, ConfirmPopupModule, InputTextModule, FormsModule, TooltipModule], imports: [ToastModule, DialogModule, ButtonModule, DrawerModule, PopoverModule, ConfirmPopupModule, InputTextModule, FormsModule, TooltipModule, TableModule, ToastModule],
template:` template: ` <div class="flex flex-col md:flex-row gap-8">
<div class="flex flex-col md:flex-row gap-8">
<div class="md:w-1/2"> <div class="md:w-1/2">
<div class="card"> <div class="card">
<div class="font-semibold text-xl mb-4">Dialog</div> <div class="font-semibold text-xl mb-4">Dialog</div>
@@ -36,8 +36,24 @@ import { Product, ProductService } from '@/src/service/demo/product.service';
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
<p-button type="button" label="Show" (click)="toggleDataTable(op2, $event)" /> <p-button type="button" label="Show" (click)="toggleDataTable(op2, $event)" />
<p-popover #op2 id="overlay_panel" [style]="{ width: '450px' }"> <p-popover #op2 id="overlay_panel" [style]="{ width: '450px' }">
<!-- TABLE --> <p-table [value]="products" selectionMode="single" [(selection)]="selectedProduct" dataKey="id" [rows]="5" [paginator]="true" (onRowSelect)="onProductSelect(op2, $event)">
<ng-template #header>
<tr>
<th>Name</th>
<th>Image</th>
<th>Price</th>
</tr>
</ng-template>
<ng-template #body let-product>
<tr [pSelectableRow]="product">
<td>{{ product.name }}</td>
<td><img [src]="'https://primefaces.org/cdn/primeng/images/demo/product/' + product.image" [alt]="product.name" class="w-16 shadow-sm" /></td>
<td>{{ product.price }}</td>
</tr>
</ng-template>
</p-table>
</p-popover> </p-popover>
<p-toast />
</div> </div>
</div> </div>
@@ -119,7 +135,6 @@ import { Product, ProductService } from '@/src/service/demo/product.service';
providers: [ConfirmationService, MessageService, ProductService] providers: [ConfirmationService, MessageService, ProductService]
}) })
export class OverlayDoc implements OnInit { export class OverlayDoc implements OnInit {
images: any[] = []; images: any[] = [];
display: boolean = false; display: boolean = false;
@@ -138,34 +153,44 @@ export class OverlayDoc implements OnInit {
displayConfirmation: boolean = false; displayConfirmation: boolean = false;
constructor(private productService: ProductService, private confirmationService: ConfirmationService, private messageService: MessageService) { } selectedProduct!: Product;
constructor(
private productService: ProductService,
private confirmationService: ConfirmationService,
private messageService: MessageService
) {}
ngOnInit() { ngOnInit() {
this.productService.getProductsSmall().then(products => this.products = products); this.productService.getProductsSmall().then((products) => (this.products = products));
this.images = []; this.images = [];
this.images.push({ this.images.push({
source: 'assets/demo/images/sopranos/sopranos1.jpg', source: 'assets/demo/images/sopranos/sopranos1.jpg',
thumbnail: 'assets/demo/images/sopranos/sopranos1_small.jpg', title: 'Sopranos 1' thumbnail: 'assets/demo/images/sopranos/sopranos1_small.jpg',
title: 'Sopranos 1'
}); });
this.images.push({ this.images.push({
source: 'assets/demo/images/sopranos/sopranos2.jpg', source: 'assets/demo/images/sopranos/sopranos2.jpg',
thumbnail: 'assets/demo/images/sopranos/sopranos2_small.jpg', title: 'Sopranos 2' thumbnail: 'assets/demo/images/sopranos/sopranos2_small.jpg',
title: 'Sopranos 2'
}); });
this.images.push({ this.images.push({
source: 'assets/demo/images/sopranos/sopranos3.jpg', source: 'assets/demo/images/sopranos/sopranos3.jpg',
thumbnail: 'assets/demo/images/sopranos/sopranos3_small.jpg', title: 'Sopranos 3' thumbnail: 'assets/demo/images/sopranos/sopranos3_small.jpg',
title: 'Sopranos 3'
}); });
this.images.push({ this.images.push({
source: 'assets/demo/images/sopranos/sopranos4.jpg', source: 'assets/demo/images/sopranos/sopranos4.jpg',
thumbnail: 'assets/demo/images/sopranos/sopranos4_small.jpg', title: 'Sopranos 4' thumbnail: 'assets/demo/images/sopranos/sopranos4_small.jpg',
title: 'Sopranos 4'
}); });
} }
confirm(event: Event) { confirm(event: Event) {
this.confirmationService.confirm({ this.confirmationService.confirm({
key: 'confirm2', key: 'confirm2',
target: event.target || new EventTarget, target: event.target || new EventTarget(),
message: 'Are you sure that you want to proceed?', message: 'Are you sure that you want to proceed?',
icon: 'pi pi-exclamation-triangle', icon: 'pi pi-exclamation-triangle',
accept: () => { accept: () => {