+
+
@@ -67,56 +59,24 @@
{timelineTitle}
-
+
@@ -124,14 +84,8 @@
@@ -203,18 +175,11 @@
-
+
\ No newline at end of file
diff --git a/force-app/main/default/lwc/timeline/timeline.js b/force-app/main/default/lwc/timeline/timeline.js
index d2c71e3..918b6d1 100755
--- a/force-app/main/default/lwc/timeline/timeline.js
+++ b/force-app/main/default/lwc/timeline/timeline.js
@@ -26,6 +26,7 @@ import SHOWING from '@salesforce/label/c.Timeline_Label_Showing';
import ITEMS from '@salesforce/label/c.Timeline_Label_Items';
import FILTERS from '@salesforce/label/c.Timeline_Label_Filters';
import TYPE_LEGEND from '@salesforce/label/c.Timeline_Label_Filter_Type_Legend';
+import DATE_LEGEND from '@salesforce/label/c.Timeline_Label_Filter_Date_Legend';
import DATE_RANGE_LEGEND from '@salesforce/label/c.Timeline_Label_Date_Range_Legend';
import FILE_TYPE from '@salesforce/label/c.Timeline_Label_Files';
import ALL_TYPES from '@salesforce/label/c.Timeline_Label_Filter_All_Types';
@@ -40,6 +41,7 @@ export default class timeline extends NavigationMixin(LightningElement) {
@api timelineParent; //parent field for the lwc set as design attribute
@api timelineTitle; //title for the lwc set as design attribute
@api preferredHeight; //height of the timeline set as design attribute
+ @api iconStyle; //the style of icon plotted in the canvas
@api earliestRange; //How far back in time to go
@api latestRange; //How far into the future to go
@api zoomTo; //Zoom to current dat or latest activity
@@ -112,12 +114,20 @@ export default class timeline extends NavigationMixin(LightningElement) {
No: "#107cad"
};
+ iconStyleMap = {
+ Square: 3,
+ Circular: 20
+ };
+
+ iconRoundedValue = 3;
+
label = {
DAYS,
SHOWING,
ITEMS,
FILTERS,
TYPE_LEGEND,
+ DATE_LEGEND,
DATE_RANGE_LEGEND,
FILE_TYPE,
ALL_TYPES,
@@ -205,7 +215,6 @@ export default class timeline extends NavigationMixin(LightningElement) {
this.allFilterValues.push(key);
}
}
- this.isFilterLoaded = true;
} else if (result.error) {
let errorType = 'Error';
let errorHeading,
@@ -245,6 +254,7 @@ export default class timeline extends NavigationMixin(LightningElement) {
if (!this._d3Rendered) {
this.todaysColour = this.todayColourMap[this.showToday];
+ this.iconRoundedValue = this.iconStyleMap[this.iconStyle];
//set the height of the component as the height is dynamic based on the attributes
let timelineDIV = this.template.querySelector('div.timeline-canvas');
this.currentParentField = this.timelineParent;
@@ -446,9 +456,9 @@ export default class timeline extends NavigationMixin(LightningElement) {
recordCopy.recordId = record.objectId;
recordCopy.id = index;
- recordCopy.label =
- record.detailField.length <= 30 ? record.detailField : record.detailField.slice(0, 30) + '...';
+ recordCopy.label = record.detailField;
recordCopy.objectName = record.objectName;
+ recordCopy.objectLabel = record.objectLabel;
recordCopy.positionDateField = record.positionDateField;
if (record.positionDateType === 'DATE') {
@@ -492,6 +502,7 @@ export default class timeline extends NavigationMixin(LightningElement) {
recordCopy.tooltipId = record.tooltipId;
recordCopy.tooltipObject = record.tooltipObject;
recordCopy.drilldownId = record.drilldownId;
+ recordCopy.alternateDetailId = record.alternateDetailId;
recordCopy.type = record.type;
recordCopy.icon = record.icon;
@@ -625,6 +636,18 @@ export default class timeline extends NavigationMixin(LightningElement) {
timelineCanvas.attr('height', svgHeight - 1);
timelineCanvas.SVGHeight = svgHeight;
+ if(me.isLanguageRightToLeft){
+ timelineCanvas.append('clipPath')
+ .attr('id', 'clipText')
+ .append('polygon')
+ .attr('points','-215,0 0,0 0,30 -215,30');
+ }
+ else{
+ timelineCanvas.append('clipPath')
+ .attr('id', 'clipText')
+ .append('polygon')
+ .attr('points','0,0 215,0 215,30 0,30');
+ }
timelineCanvas.data = timelineCanvas
.selectAll('[class~=timeline-canvas-record]')
@@ -642,7 +665,6 @@ export default class timeline extends NavigationMixin(LightningElement) {
.attr('transform', function (d) {
return 'translate(' + timelineCanvas.x(d.time) + ', ' + timelineCanvas.y(d.swimlane) + ')';
});
-
if (timelineCanvas.records.size() > 0) {
timelineCanvas.records
.append('rect')
@@ -672,8 +694,8 @@ export default class timeline extends NavigationMixin(LightningElement) {
.attr('y', 0)
.attr('width', 24)
.attr('height', 24)
- .attr('rx', 3)
- .attr('ry', 3);
+ .attr('rx', me.iconRoundedValue)
+ .attr('ry', me.iconRoundedValue);
timelineCanvas.records
.append('image')
@@ -681,6 +703,10 @@ export default class timeline extends NavigationMixin(LightningElement) {
.attr('y', 1)
.attr('height', 22)
.attr('width', 22)
+ .attr('aria-label', function (d){
+ const altText = d.objectLabel;
+ return altText;
+ })
.attr('xlink:href', function (d) {
let iconImage = '';
@@ -704,9 +730,17 @@ export default class timeline extends NavigationMixin(LightningElement) {
return iconImage;
});
+ timelineCanvas.records
+ .append('text')
+ .attr('class', 'sr-only')
+ .text(function (d) {
+ return d.positionDateValue;
+ });
+
timelineCanvas.records
.append('text')
.attr('class', 'timeline-canvas-record-label')
+ .attr('clip-path','url(#clipText)')
.attr('x', function () {
let x = 30;
switch (me.isLanguageRightToLeft) {
@@ -721,12 +755,17 @@ export default class timeline extends NavigationMixin(LightningElement) {
})
.attr('y', 16)
.attr('font-size', 12)
+ .attr('tabindex', '0')
.on('click', function (event, d) {
let drilldownId = d.recordId;
if (d.drilldownId !== '') {
drilldownId = d.drilldownId;
}
+ if (d.alternateDetailId !== '') {
+ drilldownId = d.alternateDetailId;
+ }
+
switch (d.objectName) {
case 'ContentDocumentLink': {
me[NavigationMixin.Navigate]({
@@ -761,6 +800,49 @@ export default class timeline extends NavigationMixin(LightningElement) {
}
}
})
+ .on('keydown', function (event, d) {
+ if(event.key === ' ' || event.key === 'Enter'){
+
+ let drilldownId = d.recordId;
+ if (d.drilldownId !== '') {
+ drilldownId = d.drilldownId;
+ }
+
+ switch (d.objectName) {
+ case 'ContentDocumentLink': {
+ me[NavigationMixin.Navigate]({
+ type: 'standard__namedPage',
+ attributes: {
+ pageName: 'filePreview'
+ },
+ state: {
+ selectedRecordId: d.recordId
+ }
+ });
+ break;
+ }
+ case 'CaseComment': {
+ const toastEvent = new ShowToastEvent({
+ title: me.toast.NAVIGATION_HEADER,
+ message: me.toast.NAVIGATION_BODY,
+ messageData: [d.objectName]
+ });
+ this.dispatchEvent(toastEvent);
+ break;
+ }
+ default: {
+ me[NavigationMixin.Navigate]({
+ type: 'standard__recordPage',
+ attributes: {
+ recordId: drilldownId,
+ actionName: 'view'
+ }
+ });
+ break;
+ }
+ }
+ }
+ })
.on('mouseover', function (event, d) {
let tooltipId = d.recordId;
let tooltipObject = d.objectName;
@@ -789,21 +871,44 @@ export default class timeline extends NavigationMixin(LightningElement) {
switch (me.isLanguageRightToLeft) {
case true:
- tipPosition =
- this.getBoundingClientRect().top -
- 30 +
- 'px ;left:' +
- (this.getBoundingClientRect().left - tooltipDIV.offsetWidth - 15) +
- 'px ;visibility:visible';
- break;
+ if(this.getBoundingClientRect().width < 184){
+ tipPosition =
+ this.getBoundingClientRect().top -
+ 30 +
+ 'px ;left:' +
+ (this.getBoundingClientRect().left - tooltipDIV.offsetWidth - 15) +
+ 'px ;visibility:visible';
+ break;
+ }
+ else{
+ tipPosition =
+ this.getBoundingClientRect().top -
+ 30 +
+ 'px ;left:' +
+ (this.getBoundingClientRect().right- tooltipDIV.offsetWidth - 215) +
+ 'px ;visibility:visible';
+ break;
+ }
+
default:
- tipPosition =
- this.getBoundingClientRect().top -
- 30 +
- 'px ;left:' +
- (this.getBoundingClientRect().right + 15) +
- 'px ;visibility:visible';
- break;
+ if(this.getBoundingClientRect().width < 184){
+ tipPosition =
+ this.getBoundingClientRect().top -
+ 30 +
+ 'px ;left:' +
+ (this.getBoundingClientRect().right + 15) +
+ 'px ;visibility:visible';
+ break;
+ }
+ else{
+ tipPosition =
+ this.getBoundingClientRect().top -
+ 30 +
+ 'px ;left:' +
+ (this.getBoundingClientRect().left + 205) +
+ 'px ;visibility:visible';
+ break;
+ }
}
tooltipDIV.setAttribute('style', 'top:' + tipPosition);
})
@@ -845,6 +950,8 @@ export default class timeline extends NavigationMixin(LightningElement) {
const axis = targetSVG
.insert('g', ':first-child')
.attr('class', axisConfig.class + '-' + me.timelineWidth)
+ .attr('role', 'presentation')
+ .attr('aria-hidden', 'true')
.call(x_axis);
if (typeof axisConfig.translate === 'object') {
@@ -1256,15 +1363,19 @@ export default class timeline extends NavigationMixin(LightningElement) {
const filterPopover = this.template.querySelector('div.timeline-filter');
const filterClasses = String(filterPopover.classList);
const refreshButton = this.template.querySelector('lightning-button-icon.timeline-refresh');
+ const closeButton = this.template.querySelector('[data-id="closeDialogBtn"]');
+ const filterButton = this.template.querySelector('[data-id="filterBtn"]');
if (filterClasses.includes('slds-is-open')) {
refreshButton.disabled = false;
filterPopover.classList.remove('slds-is-open');
this.isFilter = false;
+ filterButton.focus();
} else {
refreshButton.disabled = true;
filterPopover.classList.add('slds-is-open');
this.isFilter = true;
+ closeButton.focus();
}
switch (this.isLanguageRightToLeft) {
@@ -1299,6 +1410,16 @@ export default class timeline extends NavigationMixin(LightningElement) {
}
}
+ handleStartDateChange(e){
+ this.zoomStartDateString = e.target.value;
+ this.isFilterUpdated = true;
+ }
+
+ handleEndDateChange(e){
+ this.zoomEndDateString = e.target.value;
+ this.isFilterUpdated = true;
+ }
+
handleAllTypesChange(e) {
if (e.target.checked === true) {
this.filterValues = this.allFilterValues;
@@ -1334,6 +1455,20 @@ export default class timeline extends NavigationMixin(LightningElement) {
}
applyFilter() {
+ console.log('applyFilter start');
+ console.log('this.filterValues: '+this.filterValues);
+ if (this.zoomStartDateString) {
+ this.zoomStartDate = new Date(this.zoomStartDateString); // Convert string to Date object
+ console.log('Start Date updated to:', this.zoomStartDate);
+ } else {
+ console.log('Please enter a valid startdate.');
+ }
+ if (this.zoomEndDateString) {
+ this.zoomEndDate = new Date(this.zoomEndDateString); // Convert string to Date object
+ console.log('End Date updated to:', this.zoomEndDate);
+ } else {
+ console.log('Please enter a valid end date.');
+ }
this.refreshTimeline();
this.isFilterUpdated = false;
this.startingFilterValues = this.filterValues;
diff --git a/force-app/main/default/lwc/timeline/timeline.js-meta.xml b/force-app/main/default/lwc/timeline/timeline.js-meta.xml
index c80b452..ed29e59 100755
--- a/force-app/main/default/lwc/timeline/timeline.js-meta.xml
+++ b/force-app/main/default/lwc/timeline/timeline.js-meta.xml
@@ -1,6 +1,6 @@
- 59.0
+ 61.0
true
Time Warp
@@ -14,6 +14,7 @@
+
@@ -30,6 +31,7 @@
+
diff --git a/images/appBuilderDemo.gif b/images/appBuilderDemo.gif
index 25566bc..7e22b37 100644
Binary files a/images/appBuilderDemo.gif and b/images/appBuilderDemo.gif differ
diff --git a/images/heroDemo.gif b/images/heroDemo.gif
index f436976..9930c70 100644
Binary files a/images/heroDemo.gif and b/images/heroDemo.gif differ