Weekly planning template

Hello,

I’m trying to make a weekly planning as descripted below.
What is the best template that I could use ?
Each day is separated in 4 parts, and each part must be right-clickable.

1

I’m working on a proof of concept, but I’m really not convinced this is the way to go.
I’m a beginner in GoJS.

json.forEach((week) => 
	week.Days.forEach((day) => 
		diagram.add(
			$(go.Part, go.Panel.Spot,
			$(go.Shape, "Rectangle",
			{ fill: "lightgreen", stroke: null, width: 200, height: 25 }),
			$(go.TextBlock, day.Text, { alignment: new go.Spot(0.10, 0.5) }),
			$(go.TextBlock, day.Text, { alignment: new go.Spot(0.36, 0.5) }),
			$(go.TextBlock, day.Text, { alignment: new go.Spot(0.62, 0.5) }),
			$(go.TextBlock, day.Text, { alignment: new go.Spot(0.90, 0.5) }))
		)					
	)
);

Regards,

You say that each “part” must be right-clickable. What else should users be able to do? Selection? Copy, paste, delete? Edit-text-in-place? Will there be any Links, and if so, connecting what? How many people/rows will there be? How many tables will there be?

It’s hard to make any implementation suggestions when any decision might rule out certain behaviors, and we don’t have any idea of what behaviors and changes would want to be allowed.

There won’t be any links or edit.
Users should only be able to select multiple parts and then right-click > “manage activity”, which will open a lightbox.

I hope this helps you.
Thanks,

So each selectable piece will correspond to a cell in the table and will show four icons.

What you are doing could work if you also set the position on each Part. You’ll need to handle the header row and header column differently but similarly.

The other way of organizing it is just to have the data in the model and then use templates to create the individual cells. If users aren’t going to be modifying things directly, and if there’s not really any relationships or editing going on, then maybe that organization is not a needed goal.

Hello,

This is what I came up with so far. My only issue is that when I click or right click a “part” of a day, it selects the parent Panel, not the “part” I clicked.
I’m not quite sure how to fix this, could you help me ?
Thanks,

json.forEach(function(semaine) {
	diagram.add(
		$(go.Part, go.Panel.Spot,
			$(go.Shape, "Rectangle", { fill: "#A9BED8", stroke: null, width: 200, height: 25 }),
			$(go.TextBlock, semaine.Employe.Nom, { alignment: go.Spot.Center})
		)
	);
	semaine.Jours.forEach(function(jour) {														
		diagram.add(
			$(go.Part, go.Panel.Position,
				$(go.Panel, "Auto", 
					{ 
						position: new go.Point(0,0),
						contextMenu: $("ContextMenu",
							makeButtons(jour.M1.Actions)
						)
					}, 
					$(go.Shape, { stroke: null, width: 50, height: 25, fill: jour.M1.CouleurFond }),
					$(go.TextBlock, jour.M1.Lib)
				),
				$(go.Panel, "Auto", 
					{ 
						position: new go.Point(50,0),
						contextMenu: $("ContextMenu",
							makeButtons(jour.M1.Actions)
						) 
					},
					$(go.Shape, { stroke: null, width: 50, height: 25, fill: jour.M1.CouleurFond }),
					$(go.TextBlock, jour.M2.Lib)
				),
				$(go.Panel, "Auto", 
					{ 
						position: new go.Point(100,0),
						contextMenu: $("ContextMenu",
							makeButtons(jour.M1.Actions)
						)
					},
					$(go.Shape, { stroke: null, width: 50, height: 25, fill: jour.A1.CouleurFond }),
					$(go.TextBlock, jour.A1.Lib)
				),
				$(go.Panel, "Auto", 
					{ 
						position: new go.Point(150,0),
						contextMenu: $("ContextMenu",
							makeButtons(jour.M1.Actions)
						)
					},
					$(go.Shape, { stroke: null, width: 50, height: 25, fill: jour.A2.CouleurFond }),
					$(go.TextBlock, jour.A2.Lib)
				)
			)
		)}				
	);}
);

Only Parts can be selected. Normally that means Nodes and Links, but here just simple Parts. From your initial description, I thought you wanted users to be able to select the whole day for each person.

There are several possibilities. Perhaps simplest for you, is instead of having a single Part holding three Panels of different colors, you could have three Parts each being the respective Panel. Basically, each Part becomes simpler, but there are more of them.

By the way, in your template you set the width and height of the Shape, but you really should set the width and height of the Panel. If you take my suggestion, you would make the Part an “Auto” Panel and you would set the width and height directly on the Part.

Hmmm, your code isn’t actually setting the Part.position. But maybe you are doing that in other code, or you are using a Layout.

Yes, I am using a GridLayout, where each day is a Position Panel containing 4 Auto Panels :

diagram.layout = $(go.GridLayout, {
	wrappingColumn: 8
});

Hmmm, if you want to continue that, maybe you could put the three pieces of a day into a single Group that represents the whole day. I would make that Group not selectable. The Group.layout could be also be a GridLayout, with no spacing. The Group would have no elements – no visual tree! Note that for each of your new Parts you have to set the Part.containingGroup to refer to the new instance of Group that you construct for each day.

Thank you for your quick replies, I’ll give it a shot and get back to you.

I’m almost there, I just dont know how to set the containingGroup of each part (where I wrote “???”) :

diagram.layout = $(go.GridLayout, {
	wrappingColumn: 8
});

json.forEach(function(semaine) {
	diagram.add(
		$(go.Part, go.Panel.Spot,
			$(go.Shape, "Rectangle", { fill: "#A9BED8", stroke: null, width: 200, height: 25 }),
			$(go.TextBlock, semaine.Employe.Nom, { alignment: go.Spot.Center})
		)
	);
	
	semaine.Jours.forEach(function(jour) {														
		diagram.add(
			$(go.Group,
				{ background: "red", width: 200, height: 25, layout : $(go.GridLayout, { wrappingColumn: 4 }), selectable: false }
			),
			$(go.Part, "Auto",
				{ width: 50, height: 25, containingGroup: ??? },
				$(go.TextBlock, 
					new go.Binding("text", jour.M1.Lib)
				)
			),
			$(go.Part,
				{ width: 50, height: 25, containingGroup: ??? },
				$(go.TextBlock, 
					new go.Binding("text", jour.M2.Lib)
				)
			),
			$(go.Part,
				{ width: 50, height: 25, containingGroup: ??? },
				$(go.TextBlock, 
					new go.Binding("text", jour.A1.Lib)
				)
			),
			$(go.Part,
				{ width: 50, height: 25, containingGroup: ??? },
				$(go.TextBlock, 
					new go.Binding("text", jour.A2.Lib)
				)
			)							
		)}			
	);
});

This seems to work, but the TextBlocks are not showing :

function makeGroup(){
	return $(go.Group,{ background: "red", width: 200, height: 25, layout : $(go.GridLayout, { wrappingColumn: 4 }), selectable: false });
}

semaine.Jours.forEach(function(jour) {
	var group = makeGroup();
	diagram.add(
		group,
		$(go.Part, "Auto",
			{ background: "blue", width: 50, height: 25, containingGroup: group },
			$(go.TextBlock, 
				new go.Binding("text", jour.M1.Lib)
			)
		),
		$(go.Part,
			{ width: 50, height: 25, containingGroup: group },
			$(go.TextBlock, 
				new go.Binding("text", jour.M2.Lib)
			)
		),
		$(go.Part,
			{ width: 50, height: 25, containingGroup: group },
			$(go.TextBlock, 
				new go.Binding("text", jour.A1.Lib)
			)
		),
		$(go.Part,
			{ width: 50, height: 25, containingGroup: group },
			$(go.TextBlock, 
				new go.Binding("text", jour.A2.Lib)
			)
		)							
	)}			
);

Diagram.add only takes a single argument.

const group = new go.Group({
    selectable: false,
    layout: new go.GridLayout({ spacing: new go.Size(0, 0) })
  });  // note: no elements added to the Group

diagram.add(group);

diagram.add(new go.Part("Auto", { width: 50, height: 25, containingGroup: group })
  .add(
    new go.Shape({ stroke: null, fill: jour.M1.CouleurFond }),
    new go.TextBlock(jour.M1.Lib)
  )
);

. . . add the other two Parts to the group

That works perfectly !
Thank you so much, I really appreciate the help and how fast you’re answering.

Is there a way to make a part use multiple “slots” of a GridLayout, like a colspan for a table ?
image

I would like for the second row to stretch over the entire row, but if I set the size of the part, the first row is streched as well :
image

Thanks

GridLayout is pretty simple, so there’s no stretching or spanning as in “Table” Panels or TableLayout.

But you can set GridLayout.cellSize to new go.Size(1, 1).