fix: display CodeLookup values instead of IDs in datatable view (#2896)
Added empty check: parts[1] && parts[1].trim() to ensure the part after _cd_ exists and is not empty (line)
This commit is contained in:
@@ -35,6 +35,7 @@ export class Datatables {
|
||||
|
||||
public getFormfields(columns: any, dateTransformColumns: string[], dataTableEntryObject: any) {
|
||||
return columns.map((column: any) => {
|
||||
const displayLabel = this.toDisplayLabel(column.columnName);
|
||||
switch (column.columnDisplayType) {
|
||||
case 'INTEGER':
|
||||
case 'STRING':
|
||||
@@ -42,7 +43,7 @@ export class Datatables {
|
||||
case 'TEXT':
|
||||
return new InputBase({
|
||||
controlName: column.columnName,
|
||||
label: column.columnName,
|
||||
label: displayLabel,
|
||||
value: '',
|
||||
type: column.columnDisplayType === 'INTEGER' || column.columnDisplayType === 'DECIMAL' ? 'number' : 'text',
|
||||
required: column.isColumnNullable ? false : true
|
||||
@@ -50,7 +51,7 @@ export class Datatables {
|
||||
case 'BOOLEAN':
|
||||
return new CheckboxBase({
|
||||
controlName: column.columnName,
|
||||
label: column.columnName,
|
||||
label: displayLabel,
|
||||
value: '',
|
||||
type: 'checkbox',
|
||||
required: column.isColumnNullable ? false : true
|
||||
@@ -58,7 +59,7 @@ export class Datatables {
|
||||
case 'CODELOOKUP':
|
||||
return new SelectBase({
|
||||
controlName: column.columnName,
|
||||
label: column.columnName,
|
||||
label: displayLabel,
|
||||
value: '',
|
||||
options: { label: 'value', value: 'id', data: column.columnValues },
|
||||
required: column.isColumnNullable ? false : true
|
||||
@@ -70,7 +71,7 @@ export class Datatables {
|
||||
}
|
||||
return new DatepickerBase({
|
||||
controlName: column.columnName,
|
||||
label: column.columnName,
|
||||
label: displayLabel,
|
||||
value: '',
|
||||
maxDate: this.settingsService.maxAllowedDate,
|
||||
required: column.isColumnNullable ? false : true
|
||||
@@ -81,7 +82,7 @@ export class Datatables {
|
||||
dataTableEntryObject.dateFormat = Dates.DEFAULT_DATETIMEFORMAT;
|
||||
return new DateTimepickerBase({
|
||||
controlName: column.columnName,
|
||||
label: column.columnName,
|
||||
label: displayLabel,
|
||||
value: '',
|
||||
maxDate: this.settingsService.maxAllowedDate,
|
||||
required: column.isColumnNullable ? false : true
|
||||
@@ -174,6 +175,56 @@ export class Datatables {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
public toDisplayLabel(columnName: string): string {
|
||||
if (!columnName) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Handle CODELOOKUP pattern: extract the part after _cd_
|
||||
if (columnName.includes('_cd_')) {
|
||||
const parts = columnName.split('_cd_');
|
||||
// Ensure parts[1] exists and is not empty before processing
|
||||
if (parts.length > 1 && parts[1] && parts[1].trim()) {
|
||||
// Return the part after _cd_ converted to Title Case
|
||||
// Filter out standalone "cd" or "CD" words that are artifacts from naming convention
|
||||
// This only affects display, not database column names
|
||||
const displayWords = parts[1]
|
||||
.split('_')
|
||||
.filter((word) => word.trim() && word.toLowerCase() !== 'cd') // Remove empty strings and standalone "cd" artifacts
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
||||
.join(' ');
|
||||
|
||||
// Return empty string if all words were filtered out, otherwise return formatted label
|
||||
return displayWords || parts[1].trim();
|
||||
}
|
||||
}
|
||||
|
||||
// Convert snake_case to Title Case (e.g., "created_at" -> "Created At")
|
||||
// For non-CODELOOKUP fields, only filter standalone "cd" if it appears as an artifact
|
||||
return (
|
||||
columnName
|
||||
.split('_')
|
||||
.filter((word) => word.trim() && word.toLowerCase() !== 'cd') // Remove empty strings and standalone "cd" artifacts
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
||||
.join(' ') || columnName
|
||||
); // Fallback to original if all filtered out
|
||||
}
|
||||
|
||||
public getCodeLookupValue(columnHeader: any, id: number): string {
|
||||
if (!columnHeader?.columnValues || id === null || id === undefined) {
|
||||
return '';
|
||||
}
|
||||
const codeValue = columnHeader.columnValues.find((cv: any) => cv.id === id);
|
||||
return codeValue ? codeValue.value : id.toString();
|
||||
}
|
||||
|
||||
public getCodeName(columnName: string): string {
|
||||
if (columnName && columnName.includes('_cd_')) {
|
||||
return columnName.split('_cd_')[0];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public isValidUrl(urlString: string): boolean {
|
||||
try {
|
||||
const url = new URL(urlString);
|
||||
|
||||
+5
@@ -235,6 +235,11 @@ export class DatatableMultiRowComponent implements OnInit, OnDestroy, OnChanges
|
||||
if (typeof value === 'number') {
|
||||
value = this.numberFormat.transform(value);
|
||||
}
|
||||
} else if (columnDisplayType === 'CODELOOKUP') {
|
||||
if (columnHeader.columnValues && value !== null && value !== undefined) {
|
||||
const codeValue = columnHeader.columnValues.find((cv: any) => cv.id === value);
|
||||
value = codeValue ? codeValue.value : value;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
+6
-2
@@ -25,8 +25,7 @@
|
||||
@for (columnHeader of dataObject.columnHeaders; track columnHeader; let i = $index) {
|
||||
<div class="flex-fill" [ngClass]="setAttributeClass(columnHeader.columnName)">
|
||||
<div class="mat-body-strong left flex-40">
|
||||
{{ columnHeader.columnDisplayName }}
|
||||
{{ getInputName(columnHeader.columnName) }}
|
||||
{{ datatables.toDisplayLabel(columnHeader.columnName) }}
|
||||
</div>
|
||||
<div class="right flex-60">
|
||||
@switch (getColumnType(columnHeader.columnDisplayType, columnHeader.columnType)) {
|
||||
@@ -50,6 +49,11 @@
|
||||
{{ dataObject.data[0].row[i] | formatNumber }}
|
||||
</span>
|
||||
}
|
||||
@case ('CODELOOKUP') {
|
||||
<span>
|
||||
{{ datatables.getCodeLookupValue(columnHeader, dataObject.data[0].row[i]) }}
|
||||
</span>
|
||||
}
|
||||
@case ('TEXT') {
|
||||
<span class="long-text">
|
||||
{{ dataObject.data[0].row[i] }}
|
||||
|
||||
-2
@@ -20,8 +20,6 @@
|
||||
|
||||
.system-defined {
|
||||
margin-top: 3px;
|
||||
color: $status-approved !important;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
.long-text {
|
||||
|
||||
+6
-2
@@ -43,7 +43,7 @@ export class DatatableSingleRowComponent implements OnInit {
|
||||
private dateUtils = inject(Dates);
|
||||
private dialog = inject(MatDialog);
|
||||
private settingsService = inject(SettingsService);
|
||||
private datatables = inject(Datatables);
|
||||
public datatables = inject(Datatables);
|
||||
private systemService = inject(SystemService);
|
||||
|
||||
@Input() dataObject: any;
|
||||
@@ -123,7 +123,8 @@ export class DatatableSingleRowComponent implements OnInit {
|
||||
const data = {
|
||||
title: 'Edit ' + this.datatableName + ' for ' + this.entityType,
|
||||
formfields: formfields,
|
||||
layout: { addButtonText: 'Save' }
|
||||
layout: { addButtonText: 'Submit' },
|
||||
pristine: false
|
||||
};
|
||||
const editDialogRef = this.dialog.open(FormDialogComponent, { data, width: '50rem' });
|
||||
editDialogRef.afterClosed().subscribe((response: any) => {
|
||||
@@ -182,6 +183,9 @@ export class DatatableSingleRowComponent implements OnInit {
|
||||
case 'DECIMAL': {
|
||||
return columnDisplayType;
|
||||
}
|
||||
case 'CODELOOKUP': {
|
||||
return columnDisplayType;
|
||||
}
|
||||
case 'TEXT': {
|
||||
if (columnType === 'JSON') {
|
||||
return 'JSON';
|
||||
|
||||
@@ -31,7 +31,12 @@
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header class="center">
|
||||
{{ 'labels.inputs.Field Name' | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let dataTableColumn">{{ dataTableColumn.columnName }}</td>
|
||||
<td mat-cell *matCellDef="let dataTableColumn">
|
||||
{{ getFieldDisplayName(dataTableColumn.columnName) }}
|
||||
@if (datatables.getCodeName(dataTableColumn.columnName)) {
|
||||
<span class="code-name">({{ datatables.getCodeName(dataTableColumn.columnName) }})</span>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="columnDisplayType">
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.code-name {
|
||||
opacity: 0.6;
|
||||
font-size: 0.9em;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@ import {
|
||||
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
||||
|
||||
/** Custom Services */
|
||||
import { SystemService } from '../../system.service';
|
||||
import { SystemService } from 'app/system/system.service';
|
||||
import { Datatables } from 'app/core/utils/datatables';
|
||||
|
||||
/** Custom Components */
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
@@ -60,6 +61,7 @@ export class ViewDataTableComponent implements OnInit {
|
||||
private router = inject(Router);
|
||||
private dialog = inject(MatDialog);
|
||||
private translateService = inject(TranslateService);
|
||||
public datatables = inject(Datatables);
|
||||
|
||||
/** Data Table Data */
|
||||
dataTableData: any;
|
||||
@@ -105,6 +107,13 @@ export class ViewDataTableComponent implements OnInit {
|
||||
this.setColumnsTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get display name for field (e.g., "Actividad" from "ADDRESS_TYPE_cd_ACTIVIDAD")
|
||||
*/
|
||||
getFieldDisplayName(columnName: string): string {
|
||||
return this.datatables.toDisplayLabel(columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the data source, paginator and sorter for columns table.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user