Skip to content

Commit adbcd47

Browse files
authored
adjustments and new functionality for TAG Related List (#2128)
1 parent e61aa48 commit adbcd47

File tree

4 files changed

+129
-28
lines changed

4 files changed

+129
-28
lines changed

force-app/components/relatedList/lwc/tagRelatedList/tagRelatedList.css

+25-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
display: flex;
33
align-items: center;
44
justify-content: space-between;
5-
padding: 0.25rem 0.5rem;
5+
padding: 0.25rem 1rem;
66
}
77

88
.chevronIcon {
@@ -36,3 +36,27 @@
3636
height: 2rem;
3737
padding: 0 0.5rem;
3838
}
39+
40+
/* Inactive row styling: light grey background and grey text */
41+
.inactiveRow {
42+
background-color: #f4f6f9 !important;
43+
color: #7e7e7e !important;
44+
}
45+
46+
/* Also force text inside inactive rows to appear grey */
47+
.inactiveRow .slds-truncate {
48+
color: #7e7e7e;
49+
}
50+
51+
.slds-table thead tr > th:first-child,
52+
.slds-table tbody tr > td:first-child {
53+
padding-left: 1rem !important;
54+
}
55+
56+
.slds-popover_medium .slds-popover__header {
57+
background-color: #f3f2f2; /* Slight grey for the header */
58+
border-bottom: 1px solid #dddbda;
59+
}
60+
.slds-popover_medium .slds-popover__body {
61+
padding: 1rem;
62+
}

force-app/components/relatedList/lwc/tagRelatedList/tagRelatedList.html

+25-7
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@ <h1 class="headerTitle slds-text-heading_small">{cardTitle}</h1>
4242
</thead>
4343
<tbody>
4444
<template for:each={displayedRecords} for:item="record" for:index="rowIndex">
45-
<!-- For clickable rows, added mouse event handlers for popover -->
4645
<template if:true={clickableRows}>
47-
<tr key={record.Id} data-record-id={record.Id} data-value={rowIndex} class="slds-hint-parent" onclick={handleRowClick} style="cursor: pointer"
46+
<tr key={record.Id} data-record-id={record.Id} data-value={rowIndex} class={record.rowClass} onclick={handleRowClick} style="cursor: pointer"
4847
onmouseenter={handleMouseEnter} onmouseleave={handleMouseLeave}>
4948
<template for:each={record.recordFields} for:item="field">
5049
<td key={field.label}>
@@ -53,9 +52,8 @@ <h1 class="headerTitle slds-text-heading_small">{cardTitle}</h1>
5352
</template>
5453
</tr>
5554
</template>
56-
<!-- For non-clickable rows, also added mouse event handlers for popover -->
5755
<template if:false={clickableRows}>
58-
<tr key={record.Id} data-record-id={record.Id} data-value={rowIndex} class="slds-hint-parent"
56+
<tr key={record.Id} data-record-id={record.Id} data-value={rowIndex} class={record.rowClass}
5957
onmouseenter={handleMouseEnter} onmouseleave={handleMouseLeave}>
6058
<template for:each={record.recordFields} for:item="field">
6159
<td key={field.label}>
@@ -70,12 +68,32 @@ <h1 class="headerTitle slds-text-heading_small">{cardTitle}</h1>
7068
</div>
7169
</template>
7270

73-
<!-- Popover Template for additional record details -->
7471
<template if:true={showPopover}>
75-
<div class="slds-popover slds-nubbin_top" style={popoverStyle} onmouseleave={handleMouseLeave}>
72+
<div
73+
class="slds-popover slds-nubbin_top slds-popover_medium"
74+
style={popoverStyle}
75+
role="dialog"
76+
onmouseenter={handlePopoverEnter}
77+
onmouseleave={handleMouseLeave}
78+
>
79+
<!-- Popover Header -->
80+
<div class="slds-popover__header">
81+
<div class="slds-media slds-media_center slds-has-flexi-truncate">
82+
<div class="slds-media__figure">
83+
<lightning-icon icon-name={icon} size="small"></lightning-icon>
84+
</div>
85+
<div class="slds-media__body">
86+
<h2 id="popover-heading" class="slds-text-heading_small slds-hyphenate">
87+
{popoverTitle}
88+
</h2>
89+
</div>
90+
</div>
91+
</div>
92+
93+
<!-- Popover Body -->
7694
<div class="slds-popover__body">
7795
<template for:each={popoverFieldValues} for:item="fieldObj">
78-
<p key={fieldObj.apiName}>
96+
<p key={fieldObj.apiName} class="slds-truncate">
7997
<strong>{fieldObj.apiName}:</strong> {fieldObj.value}
8098
</p>
8199
</template>

force-app/components/relatedList/lwc/tagRelatedList/tagRelatedList.js

+71-20
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import { getRecord } from 'lightning/uiRecordApi';
55
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
66

77
export default class TagRelatedList extends NavigationMixin(LightningElement) {
8+
9+
hoverTimer;
10+
hideTimer;
11+
812
@api recordId;
913
@api objectApiName;
1014
@api listTitle; // Title of the list.
@@ -24,14 +28,13 @@ export default class TagRelatedList extends NavigationMixin(LightningElement) {
2428
@api popoverFields; //Popover additional fields (comma separated)
2529
@api showNewRecordButton;
2630
@api newRecordButtonLabel; // Button label for New Record button
27-
31+
@api inactiveRecordFilter; // Example: "Active__c = false"
2832

2933
@track relatedRecords;
3034
@track isExpanded = false; // Accordion state
3135

3236
@track popoverRecordData; // Holds the record data for the hovered row
3337
@track showPopover = false; // Flag to conditionally display popover
34-
hoverTimer; // Timer for delayed popover display
3538
@track popoverPosition = { top: 0, left: 0 };
3639

3740
connectedCallback() {
@@ -48,7 +51,6 @@ export default class TagRelatedList extends NavigationMixin(LightningElement) {
4851
if (data && this.dynamicUpdate === true) {
4952
this.getList();
5053
} else if (error) {
51-
// Handle error accordingly
5254
}
5355
}
5456

@@ -126,6 +128,15 @@ export default class TagRelatedList extends NavigationMixin(LightningElement) {
126128
get listRecords() {
127129
let returnRecords = [];
128130
if (this.relatedRecords) {
131+
// Parse the inactive filter if provided
132+
let filterField = null;
133+
let filterValue = null;
134+
if (this.inactiveRecordFilter && this.inactiveRecordFilter.includes('=')) {
135+
let parts = this.inactiveRecordFilter.split('=');
136+
filterField = parts[0].trim();
137+
filterValue = parts[1].trim().toLowerCase();
138+
}
139+
129140
this.relatedRecords.forEach((dataRecord) => {
130141
let recordFields = [];
131142
this.displayedFieldList.forEach((key) => {
@@ -136,11 +147,34 @@ export default class TagRelatedList extends NavigationMixin(LightningElement) {
136147
});
137148
}
138149
});
139-
returnRecords.push({ recordFields: recordFields, Id: dataRecord.Id });
150+
151+
// Determine if the record is inactive
152+
let isInactive = false;
153+
if (filterField && filterValue !== null) {
154+
let fieldVal = this.resolve(filterField, dataRecord);
155+
// Convert the field value to string (if boolean, true/false will be 'true'/'false')
156+
if (fieldVal !== null && String(fieldVal).toLowerCase() === filterValue) {
157+
isInactive = true;
158+
}
159+
}
160+
161+
// Set rowClass based on whether the record is inactive.
162+
let rowClass = 'slds-hint-parent';
163+
if (isInactive) {
164+
rowClass += ' inactiveRow';
165+
}
166+
167+
returnRecords.push({
168+
recordFields: recordFields,
169+
Id: dataRecord.Id,
170+
isInactive: isInactive,
171+
rowClass: rowClass
172+
});
140173
});
141174
}
142175
return returnRecords;
143176
}
177+
144178

145179
// Build the card title with record count
146180
get cardTitle() {
@@ -170,11 +204,10 @@ export default class TagRelatedList extends NavigationMixin(LightningElement) {
170204
return labels.map((label, index, arr) => {
171205
// Base style for every header cell.
172206
let style = 'vertical-align: middle; text-align: left; padding: 4px 8px;';
173-
// Remove extra left padding for the first cell.
207+
// Padding for the first cell.
174208
if (index === 0) {
175-
style += 'padding-left: 5px;';
209+
style += 'padding-left: 1rem;';
176210
}
177-
// Remove extra right padding for the last cell.
178211
if (index === arr.length - 1) {
179212
style += 'padding-right: 0px;';
180213
}
@@ -185,14 +218,19 @@ export default class TagRelatedList extends NavigationMixin(LightningElement) {
185218
});
186219
}
187220

188-
// Parse and combine the displayed fields and popoverFields strings into an array
189221
get apexFieldList() {
190-
// Get displayedFields (if any)
222+
// Get fields from displayedFields and popoverFields
191223
let displayed = this.displayedFields ? this.displayedFields.replace(/\s/g, '').split(',') : [];
192-
// Get popoverFields (if any)
193224
let popover = this.popoverFields ? this.popoverFields.replace(/\s/g, '').split(',') : [];
194-
// Combine them and remove duplicates
195225
let combined = Array.from(new Set([...displayed, ...popover]));
226+
227+
// extract the field name and add it to the list if not already present.
228+
if (this.inactiveRecordFilter && this.inactiveRecordFilter.includes('=')) {
229+
let filterField = this.inactiveRecordFilter.split('=')[0].trim();
230+
if (!combined.includes(filterField)) {
231+
combined.push(filterField);
232+
}
233+
}
196234
return combined;
197235
}
198236

@@ -218,25 +256,29 @@ export default class TagRelatedList extends NavigationMixin(LightningElement) {
218256
}, obj || {});
219257
}
220258

221-
// Event handler for mouse enter on a record row
222259
handleMouseEnter(event) {
223260
const recordId = event.currentTarget.dataset.recordId;
224261
const rect = event.currentTarget.getBoundingClientRect();
225-
// Adjusting the position slightly (you can fine‑tune the offsets)
226262
this.popoverPosition = {
227-
top: rect.top + 10,
228-
left: rect.left + 10
263+
top: rect.top + 2,
264+
left: rect.left + 2
229265
};
230266
this.hoverTimer = window.setTimeout(() => {
231267
this.popoverRecordData = this.relatedRecords.find(rec => rec.Id === recordId);
232268
this.showPopover = true;
233-
}, 1500);
269+
}, 1000);
234270
}
235271

236-
// Event handler for mouse leave from a record row (or popover)
237272
handleMouseLeave() {
238273
window.clearTimeout(this.hoverTimer);
239-
this.showPopover = false;
274+
this.hideTimer = window.setTimeout(() => {
275+
this.showPopover = false;
276+
}, 200); // Delay closing popover to allow mouse movement
277+
}
278+
279+
handlePopoverEnter() {
280+
// Prevent hiding when entering the popover
281+
window.clearTimeout(this.hideTimer);
240282
}
241283

242284
// Getter to combine displayedFields with additional popoverFields
@@ -246,7 +288,6 @@ export default class TagRelatedList extends NavigationMixin(LightningElement) {
246288

247289
// Getter to prepare an array of objects with localized field labels and values from the hovered record
248290
get popoverFieldValues() {
249-
// Ensure we have the record data and the object metadata
250291
if (!this.popoverRecordData || !this.objectInfo.data) {
251292
return [];
252293
}
@@ -275,7 +316,17 @@ export default class TagRelatedList extends NavigationMixin(LightningElement) {
275316
top: ${relativeTop + 20}px;
276317
left: ${relativeLeft}px;
277318
z-index: 1000;
278-
transform: translate(-50%, 0);`;
319+
transform: translate(0, 0);`;
320+
}
321+
return '';
322+
}
323+
324+
get popoverTitle() {
325+
if (this.popoverRecordData && this.displayedFieldList && this.displayedFieldList.length > 0 && this.objectInfo.data) {
326+
// Get the first field's API name from the displayedFields array
327+
let firstFieldApiName = this.displayedFieldList[0];
328+
let fieldValue = this.resolve(firstFieldApiName, this.popoverRecordData);
329+
return `${fieldValue}`;
279330
}
280331
return '';
281332
}

force-app/components/relatedList/lwc/tagRelatedList/tagRelatedList.js-meta.xml

+8
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@
106106
type="String"
107107
default=""
108108
/>
109+
<property
110+
name="inactiveRecordFilter"
111+
label="Inactive Record Filter"
112+
description="Enter a SOQL condition (e.g., Active__c = false). Records meeting this condition will be styled as inactive."
113+
type="String"
114+
default=""
115+
/>
116+
109117
</targetConfig>
110118
</targetConfigs>
111119
</LightningComponentBundle>

0 commit comments

Comments
 (0)