feat: remove AGENT.md and add new agents.md with updated repository-specific instructions
refactor: update shared-saleInvoice.component.ts to simplify SKU code handling refactor: modify goods.component.html to optimize payload form dialog rendering fix: adjust goods.component.ts to ensure payload form visibility logic is correct fix: update order-section.component.ts to improve customer dialog and payment form visibility style: enhance form.component.html button styling for better responsiveness fix: change abstract-form.ts to reset form with default values on initialization refactor: streamline page-data-list-grid-view.component.html for better caption handling refactor: update page-data-list-grid-view.component.ts to remove unused methods and improve readability refactor: simplify page-data-list-table-view.component.html and remove redundant code refactor: clean up page-data-list-table-view.component.ts by removing unnecessary methods feat: enhance page-data-list.component.html with new caption and paginator templates feat: create page-data-value.component.ts to encapsulate data rendering logic for grid and table views style: update presets.ts to modify color palette for better UI consistency
This commit is contained in:
@@ -10,7 +10,7 @@ import {
|
|||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
import { PriceMaskDirective } from '@/shared/directives';
|
import { PriceMaskDirective } from '@/shared/directives';
|
||||||
import { UikitEmptyStateComponent } from '@/uikit';
|
import { UikitEmptyStateComponent } from '@/uikit';
|
||||||
import { formatJalali, getGoodUnitTypeProperties } from '@/utils';
|
import { formatJalali } from '@/utils';
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
computed,
|
computed,
|
||||||
@@ -91,6 +91,10 @@ export class ConsumerSaleInvoiceSharedComponent {
|
|||||||
path: 'good.name',
|
path: 'good.name',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'sku_code',
|
||||||
|
header: 'شناسه کالا',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'unit_price',
|
field: 'unit_price',
|
||||||
header: 'قیمت واحد',
|
header: 'قیمت واحد',
|
||||||
@@ -100,7 +104,7 @@ export class ConsumerSaleInvoiceSharedComponent {
|
|||||||
field: 'quantity',
|
field: 'quantity',
|
||||||
header: 'مقدار',
|
header: 'مقدار',
|
||||||
customDataModel(item) {
|
customDataModel(item) {
|
||||||
return `${item.quantity} ${getGoodUnitTypeProperties(item.good.unit_type).quantitySymbolText}`;
|
return `${item.quantity} ${item.measure_unit_text}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,11 +36,7 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@defer (when showPayloadForm()) {
|
@if (showPayloadForm() && selectedGoodToAdd(); as selectedGood) {
|
||||||
<pos-payload-form-dialog
|
<pos-payload-form-dialog [(visible)]="showPayloadForm" [good]="selectedGood" (onClose)="onClosePayloadForm()" />
|
||||||
[(visible)]="showPayloadForm"
|
|
||||||
[good]="selectedGoodToAdd()!"
|
|
||||||
(onClose)="onClosePayloadForm()"
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,14 +67,14 @@ export class PosGoodsComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addGood(good: IGoodResponse) {
|
addGood(good: IGoodResponse) {
|
||||||
this.showPayloadForm.set(true);
|
this.showPayloadForm.set(false);
|
||||||
|
this.selectedGoodToAdd.set(null);
|
||||||
console.log('good', good);
|
|
||||||
|
|
||||||
this.selectedGoodToAdd.set(good);
|
this.selectedGoodToAdd.set(good);
|
||||||
|
queueMicrotask(() => this.showPayloadForm.set(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
onClosePayloadForm() {
|
onClosePayloadForm() {
|
||||||
|
this.showPayloadForm.set(false);
|
||||||
this.selectedGoodToAdd.set(null);
|
this.selectedGoodToAdd.set(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,13 +72,13 @@ export class PosOrderSectionComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openCustomerDialog() {
|
openCustomerDialog() {
|
||||||
// this.this.store.submitOrder();
|
this.isVisibleCustomerForm.set(false);
|
||||||
this.isVisibleCustomerForm.set(true);
|
queueMicrotask(() => this.isVisibleCustomerForm.set(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
submitAndPay() {
|
submitAndPay() {
|
||||||
// this.this.store.submitOrder();
|
this.isVisiblePaymentForm.set(false);
|
||||||
this.isVisiblePaymentForm.set(true);
|
queueMicrotask(() => this.isVisiblePaymentForm.set(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
addMoreGoods() {
|
addMoreGoods() {
|
||||||
|
|||||||
+1
-1
@@ -27,6 +27,6 @@
|
|||||||
[discountAmount]="discountAmount()"
|
[discountAmount]="discountAmount()"
|
||||||
[taxAmount]="taxAmount()"
|
[taxAmount]="taxAmount()"
|
||||||
/>
|
/>
|
||||||
<p-button (onClick)="submit()"> {{ preparedCTAText() }} </p-button>
|
<p-button class="sm:w-auto w-full" (onClick)="submit()"> {{ preparedCTAText() }} </p-button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -37,14 +37,14 @@ export abstract class AbstractForm<
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.form.patchValue(this.initialValues ?? {});
|
this.form.reset(this.initialValues ?? this.defaultValues);
|
||||||
// Object.entries(this.form.controls).forEach(([key, control]) => {
|
// Object.entries(this.form.controls).forEach(([key, control]) => {
|
||||||
// console.log(key, control);
|
// console.log(key, control);
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
this.form.patchValue(this.initialValues ?? {});
|
this.form.reset(this.initialValues ?? this.defaultValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSuccess(response: Response): void {}
|
onSuccess(response: Response): void {}
|
||||||
|
|||||||
@@ -1,46 +1,24 @@
|
|||||||
<div class="h-full overflow-auto border border-surface-border cardShadow">
|
<div class="h-full overflow-auto border border-surface-border cardShadow">
|
||||||
<div
|
<div
|
||||||
[ngClass]="{
|
[ngClass]="{
|
||||||
'px-4': captionBox,
|
'px-4': hasCaption,
|
||||||
'pb-4': true,
|
'pb-4': true,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
@if (captionBox) {
|
@if (hasCaption && captionBox) {
|
||||||
<div class="pt-4">
|
<div class="pt-4">
|
||||||
<ng-container [ngTemplateOutlet]="captionBox"></ng-container>
|
<ng-container [ngTemplateOutlet]="captionBox"></ng-container>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
}
|
}
|
||||||
<div class="grid grid-cols-1 gap-3" [ngClass]="{ 'pt-4': captionBox }">
|
<div class="grid grid-cols-1 gap-3" [ngClass]="{ 'pt-4': hasCaption }">
|
||||||
@for (item of items; track `gridView_${$index}`) {
|
@for (item of items; track `gridView_${$index}`) {
|
||||||
<div class="card border border-surface-border bg-surface-0! mb-0! rounded-2xl p-4!">
|
<div class="card border border-surface-border bg-surface-0! mb-0! rounded-2xl p-4!">
|
||||||
<div class="listKeyValue">
|
<div class="listKeyValue">
|
||||||
@for (col of columns; track `gridView_${col.field.toString()}_${$index}`) {
|
@for (col of columns; track `gridView_${col.field.toString()}_${$index}`) {
|
||||||
@if (col.type !== "index") {
|
@if (col.type !== "index") {
|
||||||
<app-key-value [label]="col.header" [variant]="col.variant">
|
<app-key-value [label]="col.header" [variant]="col.variant">
|
||||||
@if (col.type === "thumbnail") {
|
<app-page-data-value [item]="item" [column]="col" (thumbnailClick)="openThumbnailModal($event)" />
|
||||||
<div
|
|
||||||
class="w-20 h-20 rounded-2xl overflow-hidden bg-surface-100 cursor-pointer"
|
|
||||||
(click)="openThumbnailModal(item)"
|
|
||||||
>
|
|
||||||
@if (item && col?.field && item[col!.field!]) {
|
|
||||||
<img [src]="item[col.field]" class="w-full h-full object-cover" />
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
} @else if (col.variant === "tag") {
|
|
||||||
<p-tag [value]="getCell(item, col)" [severity]="col.tagOptions?.severity || 'contrast'"></p-tag>
|
|
||||||
} @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>
|
|
||||||
}
|
|
||||||
</app-key-value>
|
</app-key-value>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import { Maybe } from '@/core';
|
import { Maybe } from '@/core';
|
||||||
import { UikitCopyComponent } from '@/uikit';
|
|
||||||
import { formatJalali, formatWithCurrency, jalaliDiff } from '@/utils';
|
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
@@ -17,8 +15,8 @@ import { DrawerModule } from 'primeng/drawer';
|
|||||||
import { PaginatorModule } from 'primeng/paginator';
|
import { PaginatorModule } from 'primeng/paginator';
|
||||||
import { SkeletonModule } from 'primeng/skeleton';
|
import { SkeletonModule } from 'primeng/skeleton';
|
||||||
import { TableModule } from 'primeng/table';
|
import { TableModule } from 'primeng/table';
|
||||||
import { Tag } from 'primeng/tag';
|
|
||||||
import { KeyValueComponent } from '../key-value.component/key-value.component';
|
import { KeyValueComponent } from '../key-value.component/key-value.component';
|
||||||
|
import { PageDataValueComponent } from './page-data-value.component';
|
||||||
import { IColumn } from './page-data-list.component';
|
import { IColumn } from './page-data-list.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -34,9 +32,8 @@ import { IColumn } from './page-data-list.component';
|
|||||||
SkeletonModule,
|
SkeletonModule,
|
||||||
PaginatorModule,
|
PaginatorModule,
|
||||||
DrawerModule,
|
DrawerModule,
|
||||||
UikitCopyComponent,
|
|
||||||
KeyValueComponent,
|
KeyValueComponent,
|
||||||
Tag,
|
PageDataValueComponent,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AppPageDataListGridView<I = any> {
|
export class AppPageDataListGridView<I = any> {
|
||||||
@@ -62,6 +59,7 @@ export class AppPageDataListGridView<I = any> {
|
|||||||
@Input() expandColumns?: Maybe<IColumn[]> = null;
|
@Input() expandColumns?: Maybe<IColumn[]> = null;
|
||||||
@Input() dataKey?: string = 'items';
|
@Input() dataKey?: string = 'items';
|
||||||
@Input() showPaginator?: boolean;
|
@Input() showPaginator?: boolean;
|
||||||
|
@Input() hasCaption: boolean = false;
|
||||||
|
|
||||||
@ContentChild('filter', { static: true }) filter!: TemplateRef<any> | null;
|
@ContentChild('filter', { static: true }) filter!: TemplateRef<any> | null;
|
||||||
@ContentChild('moreActions', { static: true }) moreActions!: TemplateRef<any> | null;
|
@ContentChild('moreActions', { static: true }) moreActions!: TemplateRef<any> | null;
|
||||||
@@ -113,99 +111,6 @@ export class AppPageDataListGridView<I = any> {
|
|||||||
// this.
|
// this.
|
||||||
};
|
};
|
||||||
|
|
||||||
getPreviewClasses(item: Record<string, any>, column: IColumn): any {
|
|
||||||
if (!item || !column || column.customDataModel) return '';
|
|
||||||
try {
|
|
||||||
const { field } = column;
|
|
||||||
|
|
||||||
const data = item[String(field)];
|
|
||||||
switch (column.type) {
|
|
||||||
case 'date':
|
|
||||||
if (column.dateOption?.expiredMode) {
|
|
||||||
if (jalaliDiff(new Date(), data) > 0) {
|
|
||||||
return 'text-error';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getCell(item: Record<string, any>, column: IColumn): any {
|
|
||||||
if (!item || !column) return '';
|
|
||||||
try {
|
|
||||||
let { field, type } = column;
|
|
||||||
|
|
||||||
if (column.customDataModel) {
|
|
||||||
return this.renderCustom(column, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = item[String(field)];
|
|
||||||
if (column.type === 'nested') {
|
|
||||||
const path = column.nestedOption?.path;
|
|
||||||
if (!path) return '-';
|
|
||||||
data = path
|
|
||||||
.split('.')
|
|
||||||
.reduce((obj, key) => (obj && obj[key] !== undefined ? obj[key] : null), item);
|
|
||||||
type = column.nestedOption?.type || 'simple';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type) {
|
|
||||||
switch (type) {
|
|
||||||
case 'id':
|
|
||||||
if (!data) return '-';
|
|
||||||
return `${data.slice(0, 5)}...${data.slice(data.length - 5, data.length)}`;
|
|
||||||
case 'date':
|
|
||||||
if (!data) return '-';
|
|
||||||
return formatJalali(data);
|
|
||||||
case 'boolean':
|
|
||||||
return data ? 'بله' : 'خیر';
|
|
||||||
case 'price':
|
|
||||||
return formatWithCurrency(data, false, 'ریال');
|
|
||||||
case 'number':
|
|
||||||
return data || 0;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data === undefined || data === null) {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
if (typeof data === 'object') {
|
|
||||||
return data.title || '-';
|
|
||||||
}
|
|
||||||
return data || '-';
|
|
||||||
} catch (e) {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getTemplate(col: IColumn): TemplateRef<any> | null {
|
|
||||||
const v = col.customDataModel;
|
|
||||||
return v instanceof TemplateRef ? (v as TemplateRef<any>) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderCustom(column: IColumn, item: any): any {
|
|
||||||
const v = column.customDataModel;
|
|
||||||
|
|
||||||
if (!v) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (typeof v === 'function') {
|
|
||||||
try {
|
|
||||||
return (v as (item: any) => any)(item);
|
|
||||||
} catch {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeof v === 'string') return v;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
actionsCount = computed(() => {
|
actionsCount = computed(() => {
|
||||||
let totalCount = 0;
|
let totalCount = 0;
|
||||||
if (this.showEdit) totalCount += 1;
|
if (this.showEdit) totalCount += 1;
|
||||||
|
|||||||
@@ -50,29 +50,7 @@
|
|||||||
}
|
}
|
||||||
@for (col of columns; track col.field) {
|
@for (col of columns; track col.field) {
|
||||||
<td>
|
<td>
|
||||||
@if (col.type === "thumbnail") {
|
<app-page-data-value [item]="item" [column]="col" (thumbnailClick)="openThumbnailModal($event)" />
|
||||||
<div
|
|
||||||
class="w-20 h-20 rounded-2xl overflow-hidden bg-surface-100 cursor-pointer"
|
|
||||||
(click)="openThumbnailModal(item)"
|
|
||||||
>
|
|
||||||
@if (item[col.field]) {
|
|
||||||
<img [src]="item[col.field]" class="w-full h-full object-cover" />
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
} @else if (col.variant === "tag") {
|
|
||||||
<p-tag [value]="getCell(item, col)" [severity]="col.tagOptions?.severity || 'contrast'"></p-tag>
|
|
||||||
} @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>
|
</td>
|
||||||
}
|
}
|
||||||
@if (actionsCount()) {
|
@if (actionsCount()) {
|
||||||
@@ -97,7 +75,7 @@
|
|||||||
[text]="true"
|
[text]="true"
|
||||||
[rounded]="true"
|
[rounded]="true"
|
||||||
[plain]="true"
|
[plain]="true"
|
||||||
[icon]="expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'"
|
[icon]="expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-left'"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
@@ -145,26 +123,12 @@
|
|||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
@if (col.type === "index") {
|
@if (col.type === "index") {
|
||||||
{{ i * (currentPage || 1) + 1 }}
|
{{ 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 {
|
} @else {
|
||||||
<span [class]="getPreviewClasses(item, col)">
|
<app-page-data-value
|
||||||
{{ getCell(item, col) }}
|
[item]="item"
|
||||||
</span>
|
[column]="col"
|
||||||
|
(thumbnailClick)="openThumbnailModal($event)"
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Maybe } from '@/core';
|
import { Maybe } from '@/core';
|
||||||
import { UikitCopyComponent, UikitEmptyStateComponent } from '@/uikit';
|
import { UikitEmptyStateComponent } from '@/uikit';
|
||||||
import { formatJalali, formatWithCurrency, jalaliDiff } from '@/utils';
|
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
@@ -17,9 +16,9 @@ import { DrawerModule } from 'primeng/drawer';
|
|||||||
import { PaginatorModule } from 'primeng/paginator';
|
import { PaginatorModule } from 'primeng/paginator';
|
||||||
import { SkeletonModule } from 'primeng/skeleton';
|
import { SkeletonModule } from 'primeng/skeleton';
|
||||||
import { TableModule } from 'primeng/table';
|
import { TableModule } from 'primeng/table';
|
||||||
import { Tag } from 'primeng/tag';
|
|
||||||
import { KeyValueComponent } from '../key-value.component/key-value.component';
|
import { KeyValueComponent } from '../key-value.component/key-value.component';
|
||||||
import { TableActionRowComponent } from '../table-action-row.component';
|
import { TableActionRowComponent } from '../table-action-row.component';
|
||||||
|
import { PageDataValueComponent } from './page-data-value.component';
|
||||||
import { IColumn } from './page-data-list.component';
|
import { IColumn } from './page-data-list.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -37,9 +36,8 @@ import { IColumn } from './page-data-list.component';
|
|||||||
SkeletonModule,
|
SkeletonModule,
|
||||||
PaginatorModule,
|
PaginatorModule,
|
||||||
DrawerModule,
|
DrawerModule,
|
||||||
UikitCopyComponent,
|
|
||||||
KeyValueComponent,
|
KeyValueComponent,
|
||||||
Tag,
|
PageDataValueComponent,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AppPageDataListTableView<I = any> {
|
export class AppPageDataListTableView<I = any> {
|
||||||
@@ -66,12 +64,13 @@ export class AppPageDataListTableView<I = any> {
|
|||||||
@Input() dataKey?: string = 'items';
|
@Input() dataKey?: string = 'items';
|
||||||
@Input() showPaginator?: boolean;
|
@Input() showPaginator?: boolean;
|
||||||
@Input() showIndex?: boolean = true;
|
@Input() showIndex?: boolean = true;
|
||||||
|
@Input() hasCaption: boolean = false;
|
||||||
|
|
||||||
@ContentChild('filter', { static: true }) filter!: TemplateRef<any> | null;
|
@ContentChild('filter', { static: true }) filter!: TemplateRef<any> | null;
|
||||||
@ContentChild('paginator', { static: true }) paginator!: TemplateRef<any> | null;
|
@ContentChild('paginator', { static: true }) paginator!: TemplateRef<any> | null;
|
||||||
@ContentChild('moreActions', { static: true }) moreActions!: TemplateRef<any> | null;
|
@ContentChild('moreActions', { static: true }) moreActions!: TemplateRef<any> | null;
|
||||||
@ContentChild('expandableTemp', { static: false }) expandableTemp!: TemplateRef<any> | null;
|
@ContentChild('expandableTemp', { static: false }) expandableTemp!: TemplateRef<any> | null;
|
||||||
@ContentChild('captionBox', { static: true }) captionBox!: TemplateRef<any> | null;
|
@ContentChild('captionBox', { static: false }) captionBox!: TemplateRef<any> | null;
|
||||||
@ContentChild('emptyMessageCard', { static: true }) emptyMessageCard!: TemplateRef<any> | null;
|
@ContentChild('emptyMessageCard', { static: true }) emptyMessageCard!: TemplateRef<any> | null;
|
||||||
|
|
||||||
@Output() onEdit = new EventEmitter<any>();
|
@Output() onEdit = new EventEmitter<any>();
|
||||||
@@ -117,99 +116,6 @@ export class AppPageDataListTableView<I = any> {
|
|||||||
// this.
|
// this.
|
||||||
};
|
};
|
||||||
|
|
||||||
getPreviewClasses(item: Record<string, any>, column: IColumn): any {
|
|
||||||
if (!item || !column || column.customDataModel) return '';
|
|
||||||
try {
|
|
||||||
const { field } = column;
|
|
||||||
|
|
||||||
const data = item[String(field)];
|
|
||||||
switch (column.type) {
|
|
||||||
case 'date':
|
|
||||||
if (column.dateOption?.expiredMode) {
|
|
||||||
if (jalaliDiff(new Date(), data) > 0) {
|
|
||||||
return 'text-error';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getCell(item: Record<string, any>, column: IColumn): any {
|
|
||||||
if (!item || !column) return '';
|
|
||||||
try {
|
|
||||||
let { field, type } = column;
|
|
||||||
|
|
||||||
if (column.customDataModel) {
|
|
||||||
return this.renderCustom(column, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = item[String(field)];
|
|
||||||
if (column.type === 'nested') {
|
|
||||||
const path = column.nestedOption?.path;
|
|
||||||
if (!path) return '-';
|
|
||||||
data = path
|
|
||||||
.split('.')
|
|
||||||
.reduce((obj, key) => (obj && obj[key] !== undefined ? obj[key] : null), item);
|
|
||||||
type = column.nestedOption?.type || 'simple';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type) {
|
|
||||||
switch (type) {
|
|
||||||
case 'id':
|
|
||||||
if (!data) return '-';
|
|
||||||
return `${data.slice(0, 5)}...${data.slice(data.length - 5, data.length)}`;
|
|
||||||
case 'date':
|
|
||||||
if (!data) return '-';
|
|
||||||
return formatJalali(data);
|
|
||||||
case 'boolean':
|
|
||||||
return data ? 'بله' : 'خیر';
|
|
||||||
case 'price':
|
|
||||||
return formatWithCurrency(data, false, 'ریال');
|
|
||||||
case 'number':
|
|
||||||
return data || 0;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data === undefined || data === null) {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
if (typeof data === 'object') {
|
|
||||||
return data.title || '-';
|
|
||||||
}
|
|
||||||
return data || '-';
|
|
||||||
} catch (e) {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getTemplate(col: IColumn): TemplateRef<any> | null {
|
|
||||||
const v = col.customDataModel;
|
|
||||||
return v instanceof TemplateRef ? (v as TemplateRef<any>) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderCustom(column: IColumn, item: any): any {
|
|
||||||
const v = column.customDataModel;
|
|
||||||
|
|
||||||
if (!v) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (typeof v === 'function') {
|
|
||||||
try {
|
|
||||||
return (v as (item: any) => any)(item);
|
|
||||||
} catch {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeof v === 'string') return v;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
actionsCount = computed(() => {
|
actionsCount = computed(() => {
|
||||||
let totalCount = 0;
|
let totalCount = 0;
|
||||||
if (this.showEdit) totalCount += 1;
|
if (this.showEdit) totalCount += 1;
|
||||||
|
|||||||
@@ -1,4 +1,70 @@
|
|||||||
<div class="h-full bg-surface-overlay rounded-(--p-card-border-radius) overflow-hidden">
|
<div class="h-full bg-surface-overlay rounded-(--p-card-border-radius) overflow-hidden">
|
||||||
|
<ng-template #captionTemplate let-isMobileView="isMobileView">
|
||||||
|
@if (pageTitle || showAdd || filter || showRefresh || moreActions) {
|
||||||
|
<ng-container [ngTemplateOutlet]="caption">
|
||||||
|
<div class="flex justify-between items-center gap-4">
|
||||||
|
<h5 class="font-bold">{{ pageTitle }}</h5>
|
||||||
|
@if (showAdd || filter || showRefresh || moreActions) {
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<ng-container [ngTemplateOutlet]="moreActions" />
|
||||||
|
@if (filter) {
|
||||||
|
<p-button
|
||||||
|
label="فیلتر"
|
||||||
|
icon="pi pi-filter"
|
||||||
|
variant="outlined"
|
||||||
|
badgeSeverity="info"
|
||||||
|
size="small"
|
||||||
|
[badge]="isFiltered ? '1' : undefined"
|
||||||
|
(click)="openFilter()"
|
||||||
|
></p-button>
|
||||||
|
}
|
||||||
|
@if (showRefresh) {
|
||||||
|
<p-button icon="pi pi-refresh" outlined size="small" (click)="refresh()"></p-button>
|
||||||
|
}
|
||||||
|
@if (showAll && allItemsPageRoute) {
|
||||||
|
@if (isMobileView) {
|
||||||
|
<a routerLink pButton [routerLink]="allItemsPageRoute" icon="pi pi-eye" outlined size="small"></a>
|
||||||
|
} @else {
|
||||||
|
<a routerLink pButton [routerLink]="allItemsPageRoute" outlined size="small">نمایش همه</a>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if (showAdd) {
|
||||||
|
@if (isMobileView) {
|
||||||
|
<p-button icon="pi pi-plus" size="small" (click)="openAddForm()"></p-button>
|
||||||
|
} @else {
|
||||||
|
<p-button
|
||||||
|
label="{{ addNewCtaLabel }}"
|
||||||
|
icon="pi pi-plus"
|
||||||
|
size="small"
|
||||||
|
(click)="openAddForm()"
|
||||||
|
></p-button>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template #emptyMessageTemplate>
|
||||||
|
<uikit-empty-state
|
||||||
|
[title]="emptyPlaceholderTitle"
|
||||||
|
[description]="emptyPlaceholderDescription"
|
||||||
|
[ctaLabel]="emptyPlaceholderCtaLabel || addNewCtaLabel"
|
||||||
|
[showCTA]="showAdd"
|
||||||
|
(ctaClick)="openAddForm()"
|
||||||
|
></uikit-empty-state>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template #paginatorTemplate>
|
||||||
|
<app-paginator
|
||||||
|
[currentPage]="currentPage || 1"
|
||||||
|
[totalRecords]="totalRecords"
|
||||||
|
[perPage]="perPage || 10"
|
||||||
|
[loading]="loading"
|
||||||
|
(onChange)="onPage($event)"
|
||||||
|
/>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
@if (!isMobile) {
|
@if (!isMobile) {
|
||||||
<app-page-data-list-table-view
|
<app-page-data-list-table-view
|
||||||
[pageTitle]="pageTitle"
|
[pageTitle]="pageTitle"
|
||||||
@@ -14,66 +80,24 @@
|
|||||||
[showDelete]="showDelete"
|
[showDelete]="showDelete"
|
||||||
[showDetails]="showDetails"
|
[showDetails]="showDetails"
|
||||||
[showIndex]="showIndex"
|
[showIndex]="showIndex"
|
||||||
|
[hasCaption]="!!(pageTitle || showAdd || filter || showRefresh || moreActions)"
|
||||||
|
[expandable]="expandable"
|
||||||
|
[expandableItemKey]="expandableItemKey"
|
||||||
|
[expandColumns]="expandColumns"
|
||||||
(onEdit)="edit($event)"
|
(onEdit)="edit($event)"
|
||||||
(onDelete)="remove($event)"
|
(onDelete)="remove($event)"
|
||||||
(onDetails)="details($event)"
|
(onDetails)="details($event)"
|
||||||
>
|
>
|
||||||
<ng-template #captionBox>
|
@if (pageTitle || showAdd || filter || showRefresh || moreActions) {
|
||||||
@if (pageTitle || showAdd || filter || caption || showRefresh || moreActions) {
|
<ng-template #captionBox>
|
||||||
<ng-container [ngTemplateOutlet]="caption">
|
<ng-container [ngTemplateOutlet]="captionTemplate" [ngTemplateOutletContext]="{ isMobileView: false }" />
|
||||||
<div class="flex justify-between items-center gap-4">
|
</ng-template>
|
||||||
<h5 class="font-bold">{{ pageTitle }}</h5>
|
}
|
||||||
@if (showAdd || filter || showRefresh || moreActions) {
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<ng-container [ngTemplateOutlet]="moreActions" />
|
|
||||||
@if (filter) {
|
|
||||||
<p-button
|
|
||||||
label="فیلتر"
|
|
||||||
icon="pi pi-filter"
|
|
||||||
variant="outlined"
|
|
||||||
badgeSeverity="info"
|
|
||||||
size="small"
|
|
||||||
[badge]="isFiltered ? '1' : undefined"
|
|
||||||
(click)="openFilter()"
|
|
||||||
></p-button>
|
|
||||||
}
|
|
||||||
@if (showRefresh) {
|
|
||||||
<p-button icon="pi pi-refresh" outlined size="small" (click)="refresh()"></p-button>
|
|
||||||
}
|
|
||||||
@if (showAll && allItemsPageRoute) {
|
|
||||||
<a routerLink pButton [routerLink]="allItemsPageRoute" outlined size="small">نمایش همه</a>
|
|
||||||
}
|
|
||||||
@if (showAdd) {
|
|
||||||
<p-button
|
|
||||||
label="{{ addNewCtaLabel }}"
|
|
||||||
icon="pi pi-plus"
|
|
||||||
size="small"
|
|
||||||
(click)="openAddForm()"
|
|
||||||
></p-button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
}
|
|
||||||
</ng-template>
|
|
||||||
<ng-template #emptyMessageCard>
|
<ng-template #emptyMessageCard>
|
||||||
<uikit-empty-state
|
<ng-container [ngTemplateOutlet]="emptyMessageTemplate" />
|
||||||
[title]="emptyPlaceholderTitle"
|
|
||||||
[description]="emptyPlaceholderDescription"
|
|
||||||
[ctaLabel]="emptyPlaceholderCtaLabel || addNewCtaLabel"
|
|
||||||
[showCTA]="showAdd"
|
|
||||||
(ctaClick)="openAddForm()"
|
|
||||||
></uikit-empty-state>
|
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<ng-template #paginator>
|
<ng-template #paginator>
|
||||||
<app-paginator
|
<ng-container [ngTemplateOutlet]="paginatorTemplate" />
|
||||||
[currentPage]="currentPage || 1"
|
|
||||||
[totalRecords]="totalRecords"
|
|
||||||
[perPage]="perPage || 10"
|
|
||||||
[loading]="loading"
|
|
||||||
(onChange)="onPage($event)"
|
|
||||||
/>
|
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</app-page-data-list-table-view>
|
</app-page-data-list-table-view>
|
||||||
} @else {
|
} @else {
|
||||||
@@ -90,61 +114,21 @@
|
|||||||
[showEdit]="showEdit"
|
[showEdit]="showEdit"
|
||||||
[showDelete]="showDelete"
|
[showDelete]="showDelete"
|
||||||
[showDetails]="showDetails"
|
[showDetails]="showDetails"
|
||||||
|
[hasCaption]="!!(pageTitle || showAdd || filter || showRefresh || moreActions)"
|
||||||
(onEdit)="edit($event)"
|
(onEdit)="edit($event)"
|
||||||
(onDelete)="remove($event)"
|
(onDelete)="remove($event)"
|
||||||
(onDetails)="details($event)"
|
(onDetails)="details($event)"
|
||||||
>
|
>
|
||||||
<ng-template #captionBox>
|
<ng-template #captionBox>
|
||||||
@if (pageTitle || showAdd || filter || caption || showRefresh || moreActions) {
|
@if (pageTitle || showAdd || filter || showRefresh || moreActions) {
|
||||||
<ng-container [ngTemplateOutlet]="caption">
|
<ng-container [ngTemplateOutlet]="captionTemplate" [ngTemplateOutletContext]="{ isMobileView: true }" />
|
||||||
<div class="flex justify-between items-center gap-4">
|
|
||||||
<h5 class="font-bold">{{ pageTitle }}</h5>
|
|
||||||
@if (showAdd || filter || showRefresh || moreActions) {
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<ng-container [ngTemplateOutlet]="moreActions" />
|
|
||||||
@if (filter) {
|
|
||||||
<p-button
|
|
||||||
label="فیلتر"
|
|
||||||
icon="pi pi-filter"
|
|
||||||
variant="outlined"
|
|
||||||
badgeSeverity="info"
|
|
||||||
size="small"
|
|
||||||
[badge]="isFiltered ? '1' : undefined"
|
|
||||||
(click)="openFilter()"
|
|
||||||
></p-button>
|
|
||||||
}
|
|
||||||
@if (showRefresh) {
|
|
||||||
<p-button icon="pi pi-refresh" outlined size="small" (click)="refresh()"></p-button>
|
|
||||||
}
|
|
||||||
@if (showAll && allItemsPageRoute) {
|
|
||||||
<a routerLink pButton [routerLink]="allItemsPageRoute" icon="pi pi-eye" outlined size="small"></a>
|
|
||||||
}
|
|
||||||
@if (showAdd) {
|
|
||||||
<p-button icon="pi pi-plus" size="small" (click)="openAddForm()"></p-button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
}
|
}
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<ng-template #emptyMessageCard>
|
<ng-template #emptyMessageCard>
|
||||||
<uikit-empty-state
|
<ng-container [ngTemplateOutlet]="emptyMessageTemplate" />
|
||||||
[title]="emptyPlaceholderTitle"
|
|
||||||
[description]="emptyPlaceholderDescription"
|
|
||||||
[ctaLabel]="emptyPlaceholderCtaLabel || addNewCtaLabel"
|
|
||||||
[showCTA]="showAdd"
|
|
||||||
(ctaClick)="openAddForm()"
|
|
||||||
></uikit-empty-state>
|
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<ng-template #paginator>
|
<ng-template #paginator>
|
||||||
<app-paginator
|
<ng-container [ngTemplateOutlet]="paginatorTemplate" />
|
||||||
[currentPage]="currentPage || 1"
|
|
||||||
[totalRecords]="totalRecords"
|
|
||||||
[perPage]="perPage || 10"
|
|
||||||
[loading]="loading"
|
|
||||||
(onChange)="onPage($event)"
|
|
||||||
/>
|
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</app-page-data-list-grid-view>
|
</app-page-data-list-grid-view>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import { formatJalali, formatWithCurrency, jalaliDiff } from '@/utils';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { Component, EventEmitter, Input, Output, TemplateRef } from '@angular/core';
|
||||||
|
import { Tag } from 'primeng/tag';
|
||||||
|
import { UikitCopyComponent } from '@/uikit';
|
||||||
|
import { IColumn } from './page-data-list.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-page-data-value',
|
||||||
|
standalone: true,
|
||||||
|
imports: [CommonModule, Tag, UikitCopyComponent],
|
||||||
|
template: `
|
||||||
|
@if (column.type === 'thumbnail') {
|
||||||
|
<div class="w-20 h-20 rounded-2xl overflow-hidden bg-surface-100 cursor-pointer" (click)="thumbnailClick.emit(item)">
|
||||||
|
@if (readFieldValue(item, column.field)) {
|
||||||
|
<img [src]="readFieldValue(item, column.field)" class="w-full h-full object-cover" />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
} @else if (column.variant === 'tag') {
|
||||||
|
<p-tag [value]="getCell(item, column)" [severity]="column.tagOptions?.severity || 'contrast'"></p-tag>
|
||||||
|
} @else if (getTemplate(column)) {
|
||||||
|
<ng-container [ngTemplateOutlet]="getTemplate(column)" [ngTemplateOutletContext]="{ $implicit: item }"></ng-container>
|
||||||
|
} @else if (column.canCopy) {
|
||||||
|
<uikit-copy [text]="getCell(item, column)"></uikit-copy>
|
||||||
|
} @else {
|
||||||
|
<span [class]="getPreviewClasses(item, column)">{{ getCell(item, column) }}</span>
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
export class PageDataValueComponent {
|
||||||
|
@Input({ required: true }) item!: Record<string, any>;
|
||||||
|
@Input({ required: true }) column!: IColumn;
|
||||||
|
@Output() thumbnailClick = new EventEmitter<any>();
|
||||||
|
|
||||||
|
readFieldValue(item: Record<string, any>, field: IColumn['field']) {
|
||||||
|
return item?.[String(field)];
|
||||||
|
}
|
||||||
|
|
||||||
|
getPreviewClasses(item: Record<string, any>, column: IColumn): string {
|
||||||
|
if (!item || !column || column.customDataModel) return '';
|
||||||
|
const data = item[String(column.field)];
|
||||||
|
if (column.type === 'date' && column.dateOption?.expiredMode && jalaliDiff(new Date(), data) > 0) {
|
||||||
|
return 'text-error';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
getCell(item: Record<string, any>, column: IColumn): any {
|
||||||
|
if (!item || !column) return '';
|
||||||
|
let { field, type } = column;
|
||||||
|
|
||||||
|
if (column.customDataModel) {
|
||||||
|
return this.renderCustom(column, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = item[String(field)];
|
||||||
|
if (column.type === 'nested') {
|
||||||
|
const path = column.nestedOption?.path;
|
||||||
|
if (!path) return '-';
|
||||||
|
data = path.split('.').reduce((obj: any, key: string) => (obj && obj[key] !== undefined ? obj[key] : null), item);
|
||||||
|
type = column.nestedOption?.type || 'simple';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'id':
|
||||||
|
return data ? `${data.slice(0, 5)}...${data.slice(data.length - 5)}` : '-';
|
||||||
|
case 'date':
|
||||||
|
return data ? formatJalali(data) : '-';
|
||||||
|
case 'boolean':
|
||||||
|
return data ? 'بله' : 'خیر';
|
||||||
|
case 'price':
|
||||||
|
return formatWithCurrency(data, false, 'ریال');
|
||||||
|
case 'number':
|
||||||
|
return data || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data === undefined || data === null) return '-';
|
||||||
|
if (typeof data === 'object') return data.title || '-';
|
||||||
|
return data || '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
getTemplate(col: IColumn): TemplateRef<any> | null {
|
||||||
|
const v = col.customDataModel;
|
||||||
|
return v instanceof TemplateRef ? (v as TemplateRef<any>) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCustom(column: IColumn, item: any): any {
|
||||||
|
const v = column.customDataModel;
|
||||||
|
if (!v) return null;
|
||||||
|
if (typeof v === 'function') {
|
||||||
|
try {
|
||||||
|
return (v as (item: any) => any)(item);
|
||||||
|
} catch {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (typeof v === 'string') return v;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
-2
@@ -31,6 +31,9 @@ const MyPreset = definePreset(Aura, {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
semantic: {
|
semantic: {
|
||||||
|
...updateSurfacePalette({
|
||||||
|
0: '#fcfcfc',
|
||||||
|
}),
|
||||||
primary: {
|
primary: {
|
||||||
0: '{surface.0}',
|
0: '{surface.0}',
|
||||||
50: '{surface.50}',
|
50: '{surface.50}',
|
||||||
@@ -45,9 +48,27 @@ const MyPreset = definePreset(Aura, {
|
|||||||
900: '{surface.900}',
|
900: '{surface.900}',
|
||||||
950: '{surface.950}',
|
950: '{surface.950}',
|
||||||
},
|
},
|
||||||
|
|
||||||
colorScheme: {
|
colorScheme: {
|
||||||
|
colorScheme: {
|
||||||
|
light: {},
|
||||||
|
dark: {},
|
||||||
|
},
|
||||||
light: {
|
light: {
|
||||||
|
surface: {
|
||||||
|
0: '#fcfcfc',
|
||||||
|
50: '#f8fafc',
|
||||||
|
100: '#f1f5f9',
|
||||||
|
200: '#e2e8f0',
|
||||||
|
300: '#cbd5e1',
|
||||||
|
400: '#94a3b8',
|
||||||
|
500: '#64748b',
|
||||||
|
600: '#475569',
|
||||||
|
700: '#334155',
|
||||||
|
800: '#1e293b',
|
||||||
|
900: '#0f172a',
|
||||||
|
950: '#020617',
|
||||||
|
},
|
||||||
|
|
||||||
primary: {
|
primary: {
|
||||||
color: '{primary.950}',
|
color: '{primary.950}',
|
||||||
contrastColor: '#f0f0f0',
|
contrastColor: '#f0f0f0',
|
||||||
@@ -79,7 +100,7 @@ const MyPreset = definePreset(Aura, {
|
|||||||
},
|
},
|
||||||
primitive: {
|
primitive: {
|
||||||
...updateSurfacePalette({
|
...updateSurfacePalette({
|
||||||
0: '#f0f0f0',
|
0: '#fcfcfc',
|
||||||
50: '#f8fafc',
|
50: '#f8fafc',
|
||||||
100: '#f1f5f9',
|
100: '#f1f5f9',
|
||||||
200: '#e2e8f0',
|
200: '#e2e8f0',
|
||||||
|
|||||||
Reference in New Issue
Block a user