This commit is contained in:
2026-04-23 01:22:44 +03:30
parent e027b89173
commit 57f333f5b8
43 changed files with 16222 additions and 2847 deletions
@@ -4,7 +4,7 @@
<div class="flex items-center gap-10 justify-between">
<h5 class="font-bold">{{ cardTitle }}</h5>
<div class="flex items-center gap-2 shrink-0">
<ng-container [ngTemplateOutlet]="moreAction"></ng-container>
<ng-container [ngTemplateOutlet]="moreActions"></ng-container>
@if (editable) {
<button
pButton
@@ -34,7 +34,7 @@ export class AppCardComponent {
@Output() editModeChange = new EventEmitter<boolean>();
@ContentChild('header', { static: true }) header?: Maybe<TemplateRef<any>>;
@ContentChild('moreAction', { static: true }) moreAction?: Maybe<TemplateRef<any>>;
@ContentChild('moreActions', { static: true }) moreActions?: Maybe<TemplateRef<any>>;
// constructor() {
// if (this.editable) {
@@ -25,7 +25,12 @@ export class KeyValueComponent {
| 'date'
| 'dateTime'
| 'duration'
| 'id'
| 'thumbnail'
| 'nested'
| 'index'
| 'simple' = 'simple';
@Input() trueValueToShow?: string;
@Input() falseValueToShow?: string;
@Input() variant?: 'badge' | 'text';
@@ -8,6 +8,8 @@
columnResizeMode="fit"
stripedRows
[showFirstLastIcon]="false"
[expandedRowKeys]="expandedRows"
[dataKey]="dataKey"
class="grow flex! flex-col overflow-hidden"
[tableStyleClass]="!items.length && !loading ? 'h-full' : ''"
>
@@ -55,10 +57,13 @@
@if (actionsCount()) {
<th type="th" [style]="{ width: `${actionsCount() * 2 + (actionsCount() - 1) * 0.25}rem` }"></th>
}
@if (expandable) {
<th style="width: 3rem"></th>
}
</tr>
</ng-template>
<ng-template #body let-item let-i="rowIndex">
<ng-template #body let-item let-i="rowIndex" let-expanded="expanded">
<tr>
@for (col of columns; track col.field) {
<td>
@@ -99,9 +104,121 @@
(details)="details(item)"
></td>
}
@if (expandable) {
<td>
<p-button
type="button"
pRipple
[pRowToggler]="item"
[text]="true"
[rounded]="true"
[plain]="true"
[icon]="expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'"
/>
</td>
}
</tr>
</ng-template>
@if (expandable && expandColumns && expandableItemKey) {
<ng-template #expandedrow let-item>
<tr>
<td [attr.colspan]="columns.length + 1">
<div class="px-4">
@if (item[expandableItemKey]?.length) {
<p-table
[columns]="expandColumns || []"
[scrollable]="true"
[value]="item[expandableItemKey]"
[loading]="loading"
columnResizeMode="fit"
stripedRows
[showFirstLastIcon]="false"
[expandedRowKeys]="expandedRows"
class="grow flex! flex-col overflow-hidden"
[tableStyleClass]="!item.items?.length && !loading ? 'h-full' : ''"
>
<ng-template #header let-columns>
<tr>
@for (col of expandColumns; track col.header) {
<th
[style]="
col.type === 'index'
? { width: '3rem', minWidth: '3rem' }
: { width: col.width, minWidth: col.minWidth }
"
>
{{ col.header }}
</th>
}
</tr>
</ng-template>
<ng-template #body let-item let-i="rowIndex">
<tr>
@for (col of expandColumns; track col.field) {
<td>
{{ item.name }}
@if (col.type === "index") {
{{ i * (currentPage || 1) + 1 }}
} @else if (col.type === "thumbnail") {
<div
class="w-20 h-20 rounded-2xl overflow-hidden bg-surface-50 cursor-pointer"
(click)="openThumbnailModal(item)"
>
@if (item[col.field]) {
<img [src]="item[col.field]" class="w-full h-full object-cover" />
}
</div>
} @else if (getTemplate(col)) {
<ng-container
[ngTemplateOutlet]="getTemplate(col)"
[ngTemplateOutletContext]="{ $implicit: item }"
></ng-container>
} @else if (col.canCopy) {
<uikit-copy [text]="getCell(item, col)"></uikit-copy>
} @else {
<span [class]="getPreviewClasses(item, col)">
{{ getCell(item, col) }}
</span>
}
</td>
}
</tr>
</ng-template>
<ng-template #emptymessage>
<tr class="">
<td [colSpan]="(expandColumns.length + 1).toString()" class="w-full">
<uikit-empty-state
[title]="emptyPlaceholderTitle"
[description]="emptyPlaceholderDescription"
[ctaLabel]="emptyPlaceholderCtaLabel || addNewCtaLabel"
[showCTA]="showAdd"
(ctaClick)="openAddForm()"
></uikit-empty-state>
</td>
</tr>
</ng-template>
</p-table>
} @else {
<div class="grid grid-cols-3 gap-4 py-2">
@for (col of expandColumns; track $index) {
<app-key-value
[label]="col.header"
[value]="item[expandableItemKey][col.field]"
[type]="col.type || 'simple'"
/>
}
</div>
}
</div>
</td>
</tr>
</ng-template>
}
<ng-template #emptymessage>
<tr class="">
<td [colSpan]="(columns.length + 1).toString()" class="w-full">
@@ -1,3 +1,4 @@
import { Maybe } from '@/core';
import { PaginatorComponent, UikitCopyComponent, UikitEmptyStateComponent } from '@/uikit';
import { formatJalali, formatWithCurrency, jalaliDiff } from '@/utils';
import { CommonModule } from '@angular/common';
@@ -18,6 +19,7 @@ import { DrawerModule } from 'primeng/drawer';
import { PaginatorModule } from 'primeng/paginator';
import { SkeletonModule } from 'primeng/skeleton';
import { TableModule } from 'primeng/table';
import { KeyValueComponent } from '../key-value.component/key-value.component';
import { TableActionRowComponent } from '../table-action-row.component';
export interface IColumn<T = any> {
@@ -26,7 +28,7 @@ export interface IColumn<T = any> {
width?: string;
minWidth?: string;
canCopy?: boolean;
type?: 'text' | 'price' | 'boolean' | 'date' | 'nested' | 'index' | 'id' | 'thumbnail';
type?: 'simple' | 'price' | 'boolean' | 'date' | 'nested' | 'index' | 'id' | 'thumbnail';
nestedPath?: string;
thumbnailOptions?: {
editable: boolean;
@@ -58,6 +60,7 @@ export interface IColumn<T = any> {
DrawerModule,
PaginatorComponent,
UikitCopyComponent,
KeyValueComponent,
],
})
export class PageDataListComponent<I> {
@@ -84,10 +87,15 @@ export class PageDataListComponent<I> {
@Input() isFiltered: boolean = false;
@Input() fullHeight?: boolean = false;
@Input() height: string = '';
@Input() expandable?: boolean = false;
@Input() expandableItemKey?: string = '';
@Input() expandColumns?: Maybe<IColumn[]> = null;
@Input() dataKey?: string = 'items';
@ContentChild('filter', { static: true }) filter!: TemplateRef<any> | null;
@ContentChild('caption', { static: true }) caption!: TemplateRef<any> | null;
@ContentChild('moreActions', { static: true }) moreActions!: TemplateRef<any> | null;
@ContentChild('expandableTemp', { static: false }) expandableTemp!: TemplateRef<any> | null;
@Output() onEdit = new EventEmitter<I>();
@Output() onDelete = new EventEmitter<I>();
@@ -97,6 +105,7 @@ export class PageDataListComponent<I> {
@Output() onThumbnailClick = new EventEmitter<I>();
filterDrawerVisible = signal<boolean>(false);
expandedRows: { [key: string]: boolean } = {};
ngOnInit() {
if (this.height)