@devjuliovilla/jv-ui 1.5.3 → 1.5.5
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/README.md +268 -65
- package/fesm2022/devjuliovilla-jv-ui.mjs +881 -323
- package/fesm2022/devjuliovilla-jv-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/devjuliovilla-jv-ui.d.ts +114 -5
|
@@ -17843,47 +17843,47 @@ class JvIconComponent {
|
|
|
17843
17843
|
return JV_LUCIDE_ICON_REGISTRY[JV_FALLBACK_ICON_NAME];
|
|
17844
17844
|
}, ...(ngDevMode ? [{ debugName: "iconDefinition" }] : /* istanbul ignore next */ []));
|
|
17845
17845
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
17846
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvIconComponent, isStandalone: true, selector: "jv-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, decorative: { classPropertyName: "decorative", publicName: "decorative", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
17847
|
-
<svg
|
|
17848
|
-
class="jv-icon"
|
|
17849
|
-
[attr.viewBox]="iconDefinition().viewBox"
|
|
17850
|
-
[attr.width]="size()"
|
|
17851
|
-
[attr.height]="size()"
|
|
17852
|
-
[attr.stroke-width]="strokeWidth()"
|
|
17853
|
-
[attr.role]="decorative() ? 'presentation' : 'img'"
|
|
17854
|
-
[attr.aria-hidden]="decorative() ? 'true' : null"
|
|
17855
|
-
[attr.aria-label]="decorative() ? null : ariaLabel() || normalizedName()"
|
|
17856
|
-
fill="none"
|
|
17857
|
-
stroke="currentColor"
|
|
17858
|
-
stroke-linecap="round"
|
|
17859
|
-
stroke-linejoin="round"
|
|
17860
|
-
>
|
|
17861
|
-
@for (element of iconDefinition().elements; track $index) {
|
|
17862
|
-
@switch (element.tag) {
|
|
17863
|
-
@case ('path') {
|
|
17864
|
-
<path [attr.d]="element.attrs['d']" />
|
|
17865
|
-
}
|
|
17866
|
-
@case ('circle') {
|
|
17867
|
-
<circle [attr.cx]="element.attrs['cx']" [attr.cy]="element.attrs['cy']" [attr.r]="element.attrs['r']" />
|
|
17868
|
-
}
|
|
17869
|
-
@case ('line') {
|
|
17870
|
-
<line [attr.x1]="element.attrs['x1']" [attr.x2]="element.attrs['x2']" [attr.y1]="element.attrs['y1']" [attr.y2]="element.attrs['y2']" />
|
|
17871
|
-
}
|
|
17872
|
-
@case ('polyline') {
|
|
17873
|
-
<polyline [attr.points]="element.attrs['points']" />
|
|
17874
|
-
}
|
|
17875
|
-
@case ('rect') {
|
|
17876
|
-
<rect [attr.x]="element.attrs['x']" [attr.y]="element.attrs['y']" [attr.width]="element.attrs['width']" [attr.height]="element.attrs['height']" [attr.rx]="element.attrs['rx']" [attr.ry]="element.attrs['ry']" />
|
|
17877
|
-
}
|
|
17878
|
-
@case ('ellipse') {
|
|
17879
|
-
<ellipse [attr.cx]="element.attrs['cx']" [attr.cy]="element.attrs['cy']" [attr.rx]="element.attrs['rx']" [attr.ry]="element.attrs['ry']" />
|
|
17880
|
-
}
|
|
17881
|
-
@case ('polygon') {
|
|
17882
|
-
<polygon [attr.points]="element.attrs['points']" />
|
|
17883
|
-
}
|
|
17884
|
-
}
|
|
17885
|
-
}
|
|
17886
|
-
</svg>
|
|
17846
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvIconComponent, isStandalone: true, selector: "jv-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, decorative: { classPropertyName: "decorative", publicName: "decorative", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
17847
|
+
<svg
|
|
17848
|
+
class="jv-icon"
|
|
17849
|
+
[attr.viewBox]="iconDefinition().viewBox"
|
|
17850
|
+
[attr.width]="size()"
|
|
17851
|
+
[attr.height]="size()"
|
|
17852
|
+
[attr.stroke-width]="strokeWidth()"
|
|
17853
|
+
[attr.role]="decorative() ? 'presentation' : 'img'"
|
|
17854
|
+
[attr.aria-hidden]="decorative() ? 'true' : null"
|
|
17855
|
+
[attr.aria-label]="decorative() ? null : ariaLabel() || normalizedName()"
|
|
17856
|
+
fill="none"
|
|
17857
|
+
stroke="currentColor"
|
|
17858
|
+
stroke-linecap="round"
|
|
17859
|
+
stroke-linejoin="round"
|
|
17860
|
+
>
|
|
17861
|
+
@for (element of iconDefinition().elements; track $index) {
|
|
17862
|
+
@switch (element.tag) {
|
|
17863
|
+
@case ('path') {
|
|
17864
|
+
<path [attr.d]="element.attrs['d']" />
|
|
17865
|
+
}
|
|
17866
|
+
@case ('circle') {
|
|
17867
|
+
<circle [attr.cx]="element.attrs['cx']" [attr.cy]="element.attrs['cy']" [attr.r]="element.attrs['r']" />
|
|
17868
|
+
}
|
|
17869
|
+
@case ('line') {
|
|
17870
|
+
<line [attr.x1]="element.attrs['x1']" [attr.x2]="element.attrs['x2']" [attr.y1]="element.attrs['y1']" [attr.y2]="element.attrs['y2']" />
|
|
17871
|
+
}
|
|
17872
|
+
@case ('polyline') {
|
|
17873
|
+
<polyline [attr.points]="element.attrs['points']" />
|
|
17874
|
+
}
|
|
17875
|
+
@case ('rect') {
|
|
17876
|
+
<rect [attr.x]="element.attrs['x']" [attr.y]="element.attrs['y']" [attr.width]="element.attrs['width']" [attr.height]="element.attrs['height']" [attr.rx]="element.attrs['rx']" [attr.ry]="element.attrs['ry']" />
|
|
17877
|
+
}
|
|
17878
|
+
@case ('ellipse') {
|
|
17879
|
+
<ellipse [attr.cx]="element.attrs['cx']" [attr.cy]="element.attrs['cy']" [attr.rx]="element.attrs['rx']" [attr.ry]="element.attrs['ry']" />
|
|
17880
|
+
}
|
|
17881
|
+
@case ('polygon') {
|
|
17882
|
+
<polygon [attr.points]="element.attrs['points']" />
|
|
17883
|
+
}
|
|
17884
|
+
}
|
|
17885
|
+
}
|
|
17886
|
+
</svg>
|
|
17887
17887
|
`, isInline: true });
|
|
17888
17888
|
}
|
|
17889
17889
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvIconComponent, decorators: [{
|
|
@@ -17891,47 +17891,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
17891
17891
|
args: [{
|
|
17892
17892
|
selector: 'jv-icon',
|
|
17893
17893
|
standalone: true,
|
|
17894
|
-
template: `
|
|
17895
|
-
<svg
|
|
17896
|
-
class="jv-icon"
|
|
17897
|
-
[attr.viewBox]="iconDefinition().viewBox"
|
|
17898
|
-
[attr.width]="size()"
|
|
17899
|
-
[attr.height]="size()"
|
|
17900
|
-
[attr.stroke-width]="strokeWidth()"
|
|
17901
|
-
[attr.role]="decorative() ? 'presentation' : 'img'"
|
|
17902
|
-
[attr.aria-hidden]="decorative() ? 'true' : null"
|
|
17903
|
-
[attr.aria-label]="decorative() ? null : ariaLabel() || normalizedName()"
|
|
17904
|
-
fill="none"
|
|
17905
|
-
stroke="currentColor"
|
|
17906
|
-
stroke-linecap="round"
|
|
17907
|
-
stroke-linejoin="round"
|
|
17908
|
-
>
|
|
17909
|
-
@for (element of iconDefinition().elements; track $index) {
|
|
17910
|
-
@switch (element.tag) {
|
|
17911
|
-
@case ('path') {
|
|
17912
|
-
<path [attr.d]="element.attrs['d']" />
|
|
17913
|
-
}
|
|
17914
|
-
@case ('circle') {
|
|
17915
|
-
<circle [attr.cx]="element.attrs['cx']" [attr.cy]="element.attrs['cy']" [attr.r]="element.attrs['r']" />
|
|
17916
|
-
}
|
|
17917
|
-
@case ('line') {
|
|
17918
|
-
<line [attr.x1]="element.attrs['x1']" [attr.x2]="element.attrs['x2']" [attr.y1]="element.attrs['y1']" [attr.y2]="element.attrs['y2']" />
|
|
17919
|
-
}
|
|
17920
|
-
@case ('polyline') {
|
|
17921
|
-
<polyline [attr.points]="element.attrs['points']" />
|
|
17922
|
-
}
|
|
17923
|
-
@case ('rect') {
|
|
17924
|
-
<rect [attr.x]="element.attrs['x']" [attr.y]="element.attrs['y']" [attr.width]="element.attrs['width']" [attr.height]="element.attrs['height']" [attr.rx]="element.attrs['rx']" [attr.ry]="element.attrs['ry']" />
|
|
17925
|
-
}
|
|
17926
|
-
@case ('ellipse') {
|
|
17927
|
-
<ellipse [attr.cx]="element.attrs['cx']" [attr.cy]="element.attrs['cy']" [attr.rx]="element.attrs['rx']" [attr.ry]="element.attrs['ry']" />
|
|
17928
|
-
}
|
|
17929
|
-
@case ('polygon') {
|
|
17930
|
-
<polygon [attr.points]="element.attrs['points']" />
|
|
17931
|
-
}
|
|
17932
|
-
}
|
|
17933
|
-
}
|
|
17934
|
-
</svg>
|
|
17894
|
+
template: `
|
|
17895
|
+
<svg
|
|
17896
|
+
class="jv-icon"
|
|
17897
|
+
[attr.viewBox]="iconDefinition().viewBox"
|
|
17898
|
+
[attr.width]="size()"
|
|
17899
|
+
[attr.height]="size()"
|
|
17900
|
+
[attr.stroke-width]="strokeWidth()"
|
|
17901
|
+
[attr.role]="decorative() ? 'presentation' : 'img'"
|
|
17902
|
+
[attr.aria-hidden]="decorative() ? 'true' : null"
|
|
17903
|
+
[attr.aria-label]="decorative() ? null : ariaLabel() || normalizedName()"
|
|
17904
|
+
fill="none"
|
|
17905
|
+
stroke="currentColor"
|
|
17906
|
+
stroke-linecap="round"
|
|
17907
|
+
stroke-linejoin="round"
|
|
17908
|
+
>
|
|
17909
|
+
@for (element of iconDefinition().elements; track $index) {
|
|
17910
|
+
@switch (element.tag) {
|
|
17911
|
+
@case ('path') {
|
|
17912
|
+
<path [attr.d]="element.attrs['d']" />
|
|
17913
|
+
}
|
|
17914
|
+
@case ('circle') {
|
|
17915
|
+
<circle [attr.cx]="element.attrs['cx']" [attr.cy]="element.attrs['cy']" [attr.r]="element.attrs['r']" />
|
|
17916
|
+
}
|
|
17917
|
+
@case ('line') {
|
|
17918
|
+
<line [attr.x1]="element.attrs['x1']" [attr.x2]="element.attrs['x2']" [attr.y1]="element.attrs['y1']" [attr.y2]="element.attrs['y2']" />
|
|
17919
|
+
}
|
|
17920
|
+
@case ('polyline') {
|
|
17921
|
+
<polyline [attr.points]="element.attrs['points']" />
|
|
17922
|
+
}
|
|
17923
|
+
@case ('rect') {
|
|
17924
|
+
<rect [attr.x]="element.attrs['x']" [attr.y]="element.attrs['y']" [attr.width]="element.attrs['width']" [attr.height]="element.attrs['height']" [attr.rx]="element.attrs['rx']" [attr.ry]="element.attrs['ry']" />
|
|
17925
|
+
}
|
|
17926
|
+
@case ('ellipse') {
|
|
17927
|
+
<ellipse [attr.cx]="element.attrs['cx']" [attr.cy]="element.attrs['cy']" [attr.rx]="element.attrs['rx']" [attr.ry]="element.attrs['ry']" />
|
|
17928
|
+
}
|
|
17929
|
+
@case ('polygon') {
|
|
17930
|
+
<polygon [attr.points]="element.attrs['points']" />
|
|
17931
|
+
}
|
|
17932
|
+
}
|
|
17933
|
+
}
|
|
17934
|
+
</svg>
|
|
17935
17935
|
`,
|
|
17936
17936
|
}]
|
|
17937
17937
|
}], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], strokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "strokeWidth", required: false }] }], decorative: [{ type: i0.Input, args: [{ isSignal: true, alias: "decorative", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
|
|
@@ -18905,6 +18905,11 @@ const ES = {
|
|
|
18905
18905
|
'grid.pageOfTotal': 'Página {page} de {total}',
|
|
18906
18906
|
'grid.itemsTotal': '{total} registros',
|
|
18907
18907
|
'grid.itemsShowing': 'Mostrando {start}-{end} de {total}',
|
|
18908
|
+
'grid.exportCsv': 'CSV',
|
|
18909
|
+
'grid.exportExcel': 'Excel',
|
|
18910
|
+
'grid.filterPlaceholder': 'Filtrar...',
|
|
18911
|
+
'grid.filterForColumn': 'Filtrar por ${column}',
|
|
18912
|
+
'grid.actionsLabel': 'Acciones',
|
|
18908
18913
|
'pagination.pageLabel': 'Página {page}',
|
|
18909
18914
|
'pagination.itemsShowing': '{start}-{end} de {total}',
|
|
18910
18915
|
'pagination.of': 'de',
|
|
@@ -18935,6 +18940,11 @@ const EN = {
|
|
|
18935
18940
|
'grid.pageOfTotal': 'Page {page} of {total}',
|
|
18936
18941
|
'grid.itemsTotal': '{total} items',
|
|
18937
18942
|
'grid.itemsShowing': 'Showing {start}-{end} of {total}',
|
|
18943
|
+
'grid.exportCsv': 'CSV',
|
|
18944
|
+
'grid.exportExcel': 'Excel',
|
|
18945
|
+
'grid.filterPlaceholder': 'Filter...',
|
|
18946
|
+
'grid.filterForColumn': 'Filter by ${column}',
|
|
18947
|
+
'grid.actionsLabel': 'Actions',
|
|
18938
18948
|
'pagination.pageLabel': 'Page {page}',
|
|
18939
18949
|
'pagination.itemsShowing': '{start}-{end} of {total}',
|
|
18940
18950
|
'pagination.of': 'of',
|
|
@@ -20193,6 +20203,17 @@ const JV_GRID_DEFAULT_OPTIONS = {
|
|
|
20193
20203
|
noResultsMessage: '',
|
|
20194
20204
|
searchPlaceholder: '',
|
|
20195
20205
|
ariaLabel: '',
|
|
20206
|
+
serverSide: false,
|
|
20207
|
+
totalItems: 0,
|
|
20208
|
+
stickyColumns: false,
|
|
20209
|
+
resizableColumns: false,
|
|
20210
|
+
reorderableColumns: false,
|
|
20211
|
+
editable: false,
|
|
20212
|
+
virtualScroll: false,
|
|
20213
|
+
virtualScrollRowHeight: 48,
|
|
20214
|
+
exportable: false,
|
|
20215
|
+
columnFilters: false,
|
|
20216
|
+
rowDoubleClick: false,
|
|
20196
20217
|
};
|
|
20197
20218
|
|
|
20198
20219
|
let gridIdSequence = 0;
|
|
@@ -20206,11 +20227,16 @@ class JvGridComponent {
|
|
|
20206
20227
|
trackBy = input(null, ...(ngDevMode ? [{ debugName: "trackBy" }] : /* istanbul ignore next */ []));
|
|
20207
20228
|
selectedIds = input([], ...(ngDevMode ? [{ debugName: "selectedIds" }] : /* istanbul ignore next */ []));
|
|
20208
20229
|
rowClick = output();
|
|
20230
|
+
rowDoubleClick = output();
|
|
20209
20231
|
actionClick = output();
|
|
20210
20232
|
selectionChange = output();
|
|
20211
20233
|
pageChange = output();
|
|
20212
20234
|
searchChange = output();
|
|
20213
20235
|
sortChange = output();
|
|
20236
|
+
columnFilter = output();
|
|
20237
|
+
columnResize = output();
|
|
20238
|
+
columnReorder = output();
|
|
20239
|
+
rowEdit = output();
|
|
20214
20240
|
effectiveOptions = computed(() => ({ ...JV_GRID_DEFAULT_OPTIONS, ...this.options() }), ...(ngDevMode ? [{ debugName: "effectiveOptions" }] : /* istanbul ignore next */ []));
|
|
20215
20241
|
idKey = computed(() => {
|
|
20216
20242
|
const tb = this.trackBy();
|
|
@@ -20220,7 +20246,18 @@ class JvGridComponent {
|
|
|
20220
20246
|
}, ...(ngDevMode ? [{ debugName: "idKey" }] : /* istanbul ignore next */ []));
|
|
20221
20247
|
resolvedOptions = this.effectiveOptions;
|
|
20222
20248
|
gridLabel = computed(() => this.resolvedOptions().ariaLabel || `Grid ${this.gridId}`, ...(ngDevMode ? [{ debugName: "gridLabel" }] : /* istanbul ignore next */ []));
|
|
20223
|
-
|
|
20249
|
+
columnOrder = signal([], ...(ngDevMode ? [{ debugName: "columnOrder" }] : /* istanbul ignore next */ []));
|
|
20250
|
+
colFilters = signal({}, ...(ngDevMode ? [{ debugName: "colFilters" }] : /* istanbul ignore next */ []));
|
|
20251
|
+
columnWidths = signal({}, ...(ngDevMode ? [{ debugName: "columnWidths" }] : /* istanbul ignore next */ []));
|
|
20252
|
+
visibleColumns = computed(() => {
|
|
20253
|
+
const cols = this.columns().filter(col => !col.hidden);
|
|
20254
|
+
const order = this.columnOrder();
|
|
20255
|
+
if (order.length > 0) {
|
|
20256
|
+
return order.map(key => cols.find(c => this.colKey(c) === key)).filter(Boolean);
|
|
20257
|
+
}
|
|
20258
|
+
return cols;
|
|
20259
|
+
}, ...(ngDevMode ? [{ debugName: "visibleColumns" }] : /* istanbul ignore next */ []));
|
|
20260
|
+
groupedHeaders = computed(() => this.columns().filter(col => col.children && col.children.length > 0), ...(ngDevMode ? [{ debugName: "groupedHeaders" }] : /* istanbul ignore next */ []));
|
|
20224
20261
|
internalSelectedIds = signal([], ...(ngDevMode ? [{ debugName: "internalSelectedIds" }] : /* istanbul ignore next */ []));
|
|
20225
20262
|
searchTerm = signal('', ...(ngDevMode ? [{ debugName: "searchTerm" }] : /* istanbul ignore next */ []));
|
|
20226
20263
|
sortState = signal({ columnKey: '', direction: null }, ...(ngDevMode ? [{ debugName: "sortState" }] : /* istanbul ignore next */ []));
|
|
@@ -20236,23 +20273,51 @@ class JvGridComponent {
|
|
|
20236
20273
|
const ids = fromInput.length > 0 ? fromInput : fromInternal;
|
|
20237
20274
|
return new Set(ids);
|
|
20238
20275
|
}, ...(ngDevMode ? [{ debugName: "selectedIdSet" }] : /* istanbul ignore next */ []));
|
|
20276
|
+
hasActiveFilters = computed(() => Object.values(this.colFilters()).some(f => f.value.trim().length > 0), ...(ngDevMode ? [{ debugName: "hasActiveFilters" }] : /* istanbul ignore next */ []));
|
|
20239
20277
|
filteredData = computed(() => {
|
|
20278
|
+
if (this.effectiveOptions().serverSide)
|
|
20279
|
+
return this.data();
|
|
20240
20280
|
let items = this.data();
|
|
20241
20281
|
const term = this.searchTerm().trim().toLowerCase();
|
|
20242
|
-
if (
|
|
20243
|
-
|
|
20244
|
-
|
|
20245
|
-
|
|
20246
|
-
|
|
20247
|
-
|
|
20248
|
-
|
|
20249
|
-
|
|
20250
|
-
return
|
|
20251
|
-
|
|
20282
|
+
if (term) {
|
|
20283
|
+
items = items.filter(row => {
|
|
20284
|
+
return this.visibleColumns().some(col => {
|
|
20285
|
+
if (col.searchable === false)
|
|
20286
|
+
return false;
|
|
20287
|
+
const value = this.getRawCellValue(row, col);
|
|
20288
|
+
if (value == null)
|
|
20289
|
+
return false;
|
|
20290
|
+
return String(value).toLowerCase().includes(term);
|
|
20291
|
+
});
|
|
20252
20292
|
});
|
|
20253
|
-
}
|
|
20293
|
+
}
|
|
20294
|
+
const filters = this.colFilters();
|
|
20295
|
+
const hasFilters = Object.values(filters).some(f => f.value.trim().length > 0);
|
|
20296
|
+
if (hasFilters) {
|
|
20297
|
+
items = items.filter(row => {
|
|
20298
|
+
return Object.entries(filters).every(([key, filter]) => {
|
|
20299
|
+
if (!filter.value.trim())
|
|
20300
|
+
return true;
|
|
20301
|
+
const col = this.columns().find(c => this.colKey(c) === key);
|
|
20302
|
+
if (!col || col.filterable === false)
|
|
20303
|
+
return true;
|
|
20304
|
+
const value = String(this.getRawCellValue(row, col) ?? '').toLowerCase();
|
|
20305
|
+
const fv = filter.value.toLowerCase();
|
|
20306
|
+
switch (filter.operator) {
|
|
20307
|
+
case 'contains': return value.includes(fv);
|
|
20308
|
+
case 'equals': return value === fv;
|
|
20309
|
+
case 'startsWith': return value.startsWith(fv);
|
|
20310
|
+
case 'endsWith': return value.endsWith(fv);
|
|
20311
|
+
default: return value.includes(fv);
|
|
20312
|
+
}
|
|
20313
|
+
});
|
|
20314
|
+
});
|
|
20315
|
+
}
|
|
20316
|
+
return items;
|
|
20254
20317
|
}, ...(ngDevMode ? [{ debugName: "filteredData" }] : /* istanbul ignore next */ []));
|
|
20255
20318
|
sortedData = computed(() => {
|
|
20319
|
+
if (this.effectiveOptions().serverSide)
|
|
20320
|
+
return this.filteredData();
|
|
20256
20321
|
let items = this.filteredData();
|
|
20257
20322
|
const { columnKey, direction } = this.sortState();
|
|
20258
20323
|
if (!columnKey || !direction)
|
|
@@ -20268,18 +20333,50 @@ class JvGridComponent {
|
|
|
20268
20333
|
return direction === 'asc' ? cmp : -cmp;
|
|
20269
20334
|
});
|
|
20270
20335
|
}, ...(ngDevMode ? [{ debugName: "sortedData" }] : /* istanbul ignore next */ []));
|
|
20271
|
-
|
|
20272
|
-
|
|
20273
|
-
|
|
20336
|
+
effectiveTotalItems = computed(() => {
|
|
20337
|
+
if (this.effectiveOptions().serverSide) {
|
|
20338
|
+
return this.effectiveOptions().totalItems ?? this.data().length;
|
|
20339
|
+
}
|
|
20340
|
+
return this.sortedData().length;
|
|
20341
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveTotalItems" }] : /* istanbul ignore next */ []));
|
|
20342
|
+
effectiveTotalPages = computed(() => Math.max(1, Math.ceil(this.effectiveTotalItems() / this.pageSize())), ...(ngDevMode ? [{ debugName: "effectiveTotalPages" }] : /* istanbul ignore next */ []));
|
|
20343
|
+
displayData = computed(() => {
|
|
20344
|
+
if (this.effectiveOptions().virtualScroll) {
|
|
20345
|
+
return this.sortedData();
|
|
20346
|
+
}
|
|
20347
|
+
if (!this.effectiveOptions().pageable)
|
|
20348
|
+
return this.sortedData();
|
|
20274
20349
|
const items = this.sortedData();
|
|
20275
20350
|
const ps = this.pageSize();
|
|
20276
|
-
const page = Math.min(this.pageIndex(), this.
|
|
20351
|
+
const page = Math.min(this.pageIndex(), this.effectiveTotalPages() - 1);
|
|
20277
20352
|
return items.slice(page * ps, page * ps + ps);
|
|
20278
|
-
}, ...(ngDevMode ? [{ debugName: "
|
|
20279
|
-
|
|
20280
|
-
|
|
20353
|
+
}, ...(ngDevMode ? [{ debugName: "displayData" }] : /* istanbul ignore next */ []));
|
|
20354
|
+
virtualScroll = computed(() => this.effectiveOptions().virtualScroll && this.effectiveOptions().virtualScrollRowHeight, ...(ngDevMode ? [{ debugName: "virtualScroll" }] : /* istanbul ignore next */ []));
|
|
20355
|
+
virtualStartIndex = signal(0, ...(ngDevMode ? [{ debugName: "virtualStartIndex" }] : /* istanbul ignore next */ []));
|
|
20356
|
+
virtualEndIndex = signal(0, ...(ngDevMode ? [{ debugName: "virtualEndIndex" }] : /* istanbul ignore next */ []));
|
|
20357
|
+
virtualDisplayData = computed(() => {
|
|
20358
|
+
if (!this.effectiveOptions().virtualScroll)
|
|
20359
|
+
return this.displayData();
|
|
20360
|
+
const items = this.sortedData();
|
|
20361
|
+
const start = this.virtualStartIndex();
|
|
20362
|
+
const end = this.virtualEndIndex();
|
|
20363
|
+
if (start >= items.length)
|
|
20364
|
+
return [];
|
|
20365
|
+
return items.slice(start, Math.min(end, items.length));
|
|
20366
|
+
}, ...(ngDevMode ? [{ debugName: "virtualDisplayData" }] : /* istanbul ignore next */ []));
|
|
20367
|
+
virtualTotalHeight = computed(() => {
|
|
20368
|
+
const count = this.effectiveOptions().serverSide
|
|
20369
|
+
? this.effectiveTotalItems()
|
|
20370
|
+
: this.sortedData().length;
|
|
20371
|
+
return count * (this.effectiveOptions().virtualScrollRowHeight ?? 48);
|
|
20372
|
+
}, ...(ngDevMode ? [{ debugName: "virtualTotalHeight" }] : /* istanbul ignore next */ []));
|
|
20373
|
+
virtualOffsetY = computed(() => {
|
|
20374
|
+
return this.virtualStartIndex() * (this.effectiveOptions().virtualScrollRowHeight ?? 48);
|
|
20375
|
+
}, ...(ngDevMode ? [{ debugName: "virtualOffsetY" }] : /* istanbul ignore next */ []));
|
|
20376
|
+
pageStart = computed(() => this.effectiveTotalItems() === 0 ? 0 : this.pageIndex() * this.pageSize() + 1, ...(ngDevMode ? [{ debugName: "pageStart" }] : /* istanbul ignore next */ []));
|
|
20377
|
+
pageEnd = computed(() => Math.min((this.pageIndex() + 1) * this.pageSize(), this.effectiveTotalItems()), ...(ngDevMode ? [{ debugName: "pageEnd" }] : /* istanbul ignore next */ []));
|
|
20281
20378
|
pageRange = computed(() => {
|
|
20282
|
-
const total = this.
|
|
20379
|
+
const total = this.effectiveTotalPages();
|
|
20283
20380
|
const current = this.pageIndex();
|
|
20284
20381
|
const range = [];
|
|
20285
20382
|
const start = Math.max(0, current - 2);
|
|
@@ -20289,11 +20386,11 @@ class JvGridComponent {
|
|
|
20289
20386
|
return range;
|
|
20290
20387
|
}, ...(ngDevMode ? [{ debugName: "pageRange" }] : /* istanbul ignore next */ []));
|
|
20291
20388
|
allSelected = computed(() => {
|
|
20292
|
-
const rows = this.
|
|
20389
|
+
const rows = this.displayData();
|
|
20293
20390
|
return rows.length > 0 && rows.every(r => this.selectedIdSet().has(this.getRowId(r)));
|
|
20294
20391
|
}, ...(ngDevMode ? [{ debugName: "allSelected" }] : /* istanbul ignore next */ []));
|
|
20295
20392
|
someSelected = computed(() => {
|
|
20296
|
-
const rows = this.
|
|
20393
|
+
const rows = this.displayData();
|
|
20297
20394
|
return rows.some(r => this.selectedIdSet().has(this.getRowId(r))) && !this.allSelected();
|
|
20298
20395
|
}, ...(ngDevMode ? [{ debugName: "someSelected" }] : /* istanbul ignore next */ []));
|
|
20299
20396
|
colspan = computed(() => {
|
|
@@ -20305,6 +20402,7 @@ class JvGridComponent {
|
|
|
20305
20402
|
return count;
|
|
20306
20403
|
}, ...(ngDevMode ? [{ debugName: "colspan" }] : /* istanbul ignore next */ []));
|
|
20307
20404
|
densityClass = computed(() => `jv-grid-density--${this.resolvedOptions().density ?? 'normal'}`, ...(ngDevMode ? [{ debugName: "densityClass" }] : /* istanbul ignore next */ []));
|
|
20405
|
+
editState = signal(null, ...(ngDevMode ? [{ debugName: "editState" }] : /* istanbul ignore next */ []));
|
|
20308
20406
|
t = (key, params) => this.translationService.translate(key, params);
|
|
20309
20407
|
getRowId(row, index) {
|
|
20310
20408
|
const idKey = this.idKey();
|
|
@@ -20326,6 +20424,10 @@ class JvGridComponent {
|
|
|
20326
20424
|
getCellValue(row, col) {
|
|
20327
20425
|
return this.getRawCellValue(row, col);
|
|
20328
20426
|
}
|
|
20427
|
+
getEditValue(row, col) {
|
|
20428
|
+
const val = this.getCellValue(row, col);
|
|
20429
|
+
return val == null ? '' : String(val);
|
|
20430
|
+
}
|
|
20329
20431
|
formatValue(value, col) {
|
|
20330
20432
|
if (value == null)
|
|
20331
20433
|
return '';
|
|
@@ -20353,6 +20455,38 @@ class JvGridComponent {
|
|
|
20353
20455
|
return `${col.header} - ${this.t('grid.sortDesc')}`;
|
|
20354
20456
|
return `${col.header} - ${this.t('grid.sortAsc')} ${this.t('grid.sortDesc')}`;
|
|
20355
20457
|
}
|
|
20458
|
+
getColumnWidth(col) {
|
|
20459
|
+
return this.columnWidths()[this.colKey(col)] ?? (col.width || undefined);
|
|
20460
|
+
}
|
|
20461
|
+
isStickyLeft(col) {
|
|
20462
|
+
return !!(this.resolvedOptions().stickyColumns && col.sticky === 'left');
|
|
20463
|
+
}
|
|
20464
|
+
isStickyRight(col) {
|
|
20465
|
+
return !!(this.resolvedOptions().stickyColumns && col.sticky === 'right');
|
|
20466
|
+
}
|
|
20467
|
+
isColumnResizable(col) {
|
|
20468
|
+
return this.resolvedOptions().resizableColumns || col.resizable === true;
|
|
20469
|
+
}
|
|
20470
|
+
isCellEditable(col) {
|
|
20471
|
+
return (this.resolvedOptions().editable || col.editable === true) && col.editable !== false;
|
|
20472
|
+
}
|
|
20473
|
+
groupColspan(group) {
|
|
20474
|
+
return group.children?.length ?? 1;
|
|
20475
|
+
}
|
|
20476
|
+
isEditingCell(row, col) {
|
|
20477
|
+
const es = this.editState();
|
|
20478
|
+
return es !== null && es.rowId === this.getRowId(row) && es.colKey === this.colKey(col);
|
|
20479
|
+
}
|
|
20480
|
+
isRowEditing(row) {
|
|
20481
|
+
const es = this.editState();
|
|
20482
|
+
return es !== null && es.rowId === this.getRowId(row);
|
|
20483
|
+
}
|
|
20484
|
+
getEditOptions(col) {
|
|
20485
|
+
return (col.editOptions || []).map(opt => ({
|
|
20486
|
+
label: opt.label,
|
|
20487
|
+
value: String(opt.value),
|
|
20488
|
+
}));
|
|
20489
|
+
}
|
|
20356
20490
|
findColumn(key) {
|
|
20357
20491
|
return this.columns().find(c => this.colKey(c) === key) ?? { key, header: key };
|
|
20358
20492
|
}
|
|
@@ -20385,7 +20519,7 @@ class JvGridComponent {
|
|
|
20385
20519
|
this.searchChange.emit(value);
|
|
20386
20520
|
}
|
|
20387
20521
|
goToPage(page) {
|
|
20388
|
-
if (page >= 0 && page < this.
|
|
20522
|
+
if (page >= 0 && page < this.effectiveTotalPages()) {
|
|
20389
20523
|
this.pageIndex.set(page);
|
|
20390
20524
|
this.pageChange.emit({ pageIndex: page, pageSize: this.pageSize() });
|
|
20391
20525
|
}
|
|
@@ -20408,7 +20542,7 @@ class JvGridComponent {
|
|
|
20408
20542
|
toggleSelectAll(checked) {
|
|
20409
20543
|
this.internalSelectedIds.update(ids => {
|
|
20410
20544
|
const set = new Set(ids);
|
|
20411
|
-
const rows = this.
|
|
20545
|
+
const rows = this.displayData();
|
|
20412
20546
|
rows.forEach(r => {
|
|
20413
20547
|
if (checked)
|
|
20414
20548
|
set.add(this.getRowId(r));
|
|
@@ -20428,9 +20562,23 @@ class JvGridComponent {
|
|
|
20428
20562
|
this.rowClick.emit(event);
|
|
20429
20563
|
}
|
|
20430
20564
|
}
|
|
20565
|
+
onRowDblClick(row) {
|
|
20566
|
+
if (this.resolvedOptions().rowDoubleClick) {
|
|
20567
|
+
this.rowDoubleClick.emit(row);
|
|
20568
|
+
}
|
|
20569
|
+
}
|
|
20431
20570
|
onActionClick(action, row) {
|
|
20432
20571
|
this.actionClick.emit({ actionId: action.id, row });
|
|
20433
20572
|
}
|
|
20573
|
+
onColumnFilterChange(col, value) {
|
|
20574
|
+
const key = this.colKey(col);
|
|
20575
|
+
this.colFilters.update(f => ({
|
|
20576
|
+
...f,
|
|
20577
|
+
[key]: { key, value, operator: 'contains' },
|
|
20578
|
+
}));
|
|
20579
|
+
this.pageIndex.set(0);
|
|
20580
|
+
this.columnFilter.emit({ columnKey: key, value });
|
|
20581
|
+
}
|
|
20434
20582
|
getRowLabel(row, index) {
|
|
20435
20583
|
const label = this.visibleColumns()
|
|
20436
20584
|
.slice(0, 2)
|
|
@@ -20439,20 +20587,160 @@ class JvGridComponent {
|
|
|
20439
20587
|
.join(' - ');
|
|
20440
20588
|
return `${label}${this.isSelected(row) ? ` (${this.t('grid.selected')})` : ''}`;
|
|
20441
20589
|
}
|
|
20590
|
+
startEdit(row, col, event) {
|
|
20591
|
+
if (!this.isCellEditable(col))
|
|
20592
|
+
return;
|
|
20593
|
+
if (col.type === 'boolean')
|
|
20594
|
+
return;
|
|
20595
|
+
event.preventDefault();
|
|
20596
|
+
this.editState.set({ rowId: this.getRowId(row), colKey: this.colKey(col) });
|
|
20597
|
+
}
|
|
20598
|
+
commitEdit(row, col, value) {
|
|
20599
|
+
const colKey = this.colKey(col);
|
|
20600
|
+
if (this.editState()?.colKey === colKey) {
|
|
20601
|
+
this.rowEdit.emit({ row, column: col, value });
|
|
20602
|
+
this.editState.set(null);
|
|
20603
|
+
}
|
|
20604
|
+
}
|
|
20605
|
+
cancelEdit() {
|
|
20606
|
+
this.editState.set(null);
|
|
20607
|
+
}
|
|
20608
|
+
onEditValueChange(row, col, value) {
|
|
20609
|
+
this.commitEdit(row, col, value);
|
|
20610
|
+
}
|
|
20611
|
+
// Column resizing
|
|
20612
|
+
resizeData = null;
|
|
20613
|
+
onResizeStart(event, col, _colIdx) {
|
|
20614
|
+
event.preventDefault();
|
|
20615
|
+
const th = event.target.closest('th');
|
|
20616
|
+
const startWidth = th.offsetWidth;
|
|
20617
|
+
this.resizeData = { col, startX: event.clientX, startWidth };
|
|
20618
|
+
document.addEventListener('mousemove', this.onResizeMove);
|
|
20619
|
+
document.addEventListener('mouseup', this.onResizeEnd);
|
|
20620
|
+
}
|
|
20621
|
+
onResizeMove = (event) => {
|
|
20622
|
+
if (!this.resizeData)
|
|
20623
|
+
return;
|
|
20624
|
+
const diff = event.clientX - this.resizeData.startX;
|
|
20625
|
+
const newWidth = Math.max(30, this.resizeData.startWidth + diff);
|
|
20626
|
+
this.columnWidths.update(w => ({
|
|
20627
|
+
...w,
|
|
20628
|
+
[this.colKey(this.resizeData.col)]: `${newWidth}px`,
|
|
20629
|
+
}));
|
|
20630
|
+
};
|
|
20631
|
+
onResizeEnd = () => {
|
|
20632
|
+
if (this.resizeData) {
|
|
20633
|
+
const key = this.colKey(this.resizeData.col);
|
|
20634
|
+
const w = this.columnWidths()[key];
|
|
20635
|
+
this.columnResize.emit({ columnKey: key, width: w });
|
|
20636
|
+
}
|
|
20637
|
+
this.resizeData = null;
|
|
20638
|
+
document.removeEventListener('mousemove', this.onResizeMove);
|
|
20639
|
+
document.removeEventListener('mouseup', this.onResizeEnd);
|
|
20640
|
+
};
|
|
20641
|
+
// Column reordering
|
|
20642
|
+
dragIndex = null;
|
|
20643
|
+
onDragStart(event, colIdx) {
|
|
20644
|
+
if (!this.resolvedOptions().reorderableColumns)
|
|
20645
|
+
return;
|
|
20646
|
+
this.dragIndex = colIdx;
|
|
20647
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
20648
|
+
}
|
|
20649
|
+
onDragOver(event, _colIdx) {
|
|
20650
|
+
if (!this.resolvedOptions().reorderableColumns || this.dragIndex === null)
|
|
20651
|
+
return;
|
|
20652
|
+
event.preventDefault();
|
|
20653
|
+
event.dataTransfer.dropEffect = 'move';
|
|
20654
|
+
}
|
|
20655
|
+
onDrop(event, targetIdx) {
|
|
20656
|
+
event.preventDefault();
|
|
20657
|
+
if (!this.resolvedOptions().reorderableColumns || this.dragIndex === null)
|
|
20658
|
+
return;
|
|
20659
|
+
if (this.dragIndex === targetIdx)
|
|
20660
|
+
return;
|
|
20661
|
+
const cols = this.visibleColumns().map(c => this.colKey(c));
|
|
20662
|
+
const [moved] = cols.splice(this.dragIndex, 1);
|
|
20663
|
+
cols.splice(targetIdx, 0, moved);
|
|
20664
|
+
this.columnOrder.set(cols);
|
|
20665
|
+
this.columnReorder.emit({ columnKey: moved, newIndex: targetIdx });
|
|
20666
|
+
this.dragIndex = null;
|
|
20667
|
+
}
|
|
20668
|
+
onDragEnd(_event) {
|
|
20669
|
+
this.dragIndex = null;
|
|
20670
|
+
}
|
|
20671
|
+
// Virtual scrolling
|
|
20672
|
+
onVirtualScroll(target) {
|
|
20673
|
+
if (!this.effectiveOptions().virtualScroll)
|
|
20674
|
+
return;
|
|
20675
|
+
const rowHeight = this.effectiveOptions().virtualScrollRowHeight ?? 48;
|
|
20676
|
+
const buffer = 5;
|
|
20677
|
+
const scrollTop = target.scrollTop;
|
|
20678
|
+
const clientHeight = target.clientHeight;
|
|
20679
|
+
const start = Math.max(0, Math.floor(scrollTop / rowHeight) - buffer);
|
|
20680
|
+
const end = Math.min(this.sortedData().length, Math.ceil((scrollTop + clientHeight) / rowHeight) + buffer);
|
|
20681
|
+
this.virtualStartIndex.set(start);
|
|
20682
|
+
this.virtualEndIndex.set(end);
|
|
20683
|
+
}
|
|
20684
|
+
// Export
|
|
20685
|
+
exportCsv() {
|
|
20686
|
+
const cols = this.visibleColumns().map(c => ({ key: this.colKey(c), header: c.header }));
|
|
20687
|
+
const allData = this.effectiveOptions().serverSide ? this.data() : this.sortedData();
|
|
20688
|
+
const headerRow = cols.map(c => `"${c.header}"`).join(',');
|
|
20689
|
+
const dataRows = allData.map(row => cols.map(col => {
|
|
20690
|
+
const val = row[col.key];
|
|
20691
|
+
if (val == null)
|
|
20692
|
+
return '';
|
|
20693
|
+
return `"${String(val).replace(/"/g, '""')}"`;
|
|
20694
|
+
}).join(','));
|
|
20695
|
+
const csv = [headerRow, ...dataRows].join('\r\n');
|
|
20696
|
+
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
|
|
20697
|
+
const url = URL.createObjectURL(blob);
|
|
20698
|
+
const a = document.createElement('a');
|
|
20699
|
+
a.href = url;
|
|
20700
|
+
a.download = 'grid-export.csv';
|
|
20701
|
+
a.click();
|
|
20702
|
+
URL.revokeObjectURL(url);
|
|
20703
|
+
}
|
|
20704
|
+
exportExcel() {
|
|
20705
|
+
const cols = this.visibleColumns().map(c => ({ key: this.colKey(c), header: c.header }));
|
|
20706
|
+
const allData = this.effectiveOptions().serverSide ? this.data() : this.sortedData();
|
|
20707
|
+
let html = '<table>';
|
|
20708
|
+
html += '<thead><tr>' + cols.map(c => `<th>${c.header}</th>`).join('') + '</tr></thead>';
|
|
20709
|
+
html += '<tbody>';
|
|
20710
|
+
for (const row of allData) {
|
|
20711
|
+
html += '<tr>' + cols.map(col => `<td>${row[col.key] ?? ''}</td>`).join('') + '</tr>';
|
|
20712
|
+
}
|
|
20713
|
+
html += '</tbody></table>';
|
|
20714
|
+
const blob = new Blob([html], { type: 'application/vnd.ms-excel' });
|
|
20715
|
+
const url = URL.createObjectURL(blob);
|
|
20716
|
+
const a = document.createElement('a');
|
|
20717
|
+
a.href = url;
|
|
20718
|
+
a.download = 'grid-export.xls';
|
|
20719
|
+
a.click();
|
|
20720
|
+
URL.revokeObjectURL(url);
|
|
20721
|
+
}
|
|
20442
20722
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20443
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvGridComponent, isStandalone: true, selector: "jv-grid", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowClick: "rowClick", actionClick: "actionClick", selectionChange: "selectionChange", pageChange: "pageChange", searchChange: "searchChange", sortChange: "sortChange" }, ngImport: i0, template: `
|
|
20723
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvGridComponent, isStandalone: true, selector: "jv-grid", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowClick: "rowClick", rowDoubleClick: "rowDoubleClick", actionClick: "actionClick", selectionChange: "selectionChange", pageChange: "pageChange", searchChange: "searchChange", sortChange: "sortChange", columnFilter: "columnFilter", columnResize: "columnResize", columnReorder: "columnReorder", rowEdit: "rowEdit" }, ngImport: i0, template: `
|
|
20444
20724
|
<div class="jv-grid" role="region" [attr.aria-label]="resolvedOptions().ariaLabel || gridLabel()">
|
|
20445
|
-
@if (resolvedOptions().searchable) {
|
|
20725
|
+
@if (resolvedOptions().searchable || resolvedOptions().exportable) {
|
|
20446
20726
|
<div class="jv-grid-toolbar">
|
|
20447
|
-
|
|
20448
|
-
<
|
|
20449
|
-
|
|
20450
|
-
|
|
20451
|
-
|
|
20452
|
-
|
|
20453
|
-
|
|
20454
|
-
|
|
20455
|
-
|
|
20727
|
+
@if (resolvedOptions().searchable) {
|
|
20728
|
+
<div class="jv-grid-search">
|
|
20729
|
+
<jv-icon name="search" [size]="16" />
|
|
20730
|
+
<jv-input
|
|
20731
|
+
inputId="grid-search"
|
|
20732
|
+
[placeholder]="t('grid.searchPlaceholder')"
|
|
20733
|
+
[ngModel]="searchTerm()"
|
|
20734
|
+
(ngModelChange)="onSearchInput($event)"
|
|
20735
|
+
/>
|
|
20736
|
+
</div>
|
|
20737
|
+
}
|
|
20738
|
+
@if (resolvedOptions().exportable) {
|
|
20739
|
+
<div class="jv-grid-export-actions">
|
|
20740
|
+
<jv-button variant="outline" icon="download" (click)="exportCsv()">{{ t('grid.exportCsv') }}</jv-button>
|
|
20741
|
+
<jv-button variant="outline" icon="file-spreadsheet" (click)="exportExcel()">{{ t('grid.exportExcel') }}</jv-button>
|
|
20742
|
+
</div>
|
|
20743
|
+
}
|
|
20456
20744
|
</div>
|
|
20457
20745
|
}
|
|
20458
20746
|
|
|
@@ -20462,17 +20750,67 @@ class JvGridComponent {
|
|
|
20462
20750
|
<span>{{ t('grid.loading') }}</span>
|
|
20463
20751
|
</div>
|
|
20464
20752
|
} @else {
|
|
20465
|
-
<div
|
|
20753
|
+
<div
|
|
20754
|
+
class="jv-grid-table-wrap"
|
|
20755
|
+
[class.jv-grid-virtual]="resolvedOptions().virtualScroll"
|
|
20756
|
+
#tableWrap
|
|
20757
|
+
(scroll)="onVirtualScroll($any($event.target))"
|
|
20758
|
+
>
|
|
20759
|
+
@if (resolvedOptions().virtualScroll) {
|
|
20760
|
+
<div class="jv-grid-virtual-spacer" [style.height.px]="virtualTotalHeight()"></div>
|
|
20761
|
+
}
|
|
20466
20762
|
<table
|
|
20467
20763
|
class="jv-grid-table"
|
|
20468
20764
|
role="grid"
|
|
20469
20765
|
[attr.aria-label]="resolvedOptions().ariaLabel || gridLabel()"
|
|
20766
|
+
[attr.aria-rowcount]="effectiveTotalItems()"
|
|
20767
|
+
[attr.aria-colcount]="visibleColumns().length"
|
|
20470
20768
|
[class]="densityClass()"
|
|
20769
|
+
[style.position]="resolvedOptions().virtualScroll ? 'relative' : null"
|
|
20770
|
+
[style.top.px]="virtualOffsetY()"
|
|
20471
20771
|
>
|
|
20472
20772
|
<caption class="sr-only">{{ resolvedOptions().ariaLabel || gridLabel() }}</caption>
|
|
20773
|
+
|
|
20774
|
+
@let hasGroupedHeaders = groupedHeaders().length > 0;
|
|
20775
|
+
|
|
20473
20776
|
<thead class="jv-grid-thead">
|
|
20777
|
+
@if (hasGroupedHeaders) {
|
|
20778
|
+
<tr>
|
|
20779
|
+
@if (resolvedOptions().selectable) {
|
|
20780
|
+
<th class="jv-grid-th jv-grid-th-select" scope="col" [attr.rowspan]="2">
|
|
20781
|
+
<input
|
|
20782
|
+
type="checkbox"
|
|
20783
|
+
class="jv-grid-checkbox"
|
|
20784
|
+
[checked]="allSelected()"
|
|
20785
|
+
(change)="toggleSelectAll($any($event.target).checked)"
|
|
20786
|
+
[attr.aria-label]="allSelected() ? t('grid.deselectAll') : t('grid.selectAll')"
|
|
20787
|
+
[indeterminate]="someSelected()"
|
|
20788
|
+
/>
|
|
20789
|
+
</th>
|
|
20790
|
+
}
|
|
20791
|
+
@for (group of groupedHeaders(); track colKey(group)) {
|
|
20792
|
+
<th
|
|
20793
|
+
class="jv-grid-th"
|
|
20794
|
+
[class]="group.headerClass || ''"
|
|
20795
|
+
[class.jv-grid-th-sticky-left]="isStickyLeft(group)"
|
|
20796
|
+
[class.jv-grid-th-sticky-right]="isStickyRight(group)"
|
|
20797
|
+
[attr.colspan]="groupColspan(group)"
|
|
20798
|
+
scope="colgroup"
|
|
20799
|
+
[style.text-align]="group.align ?? 'start'"
|
|
20800
|
+
>
|
|
20801
|
+
<div class="jv-grid-th-content">{{ group.header }}</div>
|
|
20802
|
+
</th>
|
|
20803
|
+
}
|
|
20804
|
+
@if (actions().length > 0) {
|
|
20805
|
+
<th class="jv-grid-th jv-grid-th-actions" scope="col" [attr.rowspan]="2">
|
|
20806
|
+
<span class="sr-only">{{ t('grid.actionsLabel', { label: '' }) }}</span>
|
|
20807
|
+
</th>
|
|
20808
|
+
}
|
|
20809
|
+
</tr>
|
|
20810
|
+
}
|
|
20811
|
+
|
|
20474
20812
|
<tr>
|
|
20475
|
-
@if (resolvedOptions().selectable) {
|
|
20813
|
+
@if (!hasGroupedHeaders && resolvedOptions().selectable) {
|
|
20476
20814
|
<th class="jv-grid-th jv-grid-th-select" scope="col">
|
|
20477
20815
|
<input
|
|
20478
20816
|
type="checkbox"
|
|
@@ -20484,13 +20822,18 @@ class JvGridComponent {
|
|
|
20484
20822
|
/>
|
|
20485
20823
|
</th>
|
|
20486
20824
|
}
|
|
20487
|
-
@for (col of visibleColumns(); track colKey(col)) {
|
|
20825
|
+
@for (col of visibleColumns(); track colKey(col); let colIdx = $index) {
|
|
20488
20826
|
<th
|
|
20489
20827
|
class="jv-grid-th"
|
|
20490
20828
|
[class]="col.headerClass || ''"
|
|
20491
20829
|
[class.jv-grid-th-sortable]="col.sortable !== false && resolvedOptions().sortable"
|
|
20830
|
+
[class.jv-grid-th-sticky-left]="isStickyLeft(col)"
|
|
20831
|
+
[class.jv-grid-th-sticky-right]="isStickyRight(col)"
|
|
20832
|
+
[class.jv-grid-th-reorderable]="resolvedOptions().reorderableColumns"
|
|
20492
20833
|
[style.text-align]="col.align ?? 'start'"
|
|
20493
|
-
[style.width]="col
|
|
20834
|
+
[style.width]="getColumnWidth(col)"
|
|
20835
|
+
[style.min-width]="col.minWidth || undefined"
|
|
20836
|
+
[style.max-width]="col.maxWidth || undefined"
|
|
20494
20837
|
scope="col"
|
|
20495
20838
|
[attr.aria-sort]="getAriaSort(col)"
|
|
20496
20839
|
[attr.aria-label]="getSortLabel(col)"
|
|
@@ -20498,6 +20841,11 @@ class JvGridComponent {
|
|
|
20498
20841
|
(click)="toggleSort(col)"
|
|
20499
20842
|
(keydown.enter)="toggleSort(col)"
|
|
20500
20843
|
(keydown.space)="toggleSort(col, $event)"
|
|
20844
|
+
draggable="{{ resolvedOptions().reorderableColumns ? 'true' : 'false' }}"
|
|
20845
|
+
(dragstart)="onDragStart($event, colIdx)"
|
|
20846
|
+
(dragover)="onDragOver($event, colIdx)"
|
|
20847
|
+
(drop)="onDrop($event, colIdx)"
|
|
20848
|
+
(dragend)="onDragEnd($event)"
|
|
20501
20849
|
>
|
|
20502
20850
|
<div class="jv-grid-th-content">
|
|
20503
20851
|
<span>{{ col.header }}</span>
|
|
@@ -20510,45 +20858,78 @@ class JvGridComponent {
|
|
|
20510
20858
|
</span>
|
|
20511
20859
|
}
|
|
20512
20860
|
</div>
|
|
20861
|
+
@if (isColumnResizable(col)) {
|
|
20862
|
+
<div
|
|
20863
|
+
class="jv-grid-resize-handle"
|
|
20864
|
+
(mousedown)="onResizeStart($event, col, colIdx)"
|
|
20865
|
+
></div>
|
|
20866
|
+
}
|
|
20513
20867
|
</th>
|
|
20514
20868
|
}
|
|
20515
|
-
@if (actions().length > 0) {
|
|
20869
|
+
@if (!hasGroupedHeaders && actions().length > 0) {
|
|
20516
20870
|
<th class="jv-grid-th jv-grid-th-actions" scope="col">
|
|
20517
20871
|
<span class="sr-only">{{ t('grid.actionsLabel', { label: '' }) }}</span>
|
|
20518
20872
|
</th>
|
|
20519
20873
|
}
|
|
20520
20874
|
</tr>
|
|
20875
|
+
|
|
20876
|
+
@if (resolvedOptions().columnFilters) {
|
|
20877
|
+
<tr class="jv-grid-filter-row">
|
|
20878
|
+
@if (resolvedOptions().selectable) {
|
|
20879
|
+
<th class="jv-grid-th jv-grid-th-select"></th>
|
|
20880
|
+
}
|
|
20881
|
+
@for (col of visibleColumns(); track colKey(col)) {
|
|
20882
|
+
<th class="jv-grid-th jv-grid-th-filter">
|
|
20883
|
+
@if (col.filterable !== false) {
|
|
20884
|
+
<input
|
|
20885
|
+
class="jv-grid-filter-input"
|
|
20886
|
+
[placeholder]="t('grid.filterPlaceholder')"
|
|
20887
|
+
[attr.aria-label]="t('grid.filterForColumn', { column: col.header })"
|
|
20888
|
+
[ngModel]="colFilters()[colKey(col)]?.value ?? ''"
|
|
20889
|
+
(ngModelChange)="onColumnFilterChange(col, $event)"
|
|
20890
|
+
/>
|
|
20891
|
+
}
|
|
20892
|
+
</th>
|
|
20893
|
+
}
|
|
20894
|
+
@if (actions().length > 0) {
|
|
20895
|
+
<th class="jv-grid-th jv-grid-th-actions"></th>
|
|
20896
|
+
}
|
|
20897
|
+
</tr>
|
|
20898
|
+
}
|
|
20521
20899
|
</thead>
|
|
20900
|
+
|
|
20522
20901
|
<tbody class="jv-grid-tbody">
|
|
20523
|
-
@if (
|
|
20902
|
+
@if (displayData().length === 0 && !searchTerm().trim() && !hasActiveFilters()) {
|
|
20524
20903
|
<tr>
|
|
20525
|
-
<td
|
|
20526
|
-
class="jv-grid-empty"
|
|
20527
|
-
[attr.colspan]="colspan()"
|
|
20528
|
-
>
|
|
20904
|
+
<td class="jv-grid-empty" [attr.colspan]="colspan()">
|
|
20529
20905
|
{{ resolvedOptions().emptyMessage || t('grid.emptyMessage') }}
|
|
20530
20906
|
</td>
|
|
20531
20907
|
</tr>
|
|
20532
|
-
} @else if (
|
|
20908
|
+
} @else if (displayData().length === 0 && (searchTerm().trim() || hasActiveFilters())) {
|
|
20533
20909
|
<tr>
|
|
20534
|
-
<td
|
|
20535
|
-
class="jv-grid-empty"
|
|
20536
|
-
[attr.colspan]="colspan()"
|
|
20537
|
-
>
|
|
20910
|
+
<td class="jv-grid-empty" [attr.colspan]="colspan()">
|
|
20538
20911
|
{{ resolvedOptions().noResultsMessage || t('grid.noResults') }}
|
|
20539
20912
|
</td>
|
|
20540
20913
|
</tr>
|
|
20541
20914
|
} @else {
|
|
20542
|
-
@for (row of
|
|
20915
|
+
@for (row of displayData(); track getRowId(row, $index); let rowIdx = $index) {
|
|
20543
20916
|
<tr
|
|
20544
20917
|
class="jv-grid-tr"
|
|
20918
|
+
role="row"
|
|
20919
|
+
[class.jv-grid-tr-editing]="isRowEditing(row)"
|
|
20920
|
+
[class.jv-grid-tr-selected]="isSelected(row)"
|
|
20921
|
+
[attr.aria-selected]="resolvedOptions().selectable ? isSelected(row) : null"
|
|
20545
20922
|
(click)="onRowClick(row)"
|
|
20923
|
+
(dblclick)="onRowDblClick(row)"
|
|
20546
20924
|
(keydown.enter)="onRowClick(row)"
|
|
20547
20925
|
(keydown.space)="onRowClick($event, row)"
|
|
20548
|
-
[tabindex]="
|
|
20926
|
+
[tabindex]="-1"
|
|
20549
20927
|
>
|
|
20550
20928
|
@if (resolvedOptions().selectable) {
|
|
20551
|
-
<td
|
|
20929
|
+
<td
|
|
20930
|
+
class="jv-grid-td jv-grid-td-select"
|
|
20931
|
+
[class.jv-grid-td-sticky-left]="resolvedOptions().stickyColumns"
|
|
20932
|
+
>
|
|
20552
20933
|
<input
|
|
20553
20934
|
type="checkbox"
|
|
20554
20935
|
class="jv-grid-checkbox"
|
|
@@ -20563,24 +20944,61 @@ class JvGridComponent {
|
|
|
20563
20944
|
<td
|
|
20564
20945
|
class="jv-grid-td"
|
|
20565
20946
|
[class]="col.cellClass || ''"
|
|
20947
|
+
[class.jv-grid-td-sticky-left]="isStickyLeft(col)"
|
|
20948
|
+
[class.jv-grid-td-sticky-right]="isStickyRight(col)"
|
|
20949
|
+
[class.jv-grid-td-editable]="isCellEditable(col)"
|
|
20566
20950
|
[style.text-align]="col.align ?? 'start'"
|
|
20951
|
+
(dblclick)="startEdit(row, col, $event)"
|
|
20952
|
+
(keydown.enter)="startEdit(row, col, $event)"
|
|
20953
|
+
[tabindex]="isCellEditable(col) ? -1 : null"
|
|
20567
20954
|
>
|
|
20568
|
-
@
|
|
20569
|
-
|
|
20570
|
-
|
|
20571
|
-
|
|
20955
|
+
@if (isEditingCell(row, col)) {
|
|
20956
|
+
@if (col.editType === 'select' && col.editOptions) {
|
|
20957
|
+
<jv-select
|
|
20958
|
+
[options]="getEditOptions(col)"
|
|
20959
|
+
[modelValue]="getEditValue(row, col)"
|
|
20960
|
+
(selectionChange)="onEditValueChange(row, col, $event)"
|
|
20961
|
+
/>
|
|
20962
|
+
} @else if (col.editType === 'boolean') {
|
|
20963
|
+
<input
|
|
20964
|
+
type="checkbox"
|
|
20965
|
+
class="jv-grid-checkbox"
|
|
20966
|
+
[checked]="getCellValue(row, col) === true"
|
|
20967
|
+
(change)="commitEdit(row, col, $any($event.target).checked)"
|
|
20968
|
+
[attr.aria-label]="col.header"
|
|
20969
|
+
/>
|
|
20572
20970
|
} @else {
|
|
20573
|
-
<
|
|
20971
|
+
<input
|
|
20972
|
+
class="jv-grid-edit-input"
|
|
20973
|
+
[type]="col.editType === 'number' ? 'number' : 'text'"
|
|
20974
|
+
[value]="getEditValue(row, col)"
|
|
20975
|
+
(blur)="commitEdit(row, col, $any($event.target).value)"
|
|
20976
|
+
(keydown.enter)="commitEdit(row, col, $any($event.target).value)"
|
|
20977
|
+
(keydown.escape)="cancelEdit()"
|
|
20978
|
+
autofocus
|
|
20979
|
+
/>
|
|
20574
20980
|
}
|
|
20575
|
-
} @else if (col.format) {
|
|
20576
|
-
{{ col.format(value, row) }}
|
|
20577
20981
|
} @else {
|
|
20578
|
-
|
|
20982
|
+
@let value = getCellValue(row, col);
|
|
20983
|
+
@if (col.type === 'boolean') {
|
|
20984
|
+
@if (value) {
|
|
20985
|
+
<span class="jv-grid-boolean jv-grid-boolean-true" aria-label="true">✓</span>
|
|
20986
|
+
} @else {
|
|
20987
|
+
<span class="jv-grid-boolean jv-grid-boolean-false" aria-label="false">✗</span>
|
|
20988
|
+
}
|
|
20989
|
+
} @else if (col.format) {
|
|
20990
|
+
{{ col.format(value, row) }}
|
|
20991
|
+
} @else {
|
|
20992
|
+
{{ formatValue(value, col) }}
|
|
20993
|
+
}
|
|
20579
20994
|
}
|
|
20580
20995
|
</td>
|
|
20581
20996
|
}
|
|
20582
20997
|
@if (actions().length > 0) {
|
|
20583
|
-
<td
|
|
20998
|
+
<td
|
|
20999
|
+
class="jv-grid-td jv-grid-td-actions"
|
|
21000
|
+
[class.jv-grid-td-sticky-right]="resolvedOptions().stickyColumns"
|
|
21001
|
+
>
|
|
20584
21002
|
<div class="jv-grid-actions-group">
|
|
20585
21003
|
@for (action of actions(); track action.id) {
|
|
20586
21004
|
<jv-button
|
|
@@ -20588,8 +21006,9 @@ class JvGridComponent {
|
|
|
20588
21006
|
[icon]="action.icon ?? null"
|
|
20589
21007
|
[disabled]="action.disabled?.(row) ?? false"
|
|
20590
21008
|
[attr.aria-label]="action.label"
|
|
21009
|
+
[title]="action.label"
|
|
20591
21010
|
(click)="onActionClick(action, row); $event.stopPropagation()"
|
|
20592
|
-
|
|
21011
|
+
></jv-button>
|
|
20593
21012
|
}
|
|
20594
21013
|
</div>
|
|
20595
21014
|
</td>
|
|
@@ -20602,10 +21021,10 @@ class JvGridComponent {
|
|
|
20602
21021
|
</div>
|
|
20603
21022
|
}
|
|
20604
21023
|
|
|
20605
|
-
@if (resolvedOptions().pageable &&
|
|
20606
|
-
<nav class="jv-grid-pagination" [attr.aria-label]="t('grid.paginationLabel', { label: '' })">
|
|
20607
|
-
<div class="jv-grid-pagination-info">
|
|
20608
|
-
{{ t('grid.itemsShowing', { start: pageStart(), end: pageEnd(), total:
|
|
21024
|
+
@if (resolvedOptions().pageable && effectiveTotalPages() > 1 && !resolvedOptions().loading) {
|
|
21025
|
+
<nav class="jv-grid-pagination" role="navigation" [attr.aria-label]="t('grid.paginationLabel', { label: '' })">
|
|
21026
|
+
<div class="jv-grid-pagination-info" aria-live="polite" aria-atomic="true">
|
|
21027
|
+
{{ t('grid.itemsShowing', { start: pageStart(), end: pageEnd(), total: effectiveTotalItems() }) }}
|
|
20609
21028
|
</div>
|
|
20610
21029
|
<div class="jv-grid-pagination-controls">
|
|
20611
21030
|
<jv-button
|
|
@@ -20626,45 +21045,53 @@ class JvGridComponent {
|
|
|
20626
21045
|
<jv-button
|
|
20627
21046
|
[variant]="p === pageIndex() ? 'primary' : 'outline'"
|
|
20628
21047
|
[attr.aria-current]="p === pageIndex() ? 'page' : null"
|
|
20629
|
-
[attr.aria-label]="t('grid.pageOfTotal', { page: p + 1, total:
|
|
21048
|
+
[attr.aria-label]="t('grid.pageOfTotal', { page: p + 1, total: effectiveTotalPages() })"
|
|
20630
21049
|
(click)="goToPage(p)"
|
|
20631
21050
|
>{{ p + 1 }}</jv-button>
|
|
20632
21051
|
}
|
|
20633
21052
|
<jv-button
|
|
20634
21053
|
variant="outline"
|
|
20635
21054
|
icon="chevron-right"
|
|
20636
|
-
[disabled]="pageIndex() >=
|
|
21055
|
+
[disabled]="pageIndex() >= effectiveTotalPages() - 1"
|
|
20637
21056
|
(click)="goToPage(pageIndex() + 1)"
|
|
20638
21057
|
[attr.aria-label]="t('grid.pageNext')"
|
|
20639
21058
|
></jv-button>
|
|
20640
21059
|
<jv-button
|
|
20641
21060
|
variant="outline"
|
|
20642
21061
|
icon="chevrons-right"
|
|
20643
|
-
[disabled]="pageIndex() >=
|
|
20644
|
-
(click)="goToPage(
|
|
21062
|
+
[disabled]="pageIndex() >= effectiveTotalPages() - 1"
|
|
21063
|
+
(click)="goToPage(effectiveTotalPages() - 1)"
|
|
20645
21064
|
[attr.aria-label]="t('grid.pageLast')"
|
|
20646
21065
|
></jv-button>
|
|
20647
21066
|
</div>
|
|
20648
21067
|
</nav>
|
|
20649
21068
|
}
|
|
20650
21069
|
</div>
|
|
20651
|
-
`, isInline: true, styles: [".jv-grid{display:flex;flex-direction:column;gap:var(--jv-spacing-md)}.jv-grid-toolbar{display:flex;align-items:center;gap:var(--jv-spacing-md)}.jv-grid-search{display:flex;align-items:center;gap:var(--jv-spacing-sm)}.jv-grid-table-wrap{overflow-x:auto;border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md)}.jv-grid-table{width:100%;border-collapse:collapse;background:var(--jv-color-surface)}.jv-grid-thead{background:var(--jv-color-surface-muted)}.jv-grid-th{padding:var(--jv-spacing-sm) var(--jv-spacing-md);font-weight:600;font-size:.875rem;color:var(--jv-color-foreground-muted);text-align:start;white-space:nowrap;border-bottom:1px solid var(--jv-color-border);-webkit-user-select:none;user-select:none}.jv-grid-th-sortable{cursor:pointer}.jv-grid-th-sortable:hover{background:var(--jv-color-surface)}.jv-grid-th-content{display:flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-grid-sort-icon{font-size:.75rem;line-height:1}.jv-grid-th-select,.jv-grid-td-select{width:3rem;text-align:center}.jv-grid-th-actions,.jv-grid-td-actions{width:1%;white-space:nowrap}.jv-grid-td{padding:var(--jv-spacing-sm) var(--jv-spacing-md);color:var(--jv-color-foreground);font-size:var(--jv-density-font-size);border-bottom:1px solid var(--jv-color-border)}.jv-grid-tr{transition:background-color .12s ease}.jv-grid-tr:hover{background:var(--jv-color-surface-muted)}.jv-grid-tr:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-grid-checkbox{width:1rem;height:1rem;accent-color:var(--jv-color-primary);cursor:pointer}.jv-grid-boolean{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:999px;font-size:.75rem;font-weight:700}.jv-grid-boolean-true{background:var(--jv-color-success);color:#fff}.jv-grid-boolean-false{background:var(--jv-color-danger);color:#fff}.jv-grid-empty{padding:var(--jv-spacing-xl) var(--jv-spacing-md);text-align:center;color:var(--jv-color-foreground-muted);font-style:italic}.jv-grid-actions-group{display:flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-grid-loading{display:flex;align-items:center;justify-content:center;gap:var(--jv-spacing-md);padding:var(--jv-spacing-xl);color:var(--jv-color-foreground-muted)}.jv-grid-spinner{width:1.25rem;height:1.25rem;border:2px solid var(--jv-color-border);border-right-color:var(--jv-color-primary);border-radius:999px;animation:jv-grid-spin .8s linear infinite}@keyframes jv-grid-spin{to{transform:rotate(360deg)}}.jv-grid-pagination{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);flex-wrap:wrap}.jv-grid-pagination-info{font-size:.875rem;color:var(--jv-color-foreground-muted)}.jv-grid-pagination-controls{display:flex;align-items:center;gap:var(--jv-spacing-xs)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: JvButtonComponent, selector: "jv-button", inputs: ["type", "variant", "icon", "iconPosition", "loading", "disabled"] }, { kind: "component", type: JvIconComponent, selector: "jv-icon", inputs: ["name", "size", "strokeWidth", "decorative", "ariaLabel"] }, { kind: "component", type: JvInputComponent, selector: "jv-input", inputs: ["type", "placeholder", "required", "invalid", "describedBy", "inputId"] }] });
|
|
21070
|
+
`, isInline: true, styles: [".jv-grid{display:flex;flex-direction:column;gap:var(--jv-spacing-md)}.jv-grid-toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);flex-wrap:wrap}.jv-grid-search{display:flex;align-items:center;gap:var(--jv-spacing-sm)}.jv-grid-export-actions{display:flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-grid-table-wrap{overflow-x:auto;overflow-y:auto;-webkit-overflow-scrolling:touch;border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);position:relative}.jv-grid-virtual{max-height:600px}.jv-grid-virtual-spacer{pointer-events:none}.jv-grid-table{width:100%;border-collapse:collapse;background:var(--jv-color-surface)}.jv-grid-thead{background:var(--jv-color-surface-muted)}.jv-grid-th{padding:var(--jv-spacing-sm) var(--jv-spacing-md);font-weight:600;font-size:.875rem;color:var(--jv-color-foreground-muted);text-align:start;white-space:nowrap;border-bottom:1px solid var(--jv-color-border);-webkit-user-select:none;user-select:none;position:relative}.jv-grid-th-sortable{cursor:pointer}.jv-grid-th-sortable:hover{background:var(--jv-color-surface)}.jv-grid-th-reorderable{cursor:grab}.jv-grid-th-reorderable:active{cursor:grabbing}.jv-grid-th-sticky-left{position:sticky;left:0;z-index:2;background:var(--jv-color-surface-muted);border-right:1px solid var(--jv-color-border)}.jv-grid-th-sticky-right{position:sticky;right:0;z-index:2;background:var(--jv-color-surface-muted);border-left:1px solid var(--jv-color-border)}.jv-grid-th-content{display:flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-grid-sort-icon{font-size:.75rem;line-height:1}.jv-grid-th-select,.jv-grid-td-select{width:3rem;text-align:center}.jv-grid-th-actions,.jv-grid-td-actions{width:1%;white-space:nowrap}.jv-grid-td{padding:var(--jv-spacing-sm) var(--jv-spacing-md);color:var(--jv-color-foreground);font-size:var(--jv-density-font-size);border-bottom:1px solid var(--jv-color-border)}.jv-grid-td-sticky-left{position:sticky;left:0;z-index:1;background:var(--jv-color-surface);border-right:1px solid var(--jv-color-border)}.jv-grid-td-sticky-right{position:sticky;right:0;z-index:1;background:var(--jv-color-surface);border-left:1px solid var(--jv-color-border)}.jv-grid-t:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-grid-tr{transition:background-color .12s ease}.jv-grid-tr:hover{background:var(--jv-color-surface-muted)}.jv-grid-tr:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-grid-tr-editing{background:var(--jv-color-surface-highlight, rgba(59, 130, 246, .05))}.jv-grid-tr-selected{background:var(--jv-color-primary-light, rgba(59, 130, 246, .08))}.jv-grid-checkbox{width:1rem;height:1rem;accent-color:var(--jv-color-primary);cursor:pointer}.jv-grid-boolean{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:999px;font-size:.75rem;font-weight:700}.jv-grid-boolean-true{background:var(--jv-color-success);color:#fff}.jv-grid-boolean-false{background:var(--jv-color-danger);color:#fff}.jv-grid-empty{padding:var(--jv-spacing-xl) var(--jv-spacing-md);text-align:center;color:var(--jv-color-foreground-muted);font-style:italic}.jv-grid-actions-group{display:flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-grid-loading{display:flex;align-items:center;justify-content:center;gap:var(--jv-spacing-md);padding:var(--jv-spacing-xl);color:var(--jv-color-foreground-muted)}.jv-grid-spinner{width:1.25rem;height:1.25rem;border:2px solid var(--jv-color-border);border-right-color:var(--jv-color-primary);border-radius:999px;animation:jv-grid-spin .8s linear infinite}@keyframes jv-grid-spin{to{transform:rotate(360deg)}}.jv-grid-pagination{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);flex-wrap:wrap}.jv-grid-pagination-info{font-size:.875rem;color:var(--jv-color-foreground-muted)}.jv-grid-pagination-controls{display:flex;align-items:center;gap:var(--jv-spacing-xs);flex-wrap:wrap}@media(max-width:640px){.jv-grid-pagination{flex-direction:column;align-items:stretch;gap:var(--jv-spacing-sm)}.jv-grid-pagination-info{text-align:center}.jv-grid-pagination-controls{justify-content:center}.jv-grid-toolbar{flex-direction:column;align-items:stretch}.jv-grid-search{width:100%}.jv-grid-export-actions{justify-content:stretch}.jv-grid-export-actions jv-button{flex:1}}.jv-grid-resize-handle{position:absolute;top:0;right:0;width:4px;height:100%;cursor:col-resize;background:transparent;z-index:3}.jv-grid-resize-handle:hover,.jv-grid-resize-handle:active{background:var(--jv-color-primary)}.jv-grid-filter-row .jv-grid-th{padding:var(--jv-spacing-xs) var(--jv-spacing-sm)}.jv-grid-filter-input{width:100%;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-sm);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-sm);background:var(--jv-color-surface);color:var(--jv-color-foreground);font-size:.8rem;box-sizing:border-box}.jv-grid-td-editable{cursor:pointer}.jv-grid-td-editable:hover{box-shadow:inset 0 0 0 1px var(--jv-color-primary)}.jv-grid-edit-input{width:100%;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-sm);border:1px solid var(--jv-color-primary);border-radius:var(--jv-radius-sm);background:var(--jv-color-surface);color:var(--jv-color-foreground);font-size:var(--jv-density-font-size);box-sizing:border-box}.jv-grid-edit-input:focus{outline:2px solid var(--jv-color-primary);outline-offset:-1px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: JvButtonComponent, selector: "jv-button", inputs: ["type", "variant", "icon", "iconPosition", "loading", "disabled"] }, { kind: "component", type: JvIconComponent, selector: "jv-icon", inputs: ["name", "size", "strokeWidth", "decorative", "ariaLabel"] }, { kind: "component", type: JvInputComponent, selector: "jv-input", inputs: ["type", "placeholder", "required", "invalid", "describedBy", "inputId"] }, { kind: "component", type: JvSelectComponent, selector: "jv-select", inputs: ["options", "placeholder", "required", "invalid", "describedBy", "inputId", "modelValue"], outputs: ["selectionChange"] }] });
|
|
20652
21071
|
}
|
|
20653
21072
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvGridComponent, decorators: [{
|
|
20654
21073
|
type: Component,
|
|
20655
|
-
args: [{ selector: 'jv-grid', standalone: true, imports: [FormsModule, JvButtonComponent, JvIconComponent, JvInputComponent], template: `
|
|
21074
|
+
args: [{ selector: 'jv-grid', standalone: true, imports: [FormsModule, JvButtonComponent, JvIconComponent, JvInputComponent, JvSelectComponent], template: `
|
|
20656
21075
|
<div class="jv-grid" role="region" [attr.aria-label]="resolvedOptions().ariaLabel || gridLabel()">
|
|
20657
|
-
@if (resolvedOptions().searchable) {
|
|
21076
|
+
@if (resolvedOptions().searchable || resolvedOptions().exportable) {
|
|
20658
21077
|
<div class="jv-grid-toolbar">
|
|
20659
|
-
|
|
20660
|
-
<
|
|
20661
|
-
|
|
20662
|
-
|
|
20663
|
-
|
|
20664
|
-
|
|
20665
|
-
|
|
20666
|
-
|
|
20667
|
-
|
|
21078
|
+
@if (resolvedOptions().searchable) {
|
|
21079
|
+
<div class="jv-grid-search">
|
|
21080
|
+
<jv-icon name="search" [size]="16" />
|
|
21081
|
+
<jv-input
|
|
21082
|
+
inputId="grid-search"
|
|
21083
|
+
[placeholder]="t('grid.searchPlaceholder')"
|
|
21084
|
+
[ngModel]="searchTerm()"
|
|
21085
|
+
(ngModelChange)="onSearchInput($event)"
|
|
21086
|
+
/>
|
|
21087
|
+
</div>
|
|
21088
|
+
}
|
|
21089
|
+
@if (resolvedOptions().exportable) {
|
|
21090
|
+
<div class="jv-grid-export-actions">
|
|
21091
|
+
<jv-button variant="outline" icon="download" (click)="exportCsv()">{{ t('grid.exportCsv') }}</jv-button>
|
|
21092
|
+
<jv-button variant="outline" icon="file-spreadsheet" (click)="exportExcel()">{{ t('grid.exportExcel') }}</jv-button>
|
|
21093
|
+
</div>
|
|
21094
|
+
}
|
|
20668
21095
|
</div>
|
|
20669
21096
|
}
|
|
20670
21097
|
|
|
@@ -20674,17 +21101,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
20674
21101
|
<span>{{ t('grid.loading') }}</span>
|
|
20675
21102
|
</div>
|
|
20676
21103
|
} @else {
|
|
20677
|
-
<div
|
|
21104
|
+
<div
|
|
21105
|
+
class="jv-grid-table-wrap"
|
|
21106
|
+
[class.jv-grid-virtual]="resolvedOptions().virtualScroll"
|
|
21107
|
+
#tableWrap
|
|
21108
|
+
(scroll)="onVirtualScroll($any($event.target))"
|
|
21109
|
+
>
|
|
21110
|
+
@if (resolvedOptions().virtualScroll) {
|
|
21111
|
+
<div class="jv-grid-virtual-spacer" [style.height.px]="virtualTotalHeight()"></div>
|
|
21112
|
+
}
|
|
20678
21113
|
<table
|
|
20679
21114
|
class="jv-grid-table"
|
|
20680
21115
|
role="grid"
|
|
20681
21116
|
[attr.aria-label]="resolvedOptions().ariaLabel || gridLabel()"
|
|
21117
|
+
[attr.aria-rowcount]="effectiveTotalItems()"
|
|
21118
|
+
[attr.aria-colcount]="visibleColumns().length"
|
|
20682
21119
|
[class]="densityClass()"
|
|
21120
|
+
[style.position]="resolvedOptions().virtualScroll ? 'relative' : null"
|
|
21121
|
+
[style.top.px]="virtualOffsetY()"
|
|
20683
21122
|
>
|
|
20684
21123
|
<caption class="sr-only">{{ resolvedOptions().ariaLabel || gridLabel() }}</caption>
|
|
21124
|
+
|
|
21125
|
+
@let hasGroupedHeaders = groupedHeaders().length > 0;
|
|
21126
|
+
|
|
20685
21127
|
<thead class="jv-grid-thead">
|
|
21128
|
+
@if (hasGroupedHeaders) {
|
|
21129
|
+
<tr>
|
|
21130
|
+
@if (resolvedOptions().selectable) {
|
|
21131
|
+
<th class="jv-grid-th jv-grid-th-select" scope="col" [attr.rowspan]="2">
|
|
21132
|
+
<input
|
|
21133
|
+
type="checkbox"
|
|
21134
|
+
class="jv-grid-checkbox"
|
|
21135
|
+
[checked]="allSelected()"
|
|
21136
|
+
(change)="toggleSelectAll($any($event.target).checked)"
|
|
21137
|
+
[attr.aria-label]="allSelected() ? t('grid.deselectAll') : t('grid.selectAll')"
|
|
21138
|
+
[indeterminate]="someSelected()"
|
|
21139
|
+
/>
|
|
21140
|
+
</th>
|
|
21141
|
+
}
|
|
21142
|
+
@for (group of groupedHeaders(); track colKey(group)) {
|
|
21143
|
+
<th
|
|
21144
|
+
class="jv-grid-th"
|
|
21145
|
+
[class]="group.headerClass || ''"
|
|
21146
|
+
[class.jv-grid-th-sticky-left]="isStickyLeft(group)"
|
|
21147
|
+
[class.jv-grid-th-sticky-right]="isStickyRight(group)"
|
|
21148
|
+
[attr.colspan]="groupColspan(group)"
|
|
21149
|
+
scope="colgroup"
|
|
21150
|
+
[style.text-align]="group.align ?? 'start'"
|
|
21151
|
+
>
|
|
21152
|
+
<div class="jv-grid-th-content">{{ group.header }}</div>
|
|
21153
|
+
</th>
|
|
21154
|
+
}
|
|
21155
|
+
@if (actions().length > 0) {
|
|
21156
|
+
<th class="jv-grid-th jv-grid-th-actions" scope="col" [attr.rowspan]="2">
|
|
21157
|
+
<span class="sr-only">{{ t('grid.actionsLabel', { label: '' }) }}</span>
|
|
21158
|
+
</th>
|
|
21159
|
+
}
|
|
21160
|
+
</tr>
|
|
21161
|
+
}
|
|
21162
|
+
|
|
20686
21163
|
<tr>
|
|
20687
|
-
@if (resolvedOptions().selectable) {
|
|
21164
|
+
@if (!hasGroupedHeaders && resolvedOptions().selectable) {
|
|
20688
21165
|
<th class="jv-grid-th jv-grid-th-select" scope="col">
|
|
20689
21166
|
<input
|
|
20690
21167
|
type="checkbox"
|
|
@@ -20696,13 +21173,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
20696
21173
|
/>
|
|
20697
21174
|
</th>
|
|
20698
21175
|
}
|
|
20699
|
-
@for (col of visibleColumns(); track colKey(col)) {
|
|
21176
|
+
@for (col of visibleColumns(); track colKey(col); let colIdx = $index) {
|
|
20700
21177
|
<th
|
|
20701
21178
|
class="jv-grid-th"
|
|
20702
21179
|
[class]="col.headerClass || ''"
|
|
20703
21180
|
[class.jv-grid-th-sortable]="col.sortable !== false && resolvedOptions().sortable"
|
|
21181
|
+
[class.jv-grid-th-sticky-left]="isStickyLeft(col)"
|
|
21182
|
+
[class.jv-grid-th-sticky-right]="isStickyRight(col)"
|
|
21183
|
+
[class.jv-grid-th-reorderable]="resolvedOptions().reorderableColumns"
|
|
20704
21184
|
[style.text-align]="col.align ?? 'start'"
|
|
20705
|
-
[style.width]="col
|
|
21185
|
+
[style.width]="getColumnWidth(col)"
|
|
21186
|
+
[style.min-width]="col.minWidth || undefined"
|
|
21187
|
+
[style.max-width]="col.maxWidth || undefined"
|
|
20706
21188
|
scope="col"
|
|
20707
21189
|
[attr.aria-sort]="getAriaSort(col)"
|
|
20708
21190
|
[attr.aria-label]="getSortLabel(col)"
|
|
@@ -20710,6 +21192,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
20710
21192
|
(click)="toggleSort(col)"
|
|
20711
21193
|
(keydown.enter)="toggleSort(col)"
|
|
20712
21194
|
(keydown.space)="toggleSort(col, $event)"
|
|
21195
|
+
draggable="{{ resolvedOptions().reorderableColumns ? 'true' : 'false' }}"
|
|
21196
|
+
(dragstart)="onDragStart($event, colIdx)"
|
|
21197
|
+
(dragover)="onDragOver($event, colIdx)"
|
|
21198
|
+
(drop)="onDrop($event, colIdx)"
|
|
21199
|
+
(dragend)="onDragEnd($event)"
|
|
20713
21200
|
>
|
|
20714
21201
|
<div class="jv-grid-th-content">
|
|
20715
21202
|
<span>{{ col.header }}</span>
|
|
@@ -20722,45 +21209,78 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
20722
21209
|
</span>
|
|
20723
21210
|
}
|
|
20724
21211
|
</div>
|
|
21212
|
+
@if (isColumnResizable(col)) {
|
|
21213
|
+
<div
|
|
21214
|
+
class="jv-grid-resize-handle"
|
|
21215
|
+
(mousedown)="onResizeStart($event, col, colIdx)"
|
|
21216
|
+
></div>
|
|
21217
|
+
}
|
|
20725
21218
|
</th>
|
|
20726
21219
|
}
|
|
20727
|
-
@if (actions().length > 0) {
|
|
21220
|
+
@if (!hasGroupedHeaders && actions().length > 0) {
|
|
20728
21221
|
<th class="jv-grid-th jv-grid-th-actions" scope="col">
|
|
20729
21222
|
<span class="sr-only">{{ t('grid.actionsLabel', { label: '' }) }}</span>
|
|
20730
21223
|
</th>
|
|
20731
21224
|
}
|
|
20732
21225
|
</tr>
|
|
21226
|
+
|
|
21227
|
+
@if (resolvedOptions().columnFilters) {
|
|
21228
|
+
<tr class="jv-grid-filter-row">
|
|
21229
|
+
@if (resolvedOptions().selectable) {
|
|
21230
|
+
<th class="jv-grid-th jv-grid-th-select"></th>
|
|
21231
|
+
}
|
|
21232
|
+
@for (col of visibleColumns(); track colKey(col)) {
|
|
21233
|
+
<th class="jv-grid-th jv-grid-th-filter">
|
|
21234
|
+
@if (col.filterable !== false) {
|
|
21235
|
+
<input
|
|
21236
|
+
class="jv-grid-filter-input"
|
|
21237
|
+
[placeholder]="t('grid.filterPlaceholder')"
|
|
21238
|
+
[attr.aria-label]="t('grid.filterForColumn', { column: col.header })"
|
|
21239
|
+
[ngModel]="colFilters()[colKey(col)]?.value ?? ''"
|
|
21240
|
+
(ngModelChange)="onColumnFilterChange(col, $event)"
|
|
21241
|
+
/>
|
|
21242
|
+
}
|
|
21243
|
+
</th>
|
|
21244
|
+
}
|
|
21245
|
+
@if (actions().length > 0) {
|
|
21246
|
+
<th class="jv-grid-th jv-grid-th-actions"></th>
|
|
21247
|
+
}
|
|
21248
|
+
</tr>
|
|
21249
|
+
}
|
|
20733
21250
|
</thead>
|
|
21251
|
+
|
|
20734
21252
|
<tbody class="jv-grid-tbody">
|
|
20735
|
-
@if (
|
|
21253
|
+
@if (displayData().length === 0 && !searchTerm().trim() && !hasActiveFilters()) {
|
|
20736
21254
|
<tr>
|
|
20737
|
-
<td
|
|
20738
|
-
class="jv-grid-empty"
|
|
20739
|
-
[attr.colspan]="colspan()"
|
|
20740
|
-
>
|
|
21255
|
+
<td class="jv-grid-empty" [attr.colspan]="colspan()">
|
|
20741
21256
|
{{ resolvedOptions().emptyMessage || t('grid.emptyMessage') }}
|
|
20742
21257
|
</td>
|
|
20743
21258
|
</tr>
|
|
20744
|
-
} @else if (
|
|
21259
|
+
} @else if (displayData().length === 0 && (searchTerm().trim() || hasActiveFilters())) {
|
|
20745
21260
|
<tr>
|
|
20746
|
-
<td
|
|
20747
|
-
class="jv-grid-empty"
|
|
20748
|
-
[attr.colspan]="colspan()"
|
|
20749
|
-
>
|
|
21261
|
+
<td class="jv-grid-empty" [attr.colspan]="colspan()">
|
|
20750
21262
|
{{ resolvedOptions().noResultsMessage || t('grid.noResults') }}
|
|
20751
21263
|
</td>
|
|
20752
21264
|
</tr>
|
|
20753
21265
|
} @else {
|
|
20754
|
-
@for (row of
|
|
21266
|
+
@for (row of displayData(); track getRowId(row, $index); let rowIdx = $index) {
|
|
20755
21267
|
<tr
|
|
20756
21268
|
class="jv-grid-tr"
|
|
21269
|
+
role="row"
|
|
21270
|
+
[class.jv-grid-tr-editing]="isRowEditing(row)"
|
|
21271
|
+
[class.jv-grid-tr-selected]="isSelected(row)"
|
|
21272
|
+
[attr.aria-selected]="resolvedOptions().selectable ? isSelected(row) : null"
|
|
20757
21273
|
(click)="onRowClick(row)"
|
|
21274
|
+
(dblclick)="onRowDblClick(row)"
|
|
20758
21275
|
(keydown.enter)="onRowClick(row)"
|
|
20759
21276
|
(keydown.space)="onRowClick($event, row)"
|
|
20760
|
-
[tabindex]="
|
|
21277
|
+
[tabindex]="-1"
|
|
20761
21278
|
>
|
|
20762
21279
|
@if (resolvedOptions().selectable) {
|
|
20763
|
-
<td
|
|
21280
|
+
<td
|
|
21281
|
+
class="jv-grid-td jv-grid-td-select"
|
|
21282
|
+
[class.jv-grid-td-sticky-left]="resolvedOptions().stickyColumns"
|
|
21283
|
+
>
|
|
20764
21284
|
<input
|
|
20765
21285
|
type="checkbox"
|
|
20766
21286
|
class="jv-grid-checkbox"
|
|
@@ -20775,24 +21295,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
20775
21295
|
<td
|
|
20776
21296
|
class="jv-grid-td"
|
|
20777
21297
|
[class]="col.cellClass || ''"
|
|
21298
|
+
[class.jv-grid-td-sticky-left]="isStickyLeft(col)"
|
|
21299
|
+
[class.jv-grid-td-sticky-right]="isStickyRight(col)"
|
|
21300
|
+
[class.jv-grid-td-editable]="isCellEditable(col)"
|
|
20778
21301
|
[style.text-align]="col.align ?? 'start'"
|
|
21302
|
+
(dblclick)="startEdit(row, col, $event)"
|
|
21303
|
+
(keydown.enter)="startEdit(row, col, $event)"
|
|
21304
|
+
[tabindex]="isCellEditable(col) ? -1 : null"
|
|
20779
21305
|
>
|
|
20780
|
-
@
|
|
20781
|
-
|
|
20782
|
-
|
|
20783
|
-
|
|
21306
|
+
@if (isEditingCell(row, col)) {
|
|
21307
|
+
@if (col.editType === 'select' && col.editOptions) {
|
|
21308
|
+
<jv-select
|
|
21309
|
+
[options]="getEditOptions(col)"
|
|
21310
|
+
[modelValue]="getEditValue(row, col)"
|
|
21311
|
+
(selectionChange)="onEditValueChange(row, col, $event)"
|
|
21312
|
+
/>
|
|
21313
|
+
} @else if (col.editType === 'boolean') {
|
|
21314
|
+
<input
|
|
21315
|
+
type="checkbox"
|
|
21316
|
+
class="jv-grid-checkbox"
|
|
21317
|
+
[checked]="getCellValue(row, col) === true"
|
|
21318
|
+
(change)="commitEdit(row, col, $any($event.target).checked)"
|
|
21319
|
+
[attr.aria-label]="col.header"
|
|
21320
|
+
/>
|
|
20784
21321
|
} @else {
|
|
20785
|
-
<
|
|
21322
|
+
<input
|
|
21323
|
+
class="jv-grid-edit-input"
|
|
21324
|
+
[type]="col.editType === 'number' ? 'number' : 'text'"
|
|
21325
|
+
[value]="getEditValue(row, col)"
|
|
21326
|
+
(blur)="commitEdit(row, col, $any($event.target).value)"
|
|
21327
|
+
(keydown.enter)="commitEdit(row, col, $any($event.target).value)"
|
|
21328
|
+
(keydown.escape)="cancelEdit()"
|
|
21329
|
+
autofocus
|
|
21330
|
+
/>
|
|
20786
21331
|
}
|
|
20787
|
-
} @else if (col.format) {
|
|
20788
|
-
{{ col.format(value, row) }}
|
|
20789
21332
|
} @else {
|
|
20790
|
-
|
|
21333
|
+
@let value = getCellValue(row, col);
|
|
21334
|
+
@if (col.type === 'boolean') {
|
|
21335
|
+
@if (value) {
|
|
21336
|
+
<span class="jv-grid-boolean jv-grid-boolean-true" aria-label="true">✓</span>
|
|
21337
|
+
} @else {
|
|
21338
|
+
<span class="jv-grid-boolean jv-grid-boolean-false" aria-label="false">✗</span>
|
|
21339
|
+
}
|
|
21340
|
+
} @else if (col.format) {
|
|
21341
|
+
{{ col.format(value, row) }}
|
|
21342
|
+
} @else {
|
|
21343
|
+
{{ formatValue(value, col) }}
|
|
21344
|
+
}
|
|
20791
21345
|
}
|
|
20792
21346
|
</td>
|
|
20793
21347
|
}
|
|
20794
21348
|
@if (actions().length > 0) {
|
|
20795
|
-
<td
|
|
21349
|
+
<td
|
|
21350
|
+
class="jv-grid-td jv-grid-td-actions"
|
|
21351
|
+
[class.jv-grid-td-sticky-right]="resolvedOptions().stickyColumns"
|
|
21352
|
+
>
|
|
20796
21353
|
<div class="jv-grid-actions-group">
|
|
20797
21354
|
@for (action of actions(); track action.id) {
|
|
20798
21355
|
<jv-button
|
|
@@ -20800,8 +21357,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
20800
21357
|
[icon]="action.icon ?? null"
|
|
20801
21358
|
[disabled]="action.disabled?.(row) ?? false"
|
|
20802
21359
|
[attr.aria-label]="action.label"
|
|
21360
|
+
[title]="action.label"
|
|
20803
21361
|
(click)="onActionClick(action, row); $event.stopPropagation()"
|
|
20804
|
-
|
|
21362
|
+
></jv-button>
|
|
20805
21363
|
}
|
|
20806
21364
|
</div>
|
|
20807
21365
|
</td>
|
|
@@ -20814,10 +21372,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
20814
21372
|
</div>
|
|
20815
21373
|
}
|
|
20816
21374
|
|
|
20817
|
-
@if (resolvedOptions().pageable &&
|
|
20818
|
-
<nav class="jv-grid-pagination" [attr.aria-label]="t('grid.paginationLabel', { label: '' })">
|
|
20819
|
-
<div class="jv-grid-pagination-info">
|
|
20820
|
-
{{ t('grid.itemsShowing', { start: pageStart(), end: pageEnd(), total:
|
|
21375
|
+
@if (resolvedOptions().pageable && effectiveTotalPages() > 1 && !resolvedOptions().loading) {
|
|
21376
|
+
<nav class="jv-grid-pagination" role="navigation" [attr.aria-label]="t('grid.paginationLabel', { label: '' })">
|
|
21377
|
+
<div class="jv-grid-pagination-info" aria-live="polite" aria-atomic="true">
|
|
21378
|
+
{{ t('grid.itemsShowing', { start: pageStart(), end: pageEnd(), total: effectiveTotalItems() }) }}
|
|
20821
21379
|
</div>
|
|
20822
21380
|
<div class="jv-grid-pagination-controls">
|
|
20823
21381
|
<jv-button
|
|
@@ -20838,30 +21396,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
20838
21396
|
<jv-button
|
|
20839
21397
|
[variant]="p === pageIndex() ? 'primary' : 'outline'"
|
|
20840
21398
|
[attr.aria-current]="p === pageIndex() ? 'page' : null"
|
|
20841
|
-
[attr.aria-label]="t('grid.pageOfTotal', { page: p + 1, total:
|
|
21399
|
+
[attr.aria-label]="t('grid.pageOfTotal', { page: p + 1, total: effectiveTotalPages() })"
|
|
20842
21400
|
(click)="goToPage(p)"
|
|
20843
21401
|
>{{ p + 1 }}</jv-button>
|
|
20844
21402
|
}
|
|
20845
21403
|
<jv-button
|
|
20846
21404
|
variant="outline"
|
|
20847
21405
|
icon="chevron-right"
|
|
20848
|
-
[disabled]="pageIndex() >=
|
|
21406
|
+
[disabled]="pageIndex() >= effectiveTotalPages() - 1"
|
|
20849
21407
|
(click)="goToPage(pageIndex() + 1)"
|
|
20850
21408
|
[attr.aria-label]="t('grid.pageNext')"
|
|
20851
21409
|
></jv-button>
|
|
20852
21410
|
<jv-button
|
|
20853
21411
|
variant="outline"
|
|
20854
21412
|
icon="chevrons-right"
|
|
20855
|
-
[disabled]="pageIndex() >=
|
|
20856
|
-
(click)="goToPage(
|
|
21413
|
+
[disabled]="pageIndex() >= effectiveTotalPages() - 1"
|
|
21414
|
+
(click)="goToPage(effectiveTotalPages() - 1)"
|
|
20857
21415
|
[attr.aria-label]="t('grid.pageLast')"
|
|
20858
21416
|
></jv-button>
|
|
20859
21417
|
</div>
|
|
20860
21418
|
</nav>
|
|
20861
21419
|
}
|
|
20862
21420
|
</div>
|
|
20863
|
-
`, styles: [".jv-grid{display:flex;flex-direction:column;gap:var(--jv-spacing-md)}.jv-grid-toolbar{display:flex;align-items:center;gap:var(--jv-spacing-md)}.jv-grid-search{display:flex;align-items:center;gap:var(--jv-spacing-sm)}.jv-grid-table-wrap{overflow-x:auto;border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md)}.jv-grid-table{width:100%;border-collapse:collapse;background:var(--jv-color-surface)}.jv-grid-thead{background:var(--jv-color-surface-muted)}.jv-grid-th{padding:var(--jv-spacing-sm) var(--jv-spacing-md);font-weight:600;font-size:.875rem;color:var(--jv-color-foreground-muted);text-align:start;white-space:nowrap;border-bottom:1px solid var(--jv-color-border);-webkit-user-select:none;user-select:none}.jv-grid-th-sortable{cursor:pointer}.jv-grid-th-sortable:hover{background:var(--jv-color-surface)}.jv-grid-th-content{display:flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-grid-sort-icon{font-size:.75rem;line-height:1}.jv-grid-th-select,.jv-grid-td-select{width:3rem;text-align:center}.jv-grid-th-actions,.jv-grid-td-actions{width:1%;white-space:nowrap}.jv-grid-td{padding:var(--jv-spacing-sm) var(--jv-spacing-md);color:var(--jv-color-foreground);font-size:var(--jv-density-font-size);border-bottom:1px solid var(--jv-color-border)}.jv-grid-tr{transition:background-color .12s ease}.jv-grid-tr:hover{background:var(--jv-color-surface-muted)}.jv-grid-tr:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-grid-checkbox{width:1rem;height:1rem;accent-color:var(--jv-color-primary);cursor:pointer}.jv-grid-boolean{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:999px;font-size:.75rem;font-weight:700}.jv-grid-boolean-true{background:var(--jv-color-success);color:#fff}.jv-grid-boolean-false{background:var(--jv-color-danger);color:#fff}.jv-grid-empty{padding:var(--jv-spacing-xl) var(--jv-spacing-md);text-align:center;color:var(--jv-color-foreground-muted);font-style:italic}.jv-grid-actions-group{display:flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-grid-loading{display:flex;align-items:center;justify-content:center;gap:var(--jv-spacing-md);padding:var(--jv-spacing-xl);color:var(--jv-color-foreground-muted)}.jv-grid-spinner{width:1.25rem;height:1.25rem;border:2px solid var(--jv-color-border);border-right-color:var(--jv-color-primary);border-radius:999px;animation:jv-grid-spin .8s linear infinite}@keyframes jv-grid-spin{to{transform:rotate(360deg)}}.jv-grid-pagination{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);flex-wrap:wrap}.jv-grid-pagination-info{font-size:.875rem;color:var(--jv-color-foreground-muted)}.jv-grid-pagination-controls{display:flex;align-items:center;gap:var(--jv-spacing-xs)}\n"] }]
|
|
20864
|
-
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], trackBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackBy", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIds", required: false }] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], searchChange: [{ type: i0.Output, args: ["searchChange"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }] } });
|
|
21421
|
+
`, styles: [".jv-grid{display:flex;flex-direction:column;gap:var(--jv-spacing-md)}.jv-grid-toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);flex-wrap:wrap}.jv-grid-search{display:flex;align-items:center;gap:var(--jv-spacing-sm)}.jv-grid-export-actions{display:flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-grid-table-wrap{overflow-x:auto;overflow-y:auto;-webkit-overflow-scrolling:touch;border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);position:relative}.jv-grid-virtual{max-height:600px}.jv-grid-virtual-spacer{pointer-events:none}.jv-grid-table{width:100%;border-collapse:collapse;background:var(--jv-color-surface)}.jv-grid-thead{background:var(--jv-color-surface-muted)}.jv-grid-th{padding:var(--jv-spacing-sm) var(--jv-spacing-md);font-weight:600;font-size:.875rem;color:var(--jv-color-foreground-muted);text-align:start;white-space:nowrap;border-bottom:1px solid var(--jv-color-border);-webkit-user-select:none;user-select:none;position:relative}.jv-grid-th-sortable{cursor:pointer}.jv-grid-th-sortable:hover{background:var(--jv-color-surface)}.jv-grid-th-reorderable{cursor:grab}.jv-grid-th-reorderable:active{cursor:grabbing}.jv-grid-th-sticky-left{position:sticky;left:0;z-index:2;background:var(--jv-color-surface-muted);border-right:1px solid var(--jv-color-border)}.jv-grid-th-sticky-right{position:sticky;right:0;z-index:2;background:var(--jv-color-surface-muted);border-left:1px solid var(--jv-color-border)}.jv-grid-th-content{display:flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-grid-sort-icon{font-size:.75rem;line-height:1}.jv-grid-th-select,.jv-grid-td-select{width:3rem;text-align:center}.jv-grid-th-actions,.jv-grid-td-actions{width:1%;white-space:nowrap}.jv-grid-td{padding:var(--jv-spacing-sm) var(--jv-spacing-md);color:var(--jv-color-foreground);font-size:var(--jv-density-font-size);border-bottom:1px solid var(--jv-color-border)}.jv-grid-td-sticky-left{position:sticky;left:0;z-index:1;background:var(--jv-color-surface);border-right:1px solid var(--jv-color-border)}.jv-grid-td-sticky-right{position:sticky;right:0;z-index:1;background:var(--jv-color-surface);border-left:1px solid var(--jv-color-border)}.jv-grid-t:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-grid-tr{transition:background-color .12s ease}.jv-grid-tr:hover{background:var(--jv-color-surface-muted)}.jv-grid-tr:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-grid-tr-editing{background:var(--jv-color-surface-highlight, rgba(59, 130, 246, .05))}.jv-grid-tr-selected{background:var(--jv-color-primary-light, rgba(59, 130, 246, .08))}.jv-grid-checkbox{width:1rem;height:1rem;accent-color:var(--jv-color-primary);cursor:pointer}.jv-grid-boolean{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border-radius:999px;font-size:.75rem;font-weight:700}.jv-grid-boolean-true{background:var(--jv-color-success);color:#fff}.jv-grid-boolean-false{background:var(--jv-color-danger);color:#fff}.jv-grid-empty{padding:var(--jv-spacing-xl) var(--jv-spacing-md);text-align:center;color:var(--jv-color-foreground-muted);font-style:italic}.jv-grid-actions-group{display:flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-grid-loading{display:flex;align-items:center;justify-content:center;gap:var(--jv-spacing-md);padding:var(--jv-spacing-xl);color:var(--jv-color-foreground-muted)}.jv-grid-spinner{width:1.25rem;height:1.25rem;border:2px solid var(--jv-color-border);border-right-color:var(--jv-color-primary);border-radius:999px;animation:jv-grid-spin .8s linear infinite}@keyframes jv-grid-spin{to{transform:rotate(360deg)}}.jv-grid-pagination{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);flex-wrap:wrap}.jv-grid-pagination-info{font-size:.875rem;color:var(--jv-color-foreground-muted)}.jv-grid-pagination-controls{display:flex;align-items:center;gap:var(--jv-spacing-xs);flex-wrap:wrap}@media(max-width:640px){.jv-grid-pagination{flex-direction:column;align-items:stretch;gap:var(--jv-spacing-sm)}.jv-grid-pagination-info{text-align:center}.jv-grid-pagination-controls{justify-content:center}.jv-grid-toolbar{flex-direction:column;align-items:stretch}.jv-grid-search{width:100%}.jv-grid-export-actions{justify-content:stretch}.jv-grid-export-actions jv-button{flex:1}}.jv-grid-resize-handle{position:absolute;top:0;right:0;width:4px;height:100%;cursor:col-resize;background:transparent;z-index:3}.jv-grid-resize-handle:hover,.jv-grid-resize-handle:active{background:var(--jv-color-primary)}.jv-grid-filter-row .jv-grid-th{padding:var(--jv-spacing-xs) var(--jv-spacing-sm)}.jv-grid-filter-input{width:100%;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-sm);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-sm);background:var(--jv-color-surface);color:var(--jv-color-foreground);font-size:.8rem;box-sizing:border-box}.jv-grid-td-editable{cursor:pointer}.jv-grid-td-editable:hover{box-shadow:inset 0 0 0 1px var(--jv-color-primary)}.jv-grid-edit-input{width:100%;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-sm);border:1px solid var(--jv-color-primary);border-radius:var(--jv-radius-sm);background:var(--jv-color-surface);color:var(--jv-color-foreground);font-size:var(--jv-density-font-size);box-sizing:border-box}.jv-grid-edit-input:focus{outline:2px solid var(--jv-color-primary);outline-offset:-1px}\n"] }]
|
|
21422
|
+
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], trackBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackBy", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIds", required: false }] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], rowDoubleClick: [{ type: i0.Output, args: ["rowDoubleClick"] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], searchChange: [{ type: i0.Output, args: ["searchChange"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], columnFilter: [{ type: i0.Output, args: ["columnFilter"] }], columnResize: [{ type: i0.Output, args: ["columnResize"] }], columnReorder: [{ type: i0.Output, args: ["columnReorder"] }], rowEdit: [{ type: i0.Output, args: ["rowEdit"] }] } });
|
|
20865
21423
|
|
|
20866
21424
|
class JvPaginationComponent {
|
|
20867
21425
|
translationService = inject(JvTranslationService);
|
|
@@ -20900,130 +21458,130 @@ class JvPaginationComponent {
|
|
|
20900
21458
|
this.pageChange.emit({ pageIndex: 0, pageSize: Number(value) });
|
|
20901
21459
|
}
|
|
20902
21460
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20903
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvPaginationComponent, isStandalone: true, selector: "jv-pagination", inputs: { totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, pageIndex: { classPropertyName: "pageIndex", publicName: "pageIndex", isSignal: true, isRequired: false, transformFunction: null }, maxVisiblePages: { classPropertyName: "maxVisiblePages", publicName: "maxVisiblePages", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange" }, ngImport: i0, template: `
|
|
20904
|
-
<nav class="jv-pagination" role="navigation" [attr.aria-label]="t('pagination.pageLabel', { page: pageIndex() + 1 })">
|
|
20905
|
-
<div class="jv-pagination-info">
|
|
20906
|
-
<span>{{ t('pagination.itemsShowing', { start: pageStart(), end: pageEnd(), total: totalItems() }) }}</span>
|
|
20907
|
-
</div>
|
|
20908
|
-
|
|
20909
|
-
<div class="jv-pagination-controls">
|
|
20910
|
-
<div class="jv-pagination-size">
|
|
20911
|
-
<label class="jv-pagination-size-label">{{ t('pagination.itemsPerPage') }}</label>
|
|
20912
|
-
<jv-select
|
|
20913
|
-
[options]="pageSizeOptionsList()"
|
|
20914
|
-
[modelValue]="pageSizeStr()"
|
|
20915
|
-
(selectionChange)="onPageSizeChange($event)"
|
|
20916
|
-
/>
|
|
20917
|
-
</div>
|
|
20918
|
-
|
|
20919
|
-
<div class="jv-pagination-buttons">
|
|
20920
|
-
<jv-button
|
|
20921
|
-
variant="outline"
|
|
20922
|
-
icon="chevrons-left"
|
|
20923
|
-
[disabled]="pageIndex() === 0"
|
|
20924
|
-
(click)="goToPage(0)"
|
|
20925
|
-
[attr.aria-label]="t('pagination.firstPage')"
|
|
20926
|
-
/>
|
|
20927
|
-
|
|
20928
|
-
<jv-button
|
|
20929
|
-
variant="outline"
|
|
20930
|
-
icon="chevron-left"
|
|
20931
|
-
[disabled]="pageIndex() === 0"
|
|
20932
|
-
(click)="goToPage(pageIndex() - 1)"
|
|
20933
|
-
[attr.aria-label]="t('pagination.prevPage')"
|
|
20934
|
-
/>
|
|
20935
|
-
|
|
20936
|
-
@for (p of pageRange(); track p) {
|
|
20937
|
-
<jv-button
|
|
20938
|
-
[variant]="p === pageIndex() ? 'primary' : 'outline'"
|
|
20939
|
-
[attr.aria-current]="p === pageIndex() ? 'page' : null"
|
|
20940
|
-
[attr.aria-label]="t('pagination.pageLabel', { page: p + 1 })"
|
|
20941
|
-
(click)="goToPage(p)"
|
|
20942
|
-
>{{ p + 1 }}</jv-button>
|
|
20943
|
-
}
|
|
20944
|
-
|
|
20945
|
-
<jv-button
|
|
20946
|
-
variant="outline"
|
|
20947
|
-
icon="chevron-right"
|
|
20948
|
-
[disabled]="pageIndex() >= totalPages() - 1"
|
|
20949
|
-
(click)="goToPage(pageIndex() + 1)"
|
|
20950
|
-
[attr.aria-label]="t('pagination.nextPage')"
|
|
20951
|
-
/>
|
|
20952
|
-
|
|
20953
|
-
<jv-button
|
|
20954
|
-
variant="outline"
|
|
20955
|
-
icon="chevrons-right"
|
|
20956
|
-
[disabled]="pageIndex() >= totalPages() - 1"
|
|
20957
|
-
(click)="goToPage(totalPages() - 1)"
|
|
20958
|
-
[attr.aria-label]="t('pagination.lastPage')"
|
|
20959
|
-
/>
|
|
20960
|
-
</div>
|
|
20961
|
-
</div>
|
|
20962
|
-
</nav>
|
|
21461
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvPaginationComponent, isStandalone: true, selector: "jv-pagination", inputs: { totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, pageIndex: { classPropertyName: "pageIndex", publicName: "pageIndex", isSignal: true, isRequired: false, transformFunction: null }, maxVisiblePages: { classPropertyName: "maxVisiblePages", publicName: "maxVisiblePages", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange" }, ngImport: i0, template: `
|
|
21462
|
+
<nav class="jv-pagination" role="navigation" [attr.aria-label]="t('pagination.pageLabel', { page: pageIndex() + 1 })">
|
|
21463
|
+
<div class="jv-pagination-info">
|
|
21464
|
+
<span>{{ t('pagination.itemsShowing', { start: pageStart(), end: pageEnd(), total: totalItems() }) }}</span>
|
|
21465
|
+
</div>
|
|
21466
|
+
|
|
21467
|
+
<div class="jv-pagination-controls">
|
|
21468
|
+
<div class="jv-pagination-size">
|
|
21469
|
+
<label class="jv-pagination-size-label">{{ t('pagination.itemsPerPage') }}</label>
|
|
21470
|
+
<jv-select
|
|
21471
|
+
[options]="pageSizeOptionsList()"
|
|
21472
|
+
[modelValue]="pageSizeStr()"
|
|
21473
|
+
(selectionChange)="onPageSizeChange($event)"
|
|
21474
|
+
/>
|
|
21475
|
+
</div>
|
|
21476
|
+
|
|
21477
|
+
<div class="jv-pagination-buttons">
|
|
21478
|
+
<jv-button
|
|
21479
|
+
variant="outline"
|
|
21480
|
+
icon="chevrons-left"
|
|
21481
|
+
[disabled]="pageIndex() === 0"
|
|
21482
|
+
(click)="goToPage(0)"
|
|
21483
|
+
[attr.aria-label]="t('pagination.firstPage')"
|
|
21484
|
+
/>
|
|
21485
|
+
|
|
21486
|
+
<jv-button
|
|
21487
|
+
variant="outline"
|
|
21488
|
+
icon="chevron-left"
|
|
21489
|
+
[disabled]="pageIndex() === 0"
|
|
21490
|
+
(click)="goToPage(pageIndex() - 1)"
|
|
21491
|
+
[attr.aria-label]="t('pagination.prevPage')"
|
|
21492
|
+
/>
|
|
21493
|
+
|
|
21494
|
+
@for (p of pageRange(); track p) {
|
|
21495
|
+
<jv-button
|
|
21496
|
+
[variant]="p === pageIndex() ? 'primary' : 'outline'"
|
|
21497
|
+
[attr.aria-current]="p === pageIndex() ? 'page' : null"
|
|
21498
|
+
[attr.aria-label]="t('pagination.pageLabel', { page: p + 1 })"
|
|
21499
|
+
(click)="goToPage(p)"
|
|
21500
|
+
>{{ p + 1 }}</jv-button>
|
|
21501
|
+
}
|
|
21502
|
+
|
|
21503
|
+
<jv-button
|
|
21504
|
+
variant="outline"
|
|
21505
|
+
icon="chevron-right"
|
|
21506
|
+
[disabled]="pageIndex() >= totalPages() - 1"
|
|
21507
|
+
(click)="goToPage(pageIndex() + 1)"
|
|
21508
|
+
[attr.aria-label]="t('pagination.nextPage')"
|
|
21509
|
+
/>
|
|
21510
|
+
|
|
21511
|
+
<jv-button
|
|
21512
|
+
variant="outline"
|
|
21513
|
+
icon="chevrons-right"
|
|
21514
|
+
[disabled]="pageIndex() >= totalPages() - 1"
|
|
21515
|
+
(click)="goToPage(totalPages() - 1)"
|
|
21516
|
+
[attr.aria-label]="t('pagination.lastPage')"
|
|
21517
|
+
/>
|
|
21518
|
+
</div>
|
|
21519
|
+
</div>
|
|
21520
|
+
</nav>
|
|
20963
21521
|
`, isInline: true, styles: [".jv-pagination{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);flex-wrap:wrap}.jv-pagination-info{font-size:.875rem;color:var(--jv-color-foreground-muted)}.jv-pagination-controls{display:flex;align-items:center;gap:var(--jv-spacing-md);flex-wrap:wrap}.jv-pagination-size{display:flex;align-items:center;gap:var(--jv-spacing-sm)}.jv-pagination-size-label{font-size:.875rem;color:var(--jv-color-foreground-muted);white-space:nowrap}.jv-pagination-size jv-select{width:auto;min-width:4.5rem}.jv-pagination-buttons{display:flex;align-items:center;gap:var(--jv-spacing-xs)}\n"], dependencies: [{ kind: "component", type: JvButtonComponent, selector: "jv-button", inputs: ["type", "variant", "icon", "iconPosition", "loading", "disabled"] }, { kind: "component", type: JvSelectComponent, selector: "jv-select", inputs: ["options", "placeholder", "required", "invalid", "describedBy", "inputId", "modelValue"], outputs: ["selectionChange"] }] });
|
|
20964
21522
|
}
|
|
20965
21523
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvPaginationComponent, decorators: [{
|
|
20966
21524
|
type: Component,
|
|
20967
|
-
args: [{ selector: 'jv-pagination', standalone: true, imports: [JvButtonComponent, JvSelectComponent], template: `
|
|
20968
|
-
<nav class="jv-pagination" role="navigation" [attr.aria-label]="t('pagination.pageLabel', { page: pageIndex() + 1 })">
|
|
20969
|
-
<div class="jv-pagination-info">
|
|
20970
|
-
<span>{{ t('pagination.itemsShowing', { start: pageStart(), end: pageEnd(), total: totalItems() }) }}</span>
|
|
20971
|
-
</div>
|
|
20972
|
-
|
|
20973
|
-
<div class="jv-pagination-controls">
|
|
20974
|
-
<div class="jv-pagination-size">
|
|
20975
|
-
<label class="jv-pagination-size-label">{{ t('pagination.itemsPerPage') }}</label>
|
|
20976
|
-
<jv-select
|
|
20977
|
-
[options]="pageSizeOptionsList()"
|
|
20978
|
-
[modelValue]="pageSizeStr()"
|
|
20979
|
-
(selectionChange)="onPageSizeChange($event)"
|
|
20980
|
-
/>
|
|
20981
|
-
</div>
|
|
20982
|
-
|
|
20983
|
-
<div class="jv-pagination-buttons">
|
|
20984
|
-
<jv-button
|
|
20985
|
-
variant="outline"
|
|
20986
|
-
icon="chevrons-left"
|
|
20987
|
-
[disabled]="pageIndex() === 0"
|
|
20988
|
-
(click)="goToPage(0)"
|
|
20989
|
-
[attr.aria-label]="t('pagination.firstPage')"
|
|
20990
|
-
/>
|
|
20991
|
-
|
|
20992
|
-
<jv-button
|
|
20993
|
-
variant="outline"
|
|
20994
|
-
icon="chevron-left"
|
|
20995
|
-
[disabled]="pageIndex() === 0"
|
|
20996
|
-
(click)="goToPage(pageIndex() - 1)"
|
|
20997
|
-
[attr.aria-label]="t('pagination.prevPage')"
|
|
20998
|
-
/>
|
|
20999
|
-
|
|
21000
|
-
@for (p of pageRange(); track p) {
|
|
21001
|
-
<jv-button
|
|
21002
|
-
[variant]="p === pageIndex() ? 'primary' : 'outline'"
|
|
21003
|
-
[attr.aria-current]="p === pageIndex() ? 'page' : null"
|
|
21004
|
-
[attr.aria-label]="t('pagination.pageLabel', { page: p + 1 })"
|
|
21005
|
-
(click)="goToPage(p)"
|
|
21006
|
-
>{{ p + 1 }}</jv-button>
|
|
21007
|
-
}
|
|
21008
|
-
|
|
21009
|
-
<jv-button
|
|
21010
|
-
variant="outline"
|
|
21011
|
-
icon="chevron-right"
|
|
21012
|
-
[disabled]="pageIndex() >= totalPages() - 1"
|
|
21013
|
-
(click)="goToPage(pageIndex() + 1)"
|
|
21014
|
-
[attr.aria-label]="t('pagination.nextPage')"
|
|
21015
|
-
/>
|
|
21016
|
-
|
|
21017
|
-
<jv-button
|
|
21018
|
-
variant="outline"
|
|
21019
|
-
icon="chevrons-right"
|
|
21020
|
-
[disabled]="pageIndex() >= totalPages() - 1"
|
|
21021
|
-
(click)="goToPage(totalPages() - 1)"
|
|
21022
|
-
[attr.aria-label]="t('pagination.lastPage')"
|
|
21023
|
-
/>
|
|
21024
|
-
</div>
|
|
21025
|
-
</div>
|
|
21026
|
-
</nav>
|
|
21525
|
+
args: [{ selector: 'jv-pagination', standalone: true, imports: [JvButtonComponent, JvSelectComponent], template: `
|
|
21526
|
+
<nav class="jv-pagination" role="navigation" [attr.aria-label]="t('pagination.pageLabel', { page: pageIndex() + 1 })">
|
|
21527
|
+
<div class="jv-pagination-info">
|
|
21528
|
+
<span>{{ t('pagination.itemsShowing', { start: pageStart(), end: pageEnd(), total: totalItems() }) }}</span>
|
|
21529
|
+
</div>
|
|
21530
|
+
|
|
21531
|
+
<div class="jv-pagination-controls">
|
|
21532
|
+
<div class="jv-pagination-size">
|
|
21533
|
+
<label class="jv-pagination-size-label">{{ t('pagination.itemsPerPage') }}</label>
|
|
21534
|
+
<jv-select
|
|
21535
|
+
[options]="pageSizeOptionsList()"
|
|
21536
|
+
[modelValue]="pageSizeStr()"
|
|
21537
|
+
(selectionChange)="onPageSizeChange($event)"
|
|
21538
|
+
/>
|
|
21539
|
+
</div>
|
|
21540
|
+
|
|
21541
|
+
<div class="jv-pagination-buttons">
|
|
21542
|
+
<jv-button
|
|
21543
|
+
variant="outline"
|
|
21544
|
+
icon="chevrons-left"
|
|
21545
|
+
[disabled]="pageIndex() === 0"
|
|
21546
|
+
(click)="goToPage(0)"
|
|
21547
|
+
[attr.aria-label]="t('pagination.firstPage')"
|
|
21548
|
+
/>
|
|
21549
|
+
|
|
21550
|
+
<jv-button
|
|
21551
|
+
variant="outline"
|
|
21552
|
+
icon="chevron-left"
|
|
21553
|
+
[disabled]="pageIndex() === 0"
|
|
21554
|
+
(click)="goToPage(pageIndex() - 1)"
|
|
21555
|
+
[attr.aria-label]="t('pagination.prevPage')"
|
|
21556
|
+
/>
|
|
21557
|
+
|
|
21558
|
+
@for (p of pageRange(); track p) {
|
|
21559
|
+
<jv-button
|
|
21560
|
+
[variant]="p === pageIndex() ? 'primary' : 'outline'"
|
|
21561
|
+
[attr.aria-current]="p === pageIndex() ? 'page' : null"
|
|
21562
|
+
[attr.aria-label]="t('pagination.pageLabel', { page: p + 1 })"
|
|
21563
|
+
(click)="goToPage(p)"
|
|
21564
|
+
>{{ p + 1 }}</jv-button>
|
|
21565
|
+
}
|
|
21566
|
+
|
|
21567
|
+
<jv-button
|
|
21568
|
+
variant="outline"
|
|
21569
|
+
icon="chevron-right"
|
|
21570
|
+
[disabled]="pageIndex() >= totalPages() - 1"
|
|
21571
|
+
(click)="goToPage(pageIndex() + 1)"
|
|
21572
|
+
[attr.aria-label]="t('pagination.nextPage')"
|
|
21573
|
+
/>
|
|
21574
|
+
|
|
21575
|
+
<jv-button
|
|
21576
|
+
variant="outline"
|
|
21577
|
+
icon="chevrons-right"
|
|
21578
|
+
[disabled]="pageIndex() >= totalPages() - 1"
|
|
21579
|
+
(click)="goToPage(totalPages() - 1)"
|
|
21580
|
+
[attr.aria-label]="t('pagination.lastPage')"
|
|
21581
|
+
/>
|
|
21582
|
+
</div>
|
|
21583
|
+
</div>
|
|
21584
|
+
</nav>
|
|
21027
21585
|
`, styles: [".jv-pagination{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);flex-wrap:wrap}.jv-pagination-info{font-size:.875rem;color:var(--jv-color-foreground-muted)}.jv-pagination-controls{display:flex;align-items:center;gap:var(--jv-spacing-md);flex-wrap:wrap}.jv-pagination-size{display:flex;align-items:center;gap:var(--jv-spacing-sm)}.jv-pagination-size-label{font-size:.875rem;color:var(--jv-color-foreground-muted);white-space:nowrap}.jv-pagination-size jv-select{width:auto;min-width:4.5rem}.jv-pagination-buttons{display:flex;align-items:center;gap:var(--jv-spacing-xs)}\n"] }]
|
|
21028
21586
|
}], propDecorators: { totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: true }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], pageIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageIndex", required: false }] }], maxVisiblePages: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxVisiblePages", required: false }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }] } });
|
|
21029
21587
|
|