Our pure JavaScript Scheduler component


Post by antoine »

Hello,

I want to show dependencies but it doesn't work. I used same method that worked for me with Gantt component.

Here is my scheduler config :

this.schedulerConfig = {
	dependenciesFeature : true,
	rowHeight: 60,
	barMargin: 0,
	eventLayout: "overlap",
	features:{
		tree : true,
		labels       : {
			top : {
				field : 'name',
				renderer({ eventRecord }): string {
					if(eventRecord.data.length !== 0){
						if (eventRecord.data.position !== "top") {
							return ``;
						}
						else {
							return `${eventRecord.data.name}`;
						}
					} 
				}
			},
			bottom : {
				field : 'name',
				renderer({ eventRecord }): string {
					if(eventRecord.data.length !== 0){
						if (eventRecord.data.position !== "bottom") {
							return ``;
						}
						else {
							return `${eventRecord.data.name}`;
						}
					} 
				}
			},
			left : {
				field : 'name',
				renderer({ eventRecord }): string {
					if(eventRecord.data.length !== 0){
						if (eventRecord.data.position !== "left") {
							return ``;
						}
						else {
							return `${eventRecord.data.name}`;
						}
					} 
				}
			},
			right : {
				field : 'name',
				renderer({ eventRecord }): string {
					if(eventRecord.data.length !== 0){
						if (eventRecord.data.position !== "right") {
							return ``;
						}
						else {
							return `${eventRecord.data.name}`;
						}
					} 
				}
			}
		},
		scheduleMenu : {
			disabled: true
		},
		cellMenu : {
			disabled : true
		},
		eventMenu : {
			items : {
				custom: {
					text : 'Custom',
					icon : 'b-fa b-fa-fw b-fa-brush',
					onItem: ({eventRecord}) =>  {
						const modalRef = this.modalService.open(GanttBcsDialogColorComponent, { size: 'lg', backdrop: 'static' });
						modalRef.componentInstance.type = eventRecord.data.type;
								modalRef.componentInstance.sendTaskColor.subscribe((color) => {
							this.setColor(eventRecord.data,color);
						});

					modalRef.componentInstance.sendLabel.subscribe((label) => {
						this.setLabel(eventRecord,label);
					})
				}
			},
			hide: {
				text: 'Cacher',
				icon : 'b-fa b-fa-fw b-fa-eye-slash',
				onItem: ({eventRecord}) =>  {
					this.setColor(eventRecord.data,"transparent");
				}
			},
			positionLabel : {
				text : 'Position label',
				icon : 'b-fa b-fa-fw b-fa-flag',
				menu: [{
					text: "Droite",
					icon : 'b-icon b-icon-right',
					onItem: ({eventRecord}) => {
						this.setPositionLabel(eventRecord,"right");
					}
				}, {
					text: "Gauche",
					icon : 'b-icon b-icon-left',
					onItem: ({eventRecord}) => {
						this.setPositionLabel(eventRecord,"left");
					}
				}, {
					text: "Dessus",
					icon : 'b-icon b-icon-up',
					onItem: ({eventRecord}) => {
						this.setPositionLabel(eventRecord,"top");
					}
				},
				{
					text: "Dessous",
					icon : 'b-icon b-icon-down',
					onItem: ({eventRecord}) => {
						this.setPositionLabel(eventRecord,"bottom");
					}
				}]
			},
			scroll: {
				text: "Scroll",
				icon: 'b-fa b-fa-fw b-fa-scroll',
				menu: [{
					text: "Début",
					icon: 'b-icon b-icon-left',
					onItem: ({eventRecord}) => {
						const eventModel = this.scheduler.eventStore.getById(eventRecord.data.id) as EventModel;
						this.scheduler.scrollEventIntoView(eventModel, {block: 'start', animate: true, highlight : true})
					}
				},{
					text: "Fin",
					icon: 'b-icon b-icon-right',
					onItem: ({eventRecord}) => {
						const eventModel = this.scheduler.eventStore.getById(eventRecord.data.id) as EventModel;
						this.scheduler.scrollEventIntoView(eventModel, {block: 'end', animate: true, highlight : true})
					}
				}]
			},
			editEvent: false,
			copyEvent: false,
			cutEvent: false,
			unassignEvent: false,
			deleteEvent: false
		},
		processItems:({ eventRecord, items }) => {
			if (eventRecord.data.hidden) {
				items.hide = {
					text   : 'Montrer',
					icon   : 'b-fa b-fa-fw b-fa-eye',
					onItem: ({ eventRecord }) => {
						const posBC = eventRecord.data.style.indexOf("background-color") + 1;
						const posEndBC = eventRecord.data.style.indexOf(";",posBC) + 1;
						let newStyle = eventRecord.data.style.substring(0, posBC) + eventRecord.data.style.substring(posEndBC, eventRecord.style.length);
						newStyle += "background-color: " + eventRecord.data.color + ";";
						this.data.events.forEach(event => {
							if(event.resourceId === eventRecord.data.resourceId){
								if(event.idEvent === eventRecord.data.idEvent){
									event.style = newStyle;
									event.hidden = !event.hidden;
								}
							}
						});
						this.data.events = this.data.events.slice();
					}
				};
			}

			if (eventRecord.data.type === "jalon"){
				if(eventRecord.data.idEvent === eventRecord.data.resourceId){
					items.parent = {
						text: 'Afficher dans parent',
						icon: "b-icon b-icon-up",
						menu: [{
							text: "Opérations",
							onItem: ({eventRecord}) => {
								this.displayInParent(eventRecord,"opération");
							}
						}, {
							text: "Versions",
							onItem: ({eventRecord}) => {
								this.displayInParent(eventRecord,"version");
							}
						}, {
							text: "Systèmes",
							onItem: ({eventRecord}) => {
								this.displayInParent(eventRecord,"système");
							}
						}]
					}
				}
				else{
					items.parent = {
						text: 'Retirer de parent',
						icon: "b-icon b-icon-down",
						onItem: ({eventRecord}) => {
							this.removeFromParent(eventRecord);
						}
					}
				}
			}
		}
	}
},

resourceStore : {
	data: this.data.resources,
	syncDataOnLoad: true
},
dependencyStore : {
	data: this.data.dependencies,
	syncDataOnLoad: true
},
eventStore : {
	data : this.data.events,
	syncDataOnLoad: true
},
viewPreset       : 'hourAndDay',
multiEventSelect : true,
	
mode : 'horizontal',
	
columns : [
	{ 
		text : 'Name', 
		field : 'name', 
		width : 130,
		type : 'tree',
		expandedFolderIconCls  : null,
		collapsedFolderIconCls : null,
		leafIconCls            : null,
		htmlEncode             : false,
		renderer(
			{ record,size}:
			{ record: ResourceModel & { [key: string]: any }; size: { height: number; color: string } }
		): string {
			size.height = record.data.size;
			if(record.data.length !== 0){
				return `<div class="name">${record.data.name}</div>`;
			}
		},
	},
],
columnLines : { disabled : false }
};

My html tag :

<bryntum-scheduler 
        #scheduler
        [barMargin]                 = "schedulerConfig.barMargin"
        [columns]                   = "schedulerConfig.columns"
        [events]                    = "data.events"
        [mode]                      = "schedulerConfig.mode"
        [resources]                 = "data.resources"
        [dependenciesFeature]       = "schedulerConfig.dependenciesFeature"
        [dependencies]              = "data.dependencies"
        [rowHeight]                 = "schedulerConfig.rowHeight"
        [viewPreset]                = "schedulerConfig.viewPreset"
        [columnLinesFeature]        = "schedulerConfig.columnLines"
        [treeFeature]               = "schedulerConfig.features.tree"
        [eventMenuFeature]          = "schedulerConfig.features.eventMenu"
        [scheduleMenuFeature]       = "schedulerConfig.features.scheduleMenu"
        [eventLayout]               = "schedulerConfig.eventLayout"
        [eventRenderer]             = "eventRenderer"
        [labelsFeature]             = "schedulerConfig.features.labels"
    ></bryntum-scheduler>

How I fill the dependency table :

if(jalon.predecesseur !== ""){
	const pred = this.dataJalons.find(element => element.idJalon === jalon.predecesseur)
	if(pred != null){
		idDependancies++;
		dependencies.push({id: idDependancies,from: jalon.predecesseur, to: jalon.idJalon})
		if(pred.idOperation !== jalon.idOperation){
			idDependancies++;
			dependencies.push({id: idDependancies,from: pred.idOperation, to: jalon.idOperation, cls: "extra-special-dependency"})
		}
	}
}

It's filled just okay when I look at my console (see picture).

What am I doing wrong, did I miss something ?

Attachments
dependency.PNG
dependency.PNG (4.98 KiB) Viewed 512 times

Post by mats »

Try

this.schedulerConfig = {
	rowHeight: 60,
	barMargin: 0,
	eventLayout: "overlap",
	features:{
		dependencies : true,

Post by antoine »

It doesn't work


Post by mats »

Can you please ZIP up a full test case showing all your code and we'll look into it quickly?


Post by antoine »

I finally have the answer ! I post it because maybe it can help somebody else. When your depencies data is used to create a depencies records, two properties are added to your data : fromEvent and toEvent. These properties are also present in depencyRecord and contain eventRecords bind by the dependency.

However when you modify your data to add/remove/modify your dependencyStore, originalData have now the two property fromEvent and toEvent, containing id of events. Then when the data is reading, properties fromEvent and toEvent are already filled and cannot contain eventRecords but contain only id of events (as we can see in the picture I sent on top of the topic). Then dependencies are not showed. To avoid the problem, you should do this after or before your modification :

this.data.dependencies.forEach(element => {
			delete element.fromEvent;
			delete element.toEvent;
		});

Post by alex.l »

Glad to hear it is working now.
Actually that should work without these manipulations in case you just add/remove data in DependencyStore.
If it's possible to get a runnable test case, we will have a look and try to understand what's the initial problem.

Thank you.

All the best,
Alex


Post Reply