@haloduck/ui 2.0.28 → 2.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/haloduck-ui.mjs +116 -108
- package/fesm2022/haloduck-ui.mjs.map +1 -1
- package/index.d.ts +28 -17
- package/package.json +1 -1
package/fesm2022/haloduck-ui.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, Input, Component, inject, ChangeDetectorRef, forwardRef, ViewChild, signal, EventEmitter, Output, ViewContainerRef, NgZone, isDevMode,
|
|
2
|
+
import { Injectable, Input, Component, inject, ChangeDetectorRef, forwardRef, ViewChild, signal, EventEmitter, Output, ViewContainerRef, NgZone, isDevMode, ElementRef, Directive, ChangeDetectionStrategy, HostBinding } from '@angular/core';
|
|
3
3
|
import { signIn, confirmSignIn, resetPassword, confirmResetPassword } from 'aws-amplify/auth';
|
|
4
4
|
import * as i1$1 from '@angular/forms';
|
|
5
5
|
import { NG_VALUE_ACCESSOR, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
6
|
-
import { BehaviorSubject, zip, Subject, takeUntil, tap, combineLatest, switchMap, of, Observable, distinctUntilChanged, map, take
|
|
6
|
+
import { BehaviorSubject, zip, Subject, takeUntil, tap, combineLatest, switchMap, of, Observable, distinctUntilChanged, map, take } from 'rxjs';
|
|
7
7
|
import { ulid } from 'ulid';
|
|
8
8
|
import * as i1 from '@angular/common';
|
|
9
9
|
import { CommonModule, DecimalPipe, DatePipe } from '@angular/common';
|
|
@@ -2888,11 +2888,106 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
2888
2888
|
args: ['viewerContainer']
|
|
2889
2889
|
}] } });
|
|
2890
2890
|
|
|
2891
|
+
class AutoLoadDirective {
|
|
2892
|
+
elementRef = inject(ElementRef);
|
|
2893
|
+
ngZone = inject(NgZone);
|
|
2894
|
+
observer;
|
|
2895
|
+
isLoading = false;
|
|
2896
|
+
hasTriggeredOnce = false;
|
|
2897
|
+
autoLoadEnabled = true;
|
|
2898
|
+
autoLoadThreshold = 0.1;
|
|
2899
|
+
autoLoadRootMargin = '0px';
|
|
2900
|
+
autoLoadTrigger = new EventEmitter();
|
|
2901
|
+
ngOnInit() {
|
|
2902
|
+
if (this.autoLoadEnabled && 'IntersectionObserver' in window) {
|
|
2903
|
+
this.initializeObserver();
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
ngOnDestroy() {
|
|
2907
|
+
this.disconnect();
|
|
2908
|
+
}
|
|
2909
|
+
initializeObserver() {
|
|
2910
|
+
this.ngZone.runOutsideAngular(() => {
|
|
2911
|
+
this.observer = new IntersectionObserver((entries) => {
|
|
2912
|
+
entries.forEach((entry) => {
|
|
2913
|
+
if (entry.isIntersecting && !this.isLoading) {
|
|
2914
|
+
this.ngZone.run(() => {
|
|
2915
|
+
this.triggerLoad();
|
|
2916
|
+
});
|
|
2917
|
+
}
|
|
2918
|
+
});
|
|
2919
|
+
}, {
|
|
2920
|
+
threshold: this.autoLoadThreshold,
|
|
2921
|
+
rootMargin: this.autoLoadRootMargin,
|
|
2922
|
+
});
|
|
2923
|
+
this.observer.observe(this.elementRef.nativeElement);
|
|
2924
|
+
});
|
|
2925
|
+
}
|
|
2926
|
+
triggerLoad() {
|
|
2927
|
+
if (this.isLoading || !this.autoLoadEnabled) {
|
|
2928
|
+
return;
|
|
2929
|
+
}
|
|
2930
|
+
// 첫 번째 로드는 건너뛰고, 이후부터는 보일 때마다 자동 로드
|
|
2931
|
+
if (this.hasTriggeredOnce) {
|
|
2932
|
+
this.isLoading = true;
|
|
2933
|
+
this.autoLoadTrigger.emit();
|
|
2934
|
+
// 옵저버를 일시적으로 해제하여 연속 트리거 방지
|
|
2935
|
+
this.temporarilyDisableObserver();
|
|
2936
|
+
}
|
|
2937
|
+
else {
|
|
2938
|
+
this.hasTriggeredOnce = true;
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
temporarilyDisableObserver() {
|
|
2942
|
+
if (this.observer) {
|
|
2943
|
+
this.observer.disconnect();
|
|
2944
|
+
// 1초 후 옵저버 재연결
|
|
2945
|
+
setTimeout(() => {
|
|
2946
|
+
if (this.autoLoadEnabled && this.observer) {
|
|
2947
|
+
this.isLoading = false;
|
|
2948
|
+
this.observer.observe(this.elementRef.nativeElement);
|
|
2949
|
+
}
|
|
2950
|
+
}, 1000);
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
disconnect() {
|
|
2954
|
+
if (this.observer) {
|
|
2955
|
+
this.observer.disconnect();
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
// 외부에서 로딩 상태를 제어할 수 있는 메서드
|
|
2959
|
+
setLoadingState(loading) {
|
|
2960
|
+
this.isLoading = loading;
|
|
2961
|
+
}
|
|
2962
|
+
// 자동 로드를 재활성화하는 메서드
|
|
2963
|
+
resetAutoLoad() {
|
|
2964
|
+
this.hasTriggeredOnce = false;
|
|
2965
|
+
this.isLoading = false;
|
|
2966
|
+
}
|
|
2967
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AutoLoadDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2968
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.4", type: AutoLoadDirective, isStandalone: true, selector: "[haloduckAutoLoad]", inputs: { autoLoadEnabled: "autoLoadEnabled", autoLoadThreshold: "autoLoadThreshold", autoLoadRootMargin: "autoLoadRootMargin" }, outputs: { autoLoadTrigger: "autoLoadTrigger" }, ngImport: i0 });
|
|
2969
|
+
}
|
|
2970
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AutoLoadDirective, decorators: [{
|
|
2971
|
+
type: Directive,
|
|
2972
|
+
args: [{
|
|
2973
|
+
selector: '[haloduckAutoLoad]',
|
|
2974
|
+
standalone: true,
|
|
2975
|
+
}]
|
|
2976
|
+
}], propDecorators: { autoLoadEnabled: [{
|
|
2977
|
+
type: Input
|
|
2978
|
+
}], autoLoadThreshold: [{
|
|
2979
|
+
type: Input
|
|
2980
|
+
}], autoLoadRootMargin: [{
|
|
2981
|
+
type: Input
|
|
2982
|
+
}], autoLoadTrigger: [{
|
|
2983
|
+
type: Output
|
|
2984
|
+
}] } });
|
|
2985
|
+
|
|
2891
2986
|
class TableComponent {
|
|
2892
2987
|
coreService = inject(CoreService);
|
|
2893
|
-
|
|
2894
|
-
destroyRef = inject(DestroyRef);
|
|
2988
|
+
loadMoreRowRef;
|
|
2895
2989
|
tableLayout = 'auto';
|
|
2990
|
+
autoLoad = true;
|
|
2896
2991
|
showHeader = true;
|
|
2897
2992
|
useLoadMore = true;
|
|
2898
2993
|
columns = [];
|
|
@@ -2907,12 +3002,6 @@ class TableComponent {
|
|
|
2907
3002
|
onLoadMore = new EventEmitter();
|
|
2908
3003
|
onRowClick = new EventEmitter();
|
|
2909
3004
|
onRowDblClick = new EventEmitter();
|
|
2910
|
-
loadMoreRow;
|
|
2911
|
-
dataRows;
|
|
2912
|
-
scrollContainer;
|
|
2913
|
-
intersectionObserver;
|
|
2914
|
-
scrollListenerTarget;
|
|
2915
|
-
didScrollSinceLastLoad = false;
|
|
2916
3005
|
getColumnValue(row, column) {
|
|
2917
3006
|
const value = this.getColumnValueRaw(row, column);
|
|
2918
3007
|
if (column.customRenderFn) {
|
|
@@ -2992,6 +3081,13 @@ class TableComponent {
|
|
|
2992
3081
|
this.onLoadMore.emit(lastEvaluatedKey);
|
|
2993
3082
|
});
|
|
2994
3083
|
}
|
|
3084
|
+
onAutoLoadTriggered() {
|
|
3085
|
+
if (this.autoLoad) {
|
|
3086
|
+
this.lastEvaluatedKey.pipe(take(1)).subscribe((lastEvaluatedKey) => {
|
|
3087
|
+
this.onLoadMore.emit(lastEvaluatedKey);
|
|
3088
|
+
});
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
2995
3091
|
onRowClicked(row) {
|
|
2996
3092
|
this.onRowClick.emit(row);
|
|
2997
3093
|
}
|
|
@@ -2999,99 +3095,20 @@ class TableComponent {
|
|
|
2999
3095
|
this.onRowDblClick.emit(row);
|
|
3000
3096
|
}
|
|
3001
3097
|
ngOnInit() { }
|
|
3002
|
-
ngAfterViewInit() {
|
|
3003
|
-
if (!this.useLoadMore)
|
|
3004
|
-
return;
|
|
3005
|
-
combineLatest([this.rows, this.lastEvaluatedKey, this.isLoading])
|
|
3006
|
-
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
3007
|
-
.subscribe(() => {
|
|
3008
|
-
this.setupIntersectionObserver();
|
|
3009
|
-
});
|
|
3010
|
-
// 데이터 행 렌더링 변화에 맞춰 센티널 타겟을 재지정
|
|
3011
|
-
this.dataRows?.changes
|
|
3012
|
-
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
3013
|
-
.subscribe(() => {
|
|
3014
|
-
this.setupIntersectionObserver();
|
|
3015
|
-
});
|
|
3016
|
-
const container = this.scrollContainer?.nativeElement;
|
|
3017
|
-
this.scrollListenerTarget = container || (typeof window !== 'undefined' ? window : undefined);
|
|
3018
|
-
if (this.scrollListenerTarget) {
|
|
3019
|
-
this.scrollListenerTarget.addEventListener('scroll', this.onScroll, { passive: true });
|
|
3020
|
-
}
|
|
3021
|
-
}
|
|
3022
|
-
ngOnDestroy() {
|
|
3023
|
-
this.cleanupIntersectionObserver();
|
|
3024
|
-
if (this.scrollListenerTarget) {
|
|
3025
|
-
this.scrollListenerTarget.removeEventListener('scroll', this.onScroll);
|
|
3026
|
-
this.scrollListenerTarget = undefined;
|
|
3027
|
-
}
|
|
3028
|
-
}
|
|
3029
|
-
setupIntersectionObserver() {
|
|
3030
|
-
if (!this.useLoadMore)
|
|
3031
|
-
return;
|
|
3032
|
-
this.cleanupIntersectionObserver();
|
|
3033
|
-
const rootElement = this.scrollContainer?.nativeElement || null;
|
|
3034
|
-
// 우선순위: 마지막 데이터 행 -> 로드모어 행
|
|
3035
|
-
const lastRowEl = this.dataRows?.last?.nativeElement;
|
|
3036
|
-
const target = lastRowEl || this.loadMoreRow?.nativeElement;
|
|
3037
|
-
if (!target)
|
|
3038
|
-
return;
|
|
3039
|
-
// 새로운 옵저버 생성 시 초기 교차 무시 플래그 초기화
|
|
3040
|
-
this.hasObservedOnce = false;
|
|
3041
|
-
// 스크롤 발생 전에는 자동 로드를 막음
|
|
3042
|
-
this.didScrollSinceLastLoad = false;
|
|
3043
|
-
this.ngZone.runOutsideAngular(() => {
|
|
3044
|
-
this.intersectionObserver = new IntersectionObserver(this.onIntersection, {
|
|
3045
|
-
root: rootElement || undefined,
|
|
3046
|
-
rootMargin: '0px 0px 200px 0px',
|
|
3047
|
-
threshold: 0.05,
|
|
3048
|
-
});
|
|
3049
|
-
this.intersectionObserver.observe(target);
|
|
3050
|
-
});
|
|
3051
|
-
}
|
|
3052
|
-
cleanupIntersectionObserver() {
|
|
3053
|
-
if (this.intersectionObserver) {
|
|
3054
|
-
this.intersectionObserver.disconnect();
|
|
3055
|
-
this.intersectionObserver = undefined;
|
|
3056
|
-
}
|
|
3057
|
-
}
|
|
3058
|
-
hasObservedOnce = false;
|
|
3059
|
-
onIntersection = (entries) => {
|
|
3060
|
-
for (const entry of entries) {
|
|
3061
|
-
if (!entry.isIntersecting)
|
|
3062
|
-
continue;
|
|
3063
|
-
// 첫 교차는 무시하여 초기 붙자마자의 즉시 트리거 방지
|
|
3064
|
-
if (!this.hasObservedOnce) {
|
|
3065
|
-
this.hasObservedOnce = true;
|
|
3066
|
-
continue;
|
|
3067
|
-
}
|
|
3068
|
-
// 마지막 키가 존재, 로딩 아님, 그리고 실제 스크롤이 있었을 때만 로드
|
|
3069
|
-
Promise.all([
|
|
3070
|
-
firstValueFrom(this.lastEvaluatedKey.pipe(take(1))),
|
|
3071
|
-
firstValueFrom(this.isLoading.pipe(take(1))),
|
|
3072
|
-
]).then(([lastKey, isLoading]) => {
|
|
3073
|
-
if (!(lastKey && !isLoading && this.didScrollSinceLastLoad)) {
|
|
3074
|
-
return;
|
|
3075
|
-
}
|
|
3076
|
-
// 중복 호출 방지: 즉시 관찰 해제 후 로드 트리거
|
|
3077
|
-
this.cleanupIntersectionObserver();
|
|
3078
|
-
this.didScrollSinceLastLoad = false;
|
|
3079
|
-
this.ngZone.run(() => this.onLoadMoreClicked());
|
|
3080
|
-
});
|
|
3081
|
-
}
|
|
3082
|
-
};
|
|
3083
|
-
onScroll = () => {
|
|
3084
|
-
this.didScrollSinceLastLoad = true;
|
|
3085
|
-
};
|
|
3086
|
-
// Note: 무스크롤 자동 로드는 연속 로딩을 유발할 수 있어 제거
|
|
3098
|
+
ngAfterViewInit() { }
|
|
3087
3099
|
constructor() { }
|
|
3088
3100
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3089
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: TableComponent, isStandalone: true, selector: "haloduck-table", inputs: { tableLayout: "tableLayout", showHeader: "showHeader", useLoadMore: "useLoadMore", columns: "columns", rows: "rows", isLoading: "isLoading", isPaging: "isPaging", sort: "sort", expandedTemplate: "expandedTemplate", customTemplates: "customTemplates", lastEvaluatedKey: "lastEvaluatedKey" }, outputs: { onSortChange: "onSortChange", onLoadMore: "onLoadMore", onRowClick: "onRowClick", onRowDblClick: "onRowDblClick" }, providers: [provideTranslocoScope('haloduck')], viewQueries: [{ propertyName: "
|
|
3101
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.4", type: TableComponent, isStandalone: true, selector: "haloduck-table", inputs: { tableLayout: "tableLayout", autoLoad: "autoLoad", showHeader: "showHeader", useLoadMore: "useLoadMore", columns: "columns", rows: "rows", isLoading: "isLoading", isPaging: "isPaging", sort: "sort", expandedTemplate: "expandedTemplate", customTemplates: "customTemplates", lastEvaluatedKey: "lastEvaluatedKey" }, outputs: { onSortChange: "onSortChange", onLoadMore: "onLoadMore", onRowClick: "onRowClick", onRowDblClick: "onRowDblClick" }, providers: [provideTranslocoScope('haloduck')], viewQueries: [{ propertyName: "loadMoreRowRef", first: true, predicate: ["loadMoreRow"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"w-full h-full shadow border border-light-inactive dark:border-dark-inactive rounded-lg overflow-auto\">\n <table class=\"w-full h-full\"\n [ngClass]=\"{\n 'table-fixed': tableLayout === 'fixed',\n 'table-auto': tableLayout === 'auto',\n }\">\n <colgroup>\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <col class=\"{{ column.width || '' }}\" />\n }\n }\n </colgroup>\n @if (showHeader) {\n <thead class=\"bg-light-inactive/50 dark:bg-dark-inactive/50 rounded-tl-lg rounded-tr-lg\">\n <tr>\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <th scope=\"col\"\n class=\"{{ column.align || '' }} py-3.5 pl-4 pr-3 text-sm font-semibold text-light-on-background dark:text-dark-on-background whitespace-nowrap\">\n <span class=\"group inline-flex\">\n {{ column.label }}\n @if (column.sortable) {\n @switch (getSortDirection(column.sort?.field || column.key) | async)\n {\n @case('desc') {\n <span (click)=\"onUpdateSort(column.sort?.field || column.key, 'asc')\"\n class=\"ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive\">\n <svg class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\">\n <path fill-rule=\"evenodd\"\n d=\"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\" />\n </svg>\n </span>\n }\n @case('asc') {\n <span (click)=\"onUpdateSort(column.sort?.field || column.key, 'desc')\"\n class=\"ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive\">\n <svg class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\">\n <path fill-rule=\"evenodd\"\n d=\"M14.78 11.78a.75.75 0 0 1-1.06 0L10 8.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06Z\"\n clip-rule=\"evenodd\" />\n </svg>\n </span>\n }\n @default {\n <span (click)=\"onUpdateSort(column.sort?.field || column.key, 'asc')\"\n class=\"invisible ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive group-hover:visible group-focus:visible\">\n <svg class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\">\n <path fill-rule=\"evenodd\"\n d=\"M14.78 11.78a.75.75 0 0 1-1.06 0L10 8.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06Z\"\n clip-rule=\"evenodd\" />\n </svg>\n </span>\n }\n }\n }\n </span>\n </th>\n }\n }\n </tr>\n </thead>\n }\n <tbody class=\"overflow-scroll\">\n @for (row of rows | async; track row['id']; let lastRow = $last) {\n <tr class=\"border-t border-light-inactive dark:border-dark-inactive {{ row.bgColor || '' }}\"\n (click)=\"onRowClicked(row)\"\n (dblclick)=\"onRowDblClicked(row)\"\n [ngClass]=\"{'rounded-b-lg': lastRow && (lastEvaluatedKey | async) === null, 'even:bg-light-alternative dark:even:bg-dark-alternative odd:bg-light-background dark:odd:bg-dark-background': !row.bgColor }\"\n [ngStyle]=\"{ 'background-color': row.bgColor || '' }\">\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <td class=\"relative overflow-visible {{ column.align || '' }} whitespace-nowrap px-3 text-sm text-light-on-background dark:text-dark-on-background\"\n [ngClass]=\"{\n 'first:rounded-bl-lg last:rounded-br-lg': lastRow && (lastEvaluatedKey | async) === null,\n 'text-wrap': row.isExpanded && column.type !== 'custom',\n 'overflow-x-hidden text-ellipsis' : !row.isExpanded && column.type !== 'custom',\n 'py-2': column.type === 'custom',\n 'py-4': column.type !== 'custom'\n }\">\n @if (column.type === 'custom') {\n @if (column.customRenderTemplate) {\n <ng-container [ngTemplateOutlet]=\"customTemplates[column.customRenderTemplate]\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"></ng-container>\n }\n }\n @else {\n {{ getColumnValue(row, column) | async }}\n }\n </td>\n }\n }\n </tr>\n\n @if (row.isExpanded && expandedTemplate) {\n <tr>\n <td [attr.colspan]=\"columns.length\">\n </td>\n </tr>\n <tr class=\"even:bg-light-alternative dark:even:bg-dark-alternative odd:bg-light-background dark:odd:bg-dark-background\">\n <td [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 pb-4 text-sm text-center\">\n <ng-container [ngTemplateOutlet]=\"expandedTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row }\"></ng-container>\n </td>\n </tr>\n }\n\n @if (lastRow && (lastEvaluatedKey | async) && !(isLoading | async) && useLoadMore) {\n <tr #loadMoreRow \n class=\"border-t border-light-inactive dark:border-dark-inactive bg-light-background dark:bg-dark-background\"\n haloduckAutoLoad\n [autoLoadEnabled]=\"autoLoad\"\n [autoLoadThreshold]=\"0.1\"\n (autoLoadTrigger)=\"onAutoLoadTriggered()\">\n <td [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 py-4 text-sm text-light-on-background dark:text-dark-on-background text-center h-16 bg-light-background dark:bg-dark-background rounded-bl-lg rounded-br-lg\">\n <div (click)=\"onLoadMoreClicked()\"\n class=\"cursor-pointer\">\n {{ 'haloduck.ui.table.Load More...' | transloco }}\n </div>\n </td>\n </tr>\n }\n\n } @empty {\n @if(!(isLoading | async)) {\n <tr>\n <td [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 py-4 text-sm text-light-on-background dark:text-dark-on-background text-center h-16 bg-light-background dark:bg-dark-background rounded-bl-lg rounded-br-lg\">\n {{ 'haloduck.ui.table.No data available.' | transloco }}\n </td>\n </tr>\n }\n }\n\n @if(isLoading | async) {\n @for ( i of [0,1,2,3,4]; track i; let lastRow = $last)\n {\n <tr class=\"bg-light-background dark:bg-dark-background border-t border-light-inactive/50 dark:border-dark-inactive/50\">\n @for (column of columns; track column.key) {\n <td class=\"whitespace-nowrap py-4 pl-4 pr-3 text-sm\"\n [ngClass]=\"{'first:rounded-bl-lg last:rounded-br-lg': lastRow}\">\n <div class=\"h-4 bg-light-inactive/50 dark:bg-dark-inactive/50 rounded-md animate-pulse\"></div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "directive", type: AutoLoadDirective, selector: "[haloduckAutoLoad]", inputs: ["autoLoadEnabled", "autoLoadThreshold", "autoLoadRootMargin"], outputs: ["autoLoadTrigger"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$1.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3090
3102
|
}
|
|
3091
3103
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: TableComponent, decorators: [{
|
|
3092
3104
|
type: Component,
|
|
3093
|
-
args: [{ selector: 'haloduck-table', imports: [CommonModule, TranslocoModule], providers: [provideTranslocoScope('haloduck')], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div
|
|
3094
|
-
}], ctorParameters: () => [], propDecorators: {
|
|
3105
|
+
args: [{ selector: 'haloduck-table', imports: [CommonModule, TranslocoModule, AutoLoadDirective], providers: [provideTranslocoScope('haloduck')], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"w-full h-full shadow border border-light-inactive dark:border-dark-inactive rounded-lg overflow-auto\">\n <table class=\"w-full h-full\"\n [ngClass]=\"{\n 'table-fixed': tableLayout === 'fixed',\n 'table-auto': tableLayout === 'auto',\n }\">\n <colgroup>\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <col class=\"{{ column.width || '' }}\" />\n }\n }\n </colgroup>\n @if (showHeader) {\n <thead class=\"bg-light-inactive/50 dark:bg-dark-inactive/50 rounded-tl-lg rounded-tr-lg\">\n <tr>\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <th scope=\"col\"\n class=\"{{ column.align || '' }} py-3.5 pl-4 pr-3 text-sm font-semibold text-light-on-background dark:text-dark-on-background whitespace-nowrap\">\n <span class=\"group inline-flex\">\n {{ column.label }}\n @if (column.sortable) {\n @switch (getSortDirection(column.sort?.field || column.key) | async)\n {\n @case('desc') {\n <span (click)=\"onUpdateSort(column.sort?.field || column.key, 'asc')\"\n class=\"ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive\">\n <svg class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\">\n <path fill-rule=\"evenodd\"\n d=\"M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z\"\n clip-rule=\"evenodd\" />\n </svg>\n </span>\n }\n @case('asc') {\n <span (click)=\"onUpdateSort(column.sort?.field || column.key, 'desc')\"\n class=\"ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive\">\n <svg class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\">\n <path fill-rule=\"evenodd\"\n d=\"M14.78 11.78a.75.75 0 0 1-1.06 0L10 8.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06Z\"\n clip-rule=\"evenodd\" />\n </svg>\n </span>\n }\n @default {\n <span (click)=\"onUpdateSort(column.sort?.field || column.key, 'asc')\"\n class=\"invisible ml-2 flex-none rounded text-light-on-inactive dark:text-dark-on-inactive group-hover:visible group-focus:visible\">\n <svg class=\"size-5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n data-slot=\"icon\">\n <path fill-rule=\"evenodd\"\n d=\"M14.78 11.78a.75.75 0 0 1-1.06 0L10 8.06l-3.72 3.72a.75.75 0 1 1-1.06-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06Z\"\n clip-rule=\"evenodd\" />\n </svg>\n </span>\n }\n }\n }\n </span>\n </th>\n }\n }\n </tr>\n </thead>\n }\n <tbody class=\"overflow-scroll\">\n @for (row of rows | async; track row['id']; let lastRow = $last) {\n <tr class=\"border-t border-light-inactive dark:border-dark-inactive {{ row.bgColor || '' }}\"\n (click)=\"onRowClicked(row)\"\n (dblclick)=\"onRowDblClicked(row)\"\n [ngClass]=\"{'rounded-b-lg': lastRow && (lastEvaluatedKey | async) === null, 'even:bg-light-alternative dark:even:bg-dark-alternative odd:bg-light-background dark:odd:bg-dark-background': !row.bgColor }\"\n [ngStyle]=\"{ 'background-color': row.bgColor || '' }\">\n @for (column of columns; track column.key) {\n @if (!column.hidden || !(column.hidden | async)) {\n <td class=\"relative overflow-visible {{ column.align || '' }} whitespace-nowrap px-3 text-sm text-light-on-background dark:text-dark-on-background\"\n [ngClass]=\"{\n 'first:rounded-bl-lg last:rounded-br-lg': lastRow && (lastEvaluatedKey | async) === null,\n 'text-wrap': row.isExpanded && column.type !== 'custom',\n 'overflow-x-hidden text-ellipsis' : !row.isExpanded && column.type !== 'custom',\n 'py-2': column.type === 'custom',\n 'py-4': column.type !== 'custom'\n }\">\n @if (column.type === 'custom') {\n @if (column.customRenderTemplate) {\n <ng-container [ngTemplateOutlet]=\"customTemplates[column.customRenderTemplate]\"\n [ngTemplateOutletContext]=\"{ $implicit: row, column: column }\"></ng-container>\n }\n }\n @else {\n {{ getColumnValue(row, column) | async }}\n }\n </td>\n }\n }\n </tr>\n\n @if (row.isExpanded && expandedTemplate) {\n <tr>\n <td [attr.colspan]=\"columns.length\">\n </td>\n </tr>\n <tr class=\"even:bg-light-alternative dark:even:bg-dark-alternative odd:bg-light-background dark:odd:bg-dark-background\">\n <td [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 pb-4 text-sm text-center\">\n <ng-container [ngTemplateOutlet]=\"expandedTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row }\"></ng-container>\n </td>\n </tr>\n }\n\n @if (lastRow && (lastEvaluatedKey | async) && !(isLoading | async) && useLoadMore) {\n <tr #loadMoreRow \n class=\"border-t border-light-inactive dark:border-dark-inactive bg-light-background dark:bg-dark-background\"\n haloduckAutoLoad\n [autoLoadEnabled]=\"autoLoad\"\n [autoLoadThreshold]=\"0.1\"\n (autoLoadTrigger)=\"onAutoLoadTriggered()\">\n <td [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 py-4 text-sm text-light-on-background dark:text-dark-on-background text-center h-16 bg-light-background dark:bg-dark-background rounded-bl-lg rounded-br-lg\">\n <div (click)=\"onLoadMoreClicked()\"\n class=\"cursor-pointer\">\n {{ 'haloduck.ui.table.Load More...' | transloco }}\n </div>\n </td>\n </tr>\n }\n\n } @empty {\n @if(!(isLoading | async)) {\n <tr>\n <td [attr.colspan]=\"columns.length\"\n class=\"whitespace-nowrap px-3 py-4 text-sm text-light-on-background dark:text-dark-on-background text-center h-16 bg-light-background dark:bg-dark-background rounded-bl-lg rounded-br-lg\">\n {{ 'haloduck.ui.table.No data available.' | transloco }}\n </td>\n </tr>\n }\n }\n\n @if(isLoading | async) {\n @for ( i of [0,1,2,3,4]; track i; let lastRow = $last)\n {\n <tr class=\"bg-light-background dark:bg-dark-background border-t border-light-inactive/50 dark:border-dark-inactive/50\">\n @for (column of columns; track column.key) {\n <td class=\"whitespace-nowrap py-4 pl-4 pr-3 text-sm\"\n [ngClass]=\"{'first:rounded-bl-lg last:rounded-br-lg': lastRow}\">\n <div class=\"h-4 bg-light-inactive/50 dark:bg-dark-inactive/50 rounded-md animate-pulse\"></div>\n </td>\n }\n </tr>\n }\n }\n </tbody>\n </table>\n</div>\n" }]
|
|
3106
|
+
}], ctorParameters: () => [], propDecorators: { loadMoreRowRef: [{
|
|
3107
|
+
type: ViewChild,
|
|
3108
|
+
args: ['loadMoreRow', { read: ElementRef }]
|
|
3109
|
+
}], tableLayout: [{
|
|
3110
|
+
type: Input
|
|
3111
|
+
}], autoLoad: [{
|
|
3095
3112
|
type: Input
|
|
3096
3113
|
}], showHeader: [{
|
|
3097
3114
|
type: Input
|
|
@@ -3121,15 +3138,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
3121
3138
|
type: Output
|
|
3122
3139
|
}], onRowDblClick: [{
|
|
3123
3140
|
type: Output
|
|
3124
|
-
}], loadMoreRow: [{
|
|
3125
|
-
type: ViewChild,
|
|
3126
|
-
args: ['loadMoreRow']
|
|
3127
|
-
}], dataRows: [{
|
|
3128
|
-
type: ViewChildren,
|
|
3129
|
-
args: ['dataRow', { read: ElementRef }]
|
|
3130
|
-
}], scrollContainer: [{
|
|
3131
|
-
type: ViewChild,
|
|
3132
|
-
args: ['scrollContainer', { static: true }]
|
|
3133
3141
|
}] } });
|
|
3134
3142
|
|
|
3135
3143
|
class ToggleComponent {
|
|
@@ -3731,5 +3739,5 @@ const provideHaloduckTransloco = () => provideTranslocoScope({
|
|
|
3731
3739
|
* Generated bundle index. Do not edit.
|
|
3732
3740
|
*/
|
|
3733
3741
|
|
|
3734
|
-
export { AuthenticateComponent, BreadcrumbComponent, ButtonComponent, CalendarComponent, ConfirmDialogService, CopyButtonComponent, DatePickerComponent, DateRangeComponent, DialogService, DrawCanvasComponent, ERROR_NOT_ACCEPTABLE_FILE_TYPE, ERROR_OVER_COUNT, ERROR_OVER_SIZE, ERROR_UPLOAD, FileUploaderComponent, FlipComponent, GroupedDirective, ImageUploaderComponent, ImageViewerComponent, InputComponent, LanguageSelectorComponent, MapToAddressComponent, NotificationComponent, NotificationService, PictureNameComponent, SelectComponent, SelectDropdownComponent, SideMenuComponent, SideMenuItemComponent, StlViewerComponent, TableComponent, TabsComponent, TagInputComponent, TagViewerComponent, ToggleComponent, dateToString, provideHaloduckTransloco };
|
|
3742
|
+
export { AuthenticateComponent, AutoLoadDirective, BreadcrumbComponent, ButtonComponent, CalendarComponent, ConfirmDialogService, CopyButtonComponent, DatePickerComponent, DateRangeComponent, DialogService, DrawCanvasComponent, ERROR_NOT_ACCEPTABLE_FILE_TYPE, ERROR_OVER_COUNT, ERROR_OVER_SIZE, ERROR_UPLOAD, FileUploaderComponent, FlipComponent, GroupedDirective, ImageUploaderComponent, ImageViewerComponent, InputComponent, LanguageSelectorComponent, MapToAddressComponent, NotificationComponent, NotificationService, PictureNameComponent, SelectComponent, SelectDropdownComponent, SideMenuComponent, SideMenuItemComponent, StlViewerComponent, TableComponent, TabsComponent, TagInputComponent, TagViewerComponent, ToggleComponent, dateToString, provideHaloduckTransloco };
|
|
3735
3743
|
//# sourceMappingURL=haloduck-ui.mjs.map
|