upload.html au top
This commit is contained in:
176
newUI.html
176
newUI.html
@@ -168,7 +168,7 @@
|
||||
const timelineOptions = {
|
||||
timeAxis: {scale: "hour", step: 6},
|
||||
orientation: {axis: "top"},
|
||||
stack: false,
|
||||
stack: true,
|
||||
xss: {disabled: true}
|
||||
};
|
||||
|
||||
@@ -372,131 +372,155 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
function getColorForSkill(skill) {
|
||||
const skillColors = {
|
||||
"INFIRMIER": "#FF69B4", // Rose
|
||||
"MEDECIN": "#4169E1", // Bleu
|
||||
"PRELEVEMENT": "#FF8C00", // Orange
|
||||
"ACCUEIL": "#228B22", // Vert
|
||||
"TRANSPORT": "#8B008B", // Violet
|
||||
"SUPERVISION": "#FFD700" // Or
|
||||
};
|
||||
return skillColors[skill] || COLORS.DEFAULT;
|
||||
}
|
||||
|
||||
function renderSchedule(schedule) {
|
||||
// Clear existing data
|
||||
// Efface les anciennes données
|
||||
byEmployeeGroupDataSet.clear();
|
||||
byEmployeeItemDataSet.clear();
|
||||
byLocationGroupDataSet.clear();
|
||||
byLocationItemDataSet.clear();
|
||||
|
||||
// Update score
|
||||
|
||||
// Met à jour le score
|
||||
$('#score').text('Score: ' + (schedule.score || '?'));
|
||||
$('#analyzeButton').prop('disabled', !schedule.score);
|
||||
|
||||
// Count unassigned shifts
|
||||
|
||||
// Compte les shifts non assignés
|
||||
let unassignedCount = 0;
|
||||
schedule.shifts.forEach(shift => {
|
||||
if (!shift.employee) unassignedCount++;
|
||||
});
|
||||
|
||||
$('#unassignedShifts').text(
|
||||
unassignedCount === 0
|
||||
? 'No unassigned shifts'
|
||||
: `${unassignedCount} unassigned shifts`
|
||||
unassignedCount === 0 ? 'No unassigned shifts' : `${unassignedCount} unassigned shifts`
|
||||
);
|
||||
|
||||
// Render employees
|
||||
schedule.employees.forEach((employee, index) => {
|
||||
// Add employee group
|
||||
const skillsBadges = employee.skills.map(skill =>
|
||||
// Rend les employés
|
||||
schedule.employees.forEach(employee => {
|
||||
const skillsBadges = employee.skills.map(skill =>
|
||||
`<span class="badge bg-secondary me-1">${skill}</span>`
|
||||
).join('');
|
||||
|
||||
byEmployeeGroupDataSet.add({
|
||||
id: employee.name,
|
||||
content: `<div><strong>${employee.name}</strong><br/>${skillsBadges}</div>`
|
||||
});
|
||||
|
||||
// Add availability indicators
|
||||
// Ajoute les disponibilités
|
||||
['unavailableDates', 'undesiredDates', 'desiredDates'].forEach((dateType, typeIndex) => {
|
||||
const color = [COLORS.UNAVAILABLE, COLORS.UNDESIRED, COLORS.DESIRED][typeIndex];
|
||||
const label = ['Unavailable', 'Undesired', 'Desired'][typeIndex];
|
||||
|
||||
employee[dateType]?.forEach((date, dateIndex) => {
|
||||
const startDate = new Date(date + 'T00:00:00');
|
||||
const endDate = new Date(date + 'T23:59:59');
|
||||
|
||||
byEmployeeItemDataSet.add({
|
||||
id: `${employee.name}-${dateType}-${dateIndex}`,
|
||||
group: employee.name,
|
||||
content: label,
|
||||
content: ['Unavailable', 'Undesired', 'Desired'][typeIndex],
|
||||
start: startDate,
|
||||
end: endDate,
|
||||
type: 'background',
|
||||
style: `opacity: 0.5; background-color: ${color}`
|
||||
style: `opacity: 0.3; background-color: ${color}`
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Render locations and shifts
|
||||
const locations = [...new Set(schedule.shifts.map(shift => shift.location))];
|
||||
locations.forEach(location => {
|
||||
byLocationGroupDataSet.add({
|
||||
id: location,
|
||||
content: location
|
||||
});
|
||||
});
|
||||
|
||||
// Render shifts
|
||||
schedule.shifts.forEach((shift, index) => {
|
||||
const startTime = new Date(shift.start);
|
||||
const endTime = new Date(shift.end);
|
||||
|
||||
if (shift.employee) {
|
||||
// Assigned shift
|
||||
const hasRequiredSkill = shift.employee.skills.includes(shift.requiredSkill);
|
||||
const skillColor = hasRequiredSkill ? COLORS.SKILL_MATCH : COLORS.SKILL_MISMATCH;
|
||||
const shiftColor = getShiftColor(shift, shift.employee);
|
||||
|
||||
// Add to employee timeline
|
||||
byEmployeeItemDataSet.add({
|
||||
id: `shift-${index}-emp`,
|
||||
group: shift.employee.name,
|
||||
content: `<div><strong>${shift.location}</strong><br/>
|
||||
<span class="badge" style="background-color:${skillColor}">${shift.requiredSkill}</span></div>`,
|
||||
start: startTime,
|
||||
end: endTime,
|
||||
style: `background-color: ${shiftColor}`
|
||||
});
|
||||
|
||||
// Add to location timeline
|
||||
byLocationItemDataSet.add({
|
||||
id: `shift-${index}-loc`,
|
||||
group: shift.location,
|
||||
content: `<div><strong>${shift.employee.name}</strong><br/>
|
||||
<span class="badge" style="background-color:${skillColor}">${shift.requiredSkill}</span></div>`,
|
||||
start: startTime,
|
||||
end: endTime,
|
||||
style: `background-color: ${shiftColor}`
|
||||
});
|
||||
} else {
|
||||
// Unassigned shift
|
||||
byLocationItemDataSet.add({
|
||||
id: `shift-${index}-unassigned`,
|
||||
group: shift.location,
|
||||
content: `<div><strong>Unassigned</strong><br/>
|
||||
<span class="badge bg-secondary">${shift.requiredSkill}</span></div>`,
|
||||
start: startTime,
|
||||
end: endTime,
|
||||
style: `background-color: ${COLORS.UNASSIGNED}`
|
||||
// Crée les groupes par (lieu + compétence)
|
||||
const locationSkillGroups = {};
|
||||
schedule.shifts.forEach(shift => {
|
||||
const groupId = `${shift.location}_${shift.requiredSkill}`;
|
||||
if (!locationSkillGroups[groupId]) {
|
||||
locationSkillGroups[groupId] = true;
|
||||
byLocationGroupDataSet.add({
|
||||
id: groupId,
|
||||
content: `<div>
|
||||
<strong>${shift.location}</strong><br/>
|
||||
<span class="badge" style="background-color: ${getColorForSkill(shift.requiredSkill)}">
|
||||
${shift.requiredSkill}
|
||||
</span>
|
||||
</div>`
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Set timeline window
|
||||
// Ajoute les shifts aux groupes
|
||||
schedule.shifts.forEach((shift, index) => {
|
||||
const startTime = new Date(shift.start);
|
||||
const endTime = new Date(shift.end);
|
||||
const groupId = `${shift.location}_${shift.requiredSkill}`;
|
||||
const skillColor = getColorForSkill(shift.requiredSkill);
|
||||
|
||||
// Ajoute au timeline "By Employee"
|
||||
if (shift.employee) {
|
||||
const hasRequiredSkill = shift.employee.skills.includes(shift.requiredSkill);
|
||||
const shiftColor = hasRequiredSkill ? COLORS.SKILL_MATCH : COLORS.SKILL_MISMATCH;
|
||||
|
||||
byEmployeeItemDataSet.add({
|
||||
id: `shift-${index}-emp`,
|
||||
group: shift.employee.name,
|
||||
content: `<div>
|
||||
<strong>${shift.location}</strong><br/>
|
||||
<span class="badge" style="background-color:${skillColor}">${shift.requiredSkill}</span><br/>
|
||||
${startTime.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})} -
|
||||
${endTime.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}
|
||||
</div>`,
|
||||
start: startTime,
|
||||
end: endTime,
|
||||
style: `background-color: ${shiftColor}; border: 1px solid #555; color: #fff;`
|
||||
});
|
||||
}
|
||||
|
||||
// Ajoute au timeline "By Location"
|
||||
if (shift.employee) {
|
||||
const hasRequiredSkill = shift.employee.skills.includes(shift.requiredSkill);
|
||||
const shiftColor = hasRequiredSkill ? skillColor : COLORS.SKILL_MISMATCH;
|
||||
|
||||
byLocationItemDataSet.add({
|
||||
id: `shift-${index}-loc`,
|
||||
group: groupId,
|
||||
content: `<div>
|
||||
<strong>${shift.employee.name}</strong><br/>
|
||||
${startTime.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})} -
|
||||
${endTime.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}
|
||||
</div>`,
|
||||
start: startTime,
|
||||
end: endTime,
|
||||
style: `background-color: ${shiftColor}; border: 1px solid #555; color: #fff;`
|
||||
});
|
||||
} else {
|
||||
// Shift non assigné
|
||||
byLocationItemDataSet.add({
|
||||
id: `shift-${index}-unassigned`,
|
||||
group: groupId,
|
||||
content: `<div><strong>Non assigné</strong></div>`,
|
||||
start: startTime,
|
||||
end: endTime,
|
||||
style: `background-color: ${COLORS.UNASSIGNED}; border: 1px solid #555; color: #000;`
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Ajuste la fenêtre de la timeline
|
||||
if (schedule.shifts.length > 0) {
|
||||
const dates = schedule.shifts.map(shift => new Date(shift.start));
|
||||
const minDate = new Date(Math.min(...dates));
|
||||
const maxDate = new Date(Math.max(...dates));
|
||||
maxDate.setDate(maxDate.getDate() + 1);
|
||||
|
||||
byEmployeeTimeline.setWindow(minDate, maxDate);
|
||||
byLocationTimeline.setWindow(minDate, maxDate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getShiftColor(shift, employee) {
|
||||
const shiftDate = new Date(shift.start).toISOString().split('T')[0];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user