I used the php demo example and figured it out. So that's fixed. Now I'm trying to deliver that data from our load endpoint, but I can't get the calendar and calendar interval data to load. Is my formatting here correct?
def load
begin
tasks = Task.where(schedule_id: params[:schedule_id]).order(:parentIndex)
dependencies = Dependency.where(schedule_id: params[:schedule_id])
calendars = Calendar.where(schedule_id: params[:schedule_id])
calendar_intervals = CalendarInterval.where(schedule_id: params[:schedule_id])
resources = Resource.where(schedule_id: params[:schedule_id])
assignments = Assignment.where(schedule_id: params[:schedule_id])
time_ranges = TimeRange.where(schedule_id: params[:schedule_id])
options = Option.all
# calendar_intervals.each do |r|
# r[:type] = r[:typ]
# r.delete(:typ)
# end
# dependencies.each do |r|
# r[:type] = r[:typ]
# r.delete(:typ)
# end
# Group calendar intervals by calendar id
intervals_by_calendar = calendar_intervals.group_by(&:calendar)
# Create calendar rows with nested intervals
calendar_rows = calendars.map do |calendar|
{
id: calendar.id,
name: calendar.name,
intervals: intervals_by_calendar[calendar.id]&.map do |interval|
{
id: interval.id,
calendar: interval.calendar,
type: interval.typ, # Ensure the field name matches your model
startDate: interval.startDate,
endDate: interval.endDate,
isWorking: interval.isWorking,
availability: interval.availability,
recurrentStartDate: interval.recurrentStartDate,
recurrentEndDate: interval.recurrentEndDate
}
end || []
}
end
render json: {
success: true,
tasks: {
rows: tasks
},
dependencies: {
rows: dependencies
},
calendars: {
rows: calendar_rows
},
resources: {
rows: resources
},
assignments: {
rows: assignments
},
time_ranges: {
rows: time_ranges
},
options: {
rows: options
}
}
rescue => e
render json: {
success: false,
message: e.message
}
end
end
The data seems correct. Can you please check the calendar on project? To see if there is some calendar is being used or not. You can do this: project.calendar'. And please try setting thedifferent calendar ids` from your calendars data on project and see if that's working.
Sorry, actually 'project.calendar' does NOT have data, it is null. Only project.calendars, plural, has the calendar data. Should project.calendar have data itself? What could cause it to be null?
The only issue for this is that you are not setting the calendar on project. Can you please cross check that you have set the calendar on project? In our examples, we usually have this in our data.json:
"project" : {
"calendar" : "general",
},
This tells the project to use the calendar with general id from calendars data. As I have mentioned above, you can try setting the calendar from console and see if it is working.
You can do this:
bryntum.query('gantt').project.calendar = 2129 // 2129 is your first calendar id
I ran those commands but nothing happens. And when I check the calendar value after setting it like that it is still null. Would it be possible to do a quick Zoom so you can see the full context of our setup?
var Gantt = window.bryntum.gantt.Gantt;
var ProjectModel = window.bryntum.gantt.ProjectModel;
var Calendar = window.bryntum.gantt.CalendarModel;
var StateTrackingManager = window.bryntum.gantt.StateTrackingManager;
var LocaleHelper = window.bryntum.gantt.LocaleHelper;
var LocaleManager = window.bryntum.gantt.LocaleManager;
var DateHelper = window.bryntum.gantt.DateHelper;
var HasPercentDoneMixin = window.bryntum.gantt.HasPercentDoneMixin;
class MyProjectModel extends HasPercentDoneMixin.derive(ProjectModel) {}
LocaleHelper.publishLocale(CONSLOG.bryntum_pt_br);
LocaleHelper.publishLocale(CONSLOG.bryntum_es);
//LocaleManager.throwOnMissingLocale = true;
if (CONSLOG.locale == "br")
LocaleManager.locale = 'PtBr';
if (CONSLOG.locale == "es")
LocaleManager.locale = 'Es';
// const calendar = new Calendar({
// id: 'general',
// intervals: [
// {
// recurrentStartDate: 'on Sat at 0:00',
// recurrentEndDate: 'on Mon at 0:00',
// isWorking: false
// }
// ]
// });
const project = new MyProjectModel({
taskStore : {
transformFlatData : true
},
// loadUrl: `/${CONSLOG.locale}/projects/${CONSLOG.project_id}/schedules/${schedule_id}/tasks/load`, // URL for data loading
// syncUrl: `/${CONSLOG.locale}/projects/${CONSLOG.project_id}/schedules/${schedule_id}/tasks/sync`, // URL for data saving
transport : {
load : {
url : `/${CONSLOG.locale}/projects/${CONSLOG.project_id}/schedules/${schedule_id}/tasks/load`, // URL for data loading
requestConfig: {
headers: {
'X-CSRF-Token': csrfToken
}
}
},
sync : {
url : `/${CONSLOG.locale}/projects/${CONSLOG.project_id}/schedules/${schedule_id}/tasks/sync`, // URL for data saving
requestConfig: {
headers: {
'X-CSRF-Token': csrfToken
}
}
}
},
autoLoad: true,
autoSync: true,
stm: new StateTrackingManager({
autoRecord: true
}),
//calendar: 'general'
});
// project.calendarManagerStore.add(calendar);
// create the Bryntum Gantt instance and append to body
const gantt = new Gantt({
appendTo: "gantt_here",
dependencyIdField : 'wbsCode',
selectionMode : {
cell : true,
dragSelect : true,
rowNumber : true
},
project,
features : {
excelExporter : {
// Choose the date format for date fields
dateFormat : 'YYYY-MM-DD HH:mm'
},
mspExport : true,
//xerExport: true,
taskMenu : {
items : {
// Add extra Export menu item available on all tasks
exportToIcs : {
icon : 'b-fa b-fa-calendar-alt',
text : 'Add to Calendar (.ics)',
weight : 900,
onItem({ taskRecord }) {
taskRecord.exportToICS({
// Here you can add some custom ICS values (See https://tools.ietf.org/html/rfc5545 for more information)
});
}
}
}
},
pdfExport : {
exportServer: 'https://dev.bryntum.com:8082',
// Required for font-awesome icons to display correctly
// headerTpl,
// footerTpl
},
rowReorder : {
showGrip : true
},
nonWorkingTime : true
},
columns: [
{ type: 'wbs', hidden: true },
{ type: 'name', width: 250, text: CONSLOG.T.activity[CONSLOG.locale], showWbs: true},
{ type: 'startdate', width: 50 },
{ type: 'enddate', width: 50 },
{ type: 'duration', width: 50 },
{ type: 'resourceassignment', width: 100, text: CONSLOG.T.resources[CONSLOG.locale] },
{ text: CONSLOG.T.percent_done[CONSLOG.locale], field: 'percentDone', type : 'percentdone', showCircle : true, width : CONSLOG.locale != 'en' ? 75 : 50, sortable: false, group: false, editor: false},
],
rowHeight: 35,
barMargin: 5,
});
// Function to update the percentage complete
const updatePercentageComplete = () => {
const tasks = project.taskStore;
if (tasks && tasks.count) { // Ensure tasks are loaded
const totalPercentageComplete = project.percentDone;
if (!isNaN(totalPercentageComplete)) {
document.querySelector('.list-group-item.schedules .counter').textContent = Math.floor(totalPercentageComplete) + '%';
}
}
};
// Enable STM after data is loaded
project.on('load', () => {
project.stm.enable();
// const calendarData = project.calendarManagerStore.data; // Check this to debug
// console.log('Calendar Data:', calendarData);
// console.log('Project Data:', project.data);
debugger
// Update percentage after task change or data change
//gantt.on('taskchanged', updatePercentageComplete);
gantt.on('taskchanged', () => {
console.log('Task changed, attempting to sync...');
updatePercentageComplete();
project.sync().then(response => {
if (response.success) {
console.log('Task synced successfully');
} else {
console.error('Failed to sync task');
}
}).catch(error => {
console.error('Error syncing task:', error);
});
});
gantt.on('datachange', updatePercentageComplete);
});
// Update percentage complete after data import
project.on('dataReady', updatePercentageComplete);
And this is our Rails /load endpoint code:
def load
begin
tasks = Task.where(schedule_id: params[:schedule_id]).order(:parentIndex)
dependencies = Dependency.where(schedule_id: params[:schedule_id])
calendars = Calendar.where(schedule_id: params[:schedule_id])
calendar_intervals = CalendarInterval.where(schedule_id: params[:schedule_id])
resources = Resource.where(schedule_id: params[:schedule_id])
assignments = Assignment.where(schedule_id: params[:schedule_id])
time_ranges = TimeRange.where(schedule_id: params[:schedule_id])
options = Option.all
# calendar_intervals.each do |r|
# r[:type] = r[:typ]
# r.delete(:typ)
# end
# dependencies.each do |r|
# r[:type] = r[:typ]
# r.delete(:typ)
# end
# Group calendar intervals by calendar id
intervals_by_calendar = calendar_intervals.group_by(&:calendar)
# Create calendar rows with nested intervals
calendar_rows = calendars.map do |calendar|
{
id: calendar.id,
name: calendar.name,
intervals: intervals_by_calendar[calendar.id]&.map do |interval|
{
calendar: interval.calendar,
isWorking: interval.isWorking,
recurrentStartDate: interval.recurrentStartDate,
recurrentEndDate: interval.recurrentEndDate
}
end || []
}
end
render json: {
success: true,
tasks: {
rows: tasks
},
dependencies: {
rows: dependencies
},
calendars: {
rows: calendar_rows
},
resources: {
rows: resources
},
assignments: {
rows: assignments
},
time_ranges: {
rows: time_ranges
},
options: {
rows: options
}
}
rescue => e
render json: {
success: false,
message: e.message
}
end
end
We've already confirmed that after loading, project.calendarManagerStore.data does in fact have the calendar data. But project.calendar is null, and like I said it stays null even after trying to set it with bryntum.query('gantt').project.calendar = 2129