const locationRankConfig = {
children: true,
treeFeature: true,
columns: [
{ type: 'tree',
field: 'name',
text: 'Name',
width: 280,
align: 'left',
editor: false,
htmlEncode: false,
renderer: ({ value, record }) => {
const highlight = record.data.highlight;
if (record.data.parentId === null) {
return `<div>${value} <i class="fas fa-user-tie"
style="margin-left: 12px; cursor: pointer;" /></div>`;
}
if (record.data.safeManning && !record.data.safeManningFilled && !record.data.inThePast) {
return `<div><i class="fas fa-exclamation-triangle"
style="left: 12px; color: red; position: absolute"></i>
<label class=${highlight ? 'highlight' : ''}>
${value}</label></div>`;
}
if (record.data.safeManningFilled && !record.data.inThePast) {
return `<div><i class="fa fa-check"
style="left: 12px; color: green; position: absolute"></i>
<label class=${highlight ? 'highlight' : ''}>
${value}</label></div>`;
}
return `<div><label class=${highlight ? 'highlight' : ''}>${value}</label></div>`;
},
},
],
};
Yes, I am using tree.
<BryntumScheduler
{...baseConfig}
{...schedulerConfig}
ref={this.scheduler}
eventEditFeature={false}
createEventOnDblClick={false}
children={this.state.selectedViewType.id !== PERSONAL_PLANNING_VIEW}
treeFeature={this.state.selectedViewType.id !== PERSONAL_PLANNING_VIEW}
// Custom view preset with header configuration
viewPreset={{
base: 'dayAndWeek',
}}
onEventDblClick={this.enterEdit}
panFeature={{ pan: true }}
eventDragCreateFeature={false}
scheduleMenuFeature={false}
onScroll={this.onVerticalScroll}
onEventDragAbort={this.onEventDragAbort}
timeRangesFeature={{
showCurrentTimeLine: true,
showHeaderElements: false,
}}
listeners={{
cellClick(event) {
// Add a new client when clicking plus icon
if (event.event.target.closest('.fa-user-tie')) {
debugger;
currentContext.scheduler.current.schedulerInstance.features.cellMenu.showContextMenu(event);
// currentContext.scheduler.current.schedulerInstance.columns.grid.features.cellMenu.showContextMenu(event);
}
},
cellMenuBeforeShow({ items, record }) {
debugger;
if (!record.data.isVessel) {
items.extraItem.hidden = true;
}
if (hasValue(currentContext.state.selectedSafeMannings) && currentContext.state.selectedSafeMannings.length > 0) {
const selectedSafeManning = currentContext.state.selectedSafeMannings.find(s => s.vesselId === record.data.vesselId);
// This should be removed when the default safe manning for a vessel will be saved
// into the database, in that case, selected safe manning id won't be null anymore
if (!hasValue(selectedSafeManning.safeManningId)) {
selectedSafeManning.safeManningId = items.extraItem.menu[0].id;
}
if (selectedSafeManning) {
items.extraItem.menu.forEach(item => {
if (item.id === selectedSafeManning.safeManningId) {
item.icon = 'fa fa-check';
} else {
item.icon = undefined;
}
});
} else {
items.extraItem.menu.forEach(item => {
item.icon = undefined;
});
}
}
},
}}
cellMenuFeature={{
items: {
removeRow: false,
cut: false,
copy: false,
extraItem: {
text: getTranslationByKey(translationGroup, 'lblSafeManning',
'Safe manning'),
icon: 'fas fa-user-tie',
weight: 200,
menu: this.state.safeMannings,
},
},
}}
eventMenuFeature={{
items: {
editEvent: false,
deleteEvent: false,
addEvent: false,
cutEvent: false,
copyEvent: false,
// custom item with inline handler
delete: {
text: getTranslationByKey(translationGroup, 'btnDeleteAppointment',
'Delete appointment'),
icon: 'b-fa b-fa-user-times',
weight: 200,
onItem: ({ eventRecord, resourceRecord }) =>
currentContext.handleDeleteAppointment(eventRecord, resourceRecord),
},
},
}}
onEventDrag={this.onEventDrag}
onEventKeyDown={this.onEventKeyDown}
enableDeleteKey={false}
rowHeight={parseInt(this.state.rowHeight, 10)}
eventBodyTemplate={(data) => {
let color = data.data.eventColor;
if (color === '#0') {
color = WHITE_COLOR;
}
const updatedColor = hasValue(color) ? currentContext.pickTextColorBasedOnBgColorSimple(color, WHITE_COLOR, BLACK_COLOR) : WHITE_COLOR;
const isRecurrence = data.data.isRecurrence;
if (isRecurrence) {
return `<div class="b-sch-event-header">
<i class="far fa-sync-alt" style="padding-right: 10px;
font-weight: 800;"></i><label style="color: ${updatedColor};">${data.data.name}<label></div>`;
}
// if (data.data.startDate < Date.now() && data.data.endDate > Date.now()) {
// const isCrewMemberBirthday = this.isCrewMemberBirthday(data.data);
// if (isCrewMemberBirthday === true) {
// eslint-disable-next-line max-len
// return `<div class="b-sch-event-header"><i class="fas fa-birthday-cake" style="padding-right: 10px; font-weight: 800;"></i>${data.data.name}</div>`;
// }
// }
return `<div class="b-sch-event-header"><label style="color: ${updatedColor};">${data.data.name}<label></div>`;
}}
timeRanges={this.state.timeRanges}
tbar={[
{
type: 'button',
ref: 'zoomInButton',
icon: 'b-icon-search-plus',
text: 'Zoom in',
onClick() {
currentContext.scheduler.current.schedulerInstance.zoomIn();
},
},
{
type: 'button',
ref: 'zoomOutButton',
icon: 'b-icon-search-minus',
text: 'Zoom out',
onClick() {
currentContext.scheduler.current.schedulerInstance.zoomOut();
},
},
{
type: 'button',
ref: 'scrollToTime',
text: getTranslationByKey(translationGroup, 'btnCurrentTime',
'Current time'),
onClick() {
currentContext.scheduler.current.schedulerInstance.scrollToDate(
today,
{
highlight,
animate: {
easing: 'easeFromTo',
duration: animate,
},
block: center ? 'center' : 'nearest',
});
},
},
{
type: 'slider',
ref: 'rowHeight',
text: getTranslationByKey(translationGroup, 'lblRowHeight',
'Row height'),
value: Cookies.get('rowHeight') ? Cookies.get('rowHeight') : 36,
showValue: true,
min: 25,
onInput({ value }) {
Cookies.set('rowHeight', value);
currentContext.scheduler.current.schedulerInstance.rowHeight = value;
},
},
]}
project={{
stm: {
autoRecord: true,
disabled: false,
},
}}
startDate={new Date(2018, 11, 1, 18)}
endDate={new Date(2022, 11, 1, 18)}
resources={this.state.resources}
events={this.state.events}
allowOverlap={this.state.selectedViewType.id !== PERSONAL_PLANNING_VIEW}
onBeforeEventDropFinalize={({ context }) => {
switch (this.state.selectedViewType.id) {
case PERSONAL_PLANNING_VIEW:
return this.validateDrop(context.draggedRecords[0].data,
context.newResource, context.startDate, context.endDate);
case LOCATION_RANK_VIEW:
break;
case RANK_LOCATION_VIEW:
break;
default:
break;
}
}}
onEventResizeEnd={this.onAppointmentResized}
onTimeAxisChange={this.onTimeAxisChange}
onEventDrop={this.onEventDrop}
eventDragFeature={{
showToolTip: true,
validatorFn: ({ draggedRecords, newResource, startDate, endDate }) =>
currentContext.validateDragEvent(draggedRecords[0].data,
newResource.data, startDate, endDate, false),
}}
eventResizeFeature={{
showToolTip: true,
validatorFn: ({ eventRecord, startDate, endDate }) =>
currentContext.validateResizeEvent(eventRecord.data,
startDate, endDate),
}}
/>