Added new modules and updated existing logic
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
const { ref, reactive } = Vue;
|
||||
|
||||
const HUBS = [
|
||||
{ id: 'DE', name: 'GERMANY HUB (DE)' },
|
||||
{ id: 'IT', name: 'ITALY HUB (IT)' },
|
||||
{ id: 'FR', name: 'FRANCE HUB (FR)' },
|
||||
{ id: 'GB', name: 'UNITED KINGDOM (GB)' },
|
||||
{ id: 'ES', name: 'SPAIN HUB (ES)' },
|
||||
{ id: 'AE', name: 'UAE HUB (AE)' },
|
||||
{ id: 'PL', name: 'POLAND HUB (PL)' }
|
||||
];
|
||||
|
||||
const DEPARTMENTS = ['Support', 'Technical', 'Sales', 'VIP', 'Billing'];
|
||||
const ROLES = ['Senior Lead', 'Specialist', 'Agent'];
|
||||
const SKILLS = [
|
||||
'English',
|
||||
'German',
|
||||
'French',
|
||||
'Molecular App',
|
||||
'Hardware',
|
||||
'Billing Specialist',
|
||||
'VIP Concierge',
|
||||
'Technical Training'
|
||||
];
|
||||
|
||||
const SHIFTS = [
|
||||
{ id: 'm', label: 'MORNING', color: 'green-7', badgeClass: 'day-cell-shift-badge-green' },
|
||||
{ id: 'a', label: 'AFTERNOON', color: 'blue-7', badgeClass: 'day-cell-shift-badge-blue' },
|
||||
{ id: 'h', label: 'HOTLINE', color: 'indigo-7', badgeClass: 'day-cell-shift-badge-indigo' },
|
||||
{ id: 'e', label: 'EOD ONLY', color: 'pink-7', badgeClass: 'day-cell-shift-badge-pink' }
|
||||
];
|
||||
|
||||
const agents = ref([]);
|
||||
const loading = ref(false);
|
||||
const lockedCells = ref(new Set());
|
||||
const onlineUsers = ref([]);
|
||||
|
||||
const assignments = reactive({});
|
||||
const comments = reactive({});
|
||||
const notes = reactive({});
|
||||
const holidays = reactive({});
|
||||
const specialDays = reactive({});
|
||||
|
||||
const MOCK_COMMENTS_TEXT = [
|
||||
'Late arrival expected.',
|
||||
'Dental appointment.',
|
||||
'Swapped shift.',
|
||||
'Priority focus.',
|
||||
'Remote session.'
|
||||
];
|
||||
const MOCK_NOTES_TEXT = [
|
||||
'Headset check.',
|
||||
'VPN slow.',
|
||||
'Training session.',
|
||||
'Backup Billing.',
|
||||
'Overtime pending.'
|
||||
];
|
||||
|
||||
const ONLINE_USER_ROLES = ['Planner', 'Scheduler', 'Lead', 'Manager'];
|
||||
const ONLINE_USERS_POOL = Array.from({ length: 28 }, (_, i) => {
|
||||
const pravatarId = (i % 70) + 1;
|
||||
return {
|
||||
id: i + 1,
|
||||
name: `User ${i + 1}`,
|
||||
role: ONLINE_USER_ROLES[i % ONLINE_USER_ROLES.length],
|
||||
img: `https://i.pravatar.cc/150?img=${pravatarId}`
|
||||
};
|
||||
});
|
||||
|
||||
const formatDateForId = (date) => {
|
||||
if (!date) return '';
|
||||
const d = new Date(date);
|
||||
const month = '' + (d.getMonth() + 1);
|
||||
const day = '' + d.getDate();
|
||||
const year = d.getFullYear();
|
||||
return [year, month.padStart(2, '0'), day.padStart(2, '0')].join('-');
|
||||
};
|
||||
|
||||
const generateMockAgents = (count) => {
|
||||
return Array.from({ length: count }, (_, i) => {
|
||||
const hub = HUBS[Math.floor(Math.random() * HUBS.length)];
|
||||
return {
|
||||
id: i + 1,
|
||||
name: `Agent ${i + 1}`,
|
||||
dept: DEPARTMENTS[i % DEPARTMENTS.length],
|
||||
role: ROLES[i % ROLES.length],
|
||||
hub: hub.id,
|
||||
hubName: hub.name,
|
||||
skills: [SKILLS[i % SKILLS.length], SKILLS[(i + 2) % SKILLS.length]],
|
||||
avatar: `https://api.dicebear.com/7.x/avataaars/svg?seed=Agent${i}`
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const loadDataFromDatabase = (startDate, notify) => {
|
||||
loading.value = true;
|
||||
setTimeout(() => {
|
||||
const fetchedAgents = generateMockAgents(800);
|
||||
agents.value = fetchedAgents;
|
||||
|
||||
const mockStartDate = new Date(startDate);
|
||||
|
||||
fetchedAgents.forEach(agent => {
|
||||
if (!assignments[agent.id]) assignments[agent.id] = {};
|
||||
if (!comments[agent.id]) comments[agent.id] = {};
|
||||
if (!notes[agent.id]) notes[agent.id] = {};
|
||||
|
||||
for (let i = 0; i < 60; i++) {
|
||||
const d = new Date(mockStartDate);
|
||||
d.setDate(d.getDate() + i);
|
||||
const dStr = formatDateForId(d);
|
||||
|
||||
if ((agent.id + i) % 7 === 0) assignments[agent.id][dStr] = SHIFTS[0].id;
|
||||
else if ((agent.id + i) % 5 === 0) assignments[agent.id][dStr] = SHIFTS[1].id;
|
||||
|
||||
if ((agent.id + i) % 20 === 0) comments[agent.id][dStr] = MOCK_COMMENTS_TEXT[(agent.id + i) % MOCK_COMMENTS_TEXT.length];
|
||||
if ((agent.id + i) % 25 === 0) notes[agent.id][dStr] = MOCK_NOTES_TEXT[(agent.id + i) % MOCK_NOTES_TEXT.length];
|
||||
}
|
||||
});
|
||||
|
||||
for (const key in holidays) delete holidays[key];
|
||||
for (const key in specialDays) delete specialDays[key];
|
||||
|
||||
const today = new Date();
|
||||
const tomorrow = new Date(today);
|
||||
tomorrow.setDate(today.getDate() + 1);
|
||||
holidays[formatDateForId(tomorrow)] = 'Regional Holiday';
|
||||
|
||||
const eventDay = new Date(today);
|
||||
eventDay.setDate(today.getDate() + 5);
|
||||
specialDays[formatDateForId(eventDay)] = 'Quarterly Planning';
|
||||
|
||||
loading.value = false;
|
||||
|
||||
if (notify) {
|
||||
notify({ message: 'Data Loaded: 800 Agents', color: 'positive', position: 'top', timeout: 1000 });
|
||||
}
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
const handleWssMessage = (type, payload, notify) => {
|
||||
if (type === 'LOCK_CELL') {
|
||||
const key = `${payload.agentId}:${payload.date}`;
|
||||
lockedCells.value.add(key);
|
||||
const agent = agents.value.find(a => a.id === payload.agentId);
|
||||
const name = agent ? agent.name : 'Unknown Agent';
|
||||
if (notify) {
|
||||
notify({
|
||||
message: `WSS: Cell Locked for ${name} on ${payload.date}`,
|
||||
color: 'negative',
|
||||
position: 'top',
|
||||
icon: 'lock'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const simulateWssLock = (notify) => {
|
||||
if (agents.value.length === 0) return;
|
||||
const randomAgent = agents.value[Math.floor(Math.random() * agents.value.length)];
|
||||
|
||||
let targetDate = new Date();
|
||||
const day = targetDate.getDay();
|
||||
if (day === 0) {
|
||||
targetDate.setDate(targetDate.getDate() + 1);
|
||||
} else if (day === 6) {
|
||||
targetDate.setDate(targetDate.getDate() + 2);
|
||||
}
|
||||
|
||||
const dateStr = formatDateForId(targetDate);
|
||||
handleWssMessage('LOCK_CELL', { agentId: randomAgent.id, date: dateStr }, notify);
|
||||
};
|
||||
|
||||
const selectRandomItems = (list, count) => {
|
||||
const pool = [...list];
|
||||
const selected = [];
|
||||
while (pool.length > 0 && selected.length < count) {
|
||||
const idx = Math.floor(Math.random() * pool.length);
|
||||
selected.push(pool.splice(idx, 1)[0]);
|
||||
}
|
||||
return selected;
|
||||
};
|
||||
|
||||
const seedOnlineUsers = (count = 7) => {
|
||||
onlineUsers.value = selectRandomItems(ONLINE_USERS_POOL, count);
|
||||
};
|
||||
|
||||
const simulateWssOnlineUsersChange = (notify) => {
|
||||
if (onlineUsers.value.length === 0) {
|
||||
seedOnlineUsers(3);
|
||||
return;
|
||||
}
|
||||
|
||||
const maxOnline = 18;
|
||||
const minOnline = 1;
|
||||
const shouldAdd = Math.random() > 0.45;
|
||||
const current = [...onlineUsers.value];
|
||||
|
||||
if (shouldAdd && current.length < maxOnline) {
|
||||
const available = ONLINE_USERS_POOL.filter(
|
||||
user => !current.some(existing => existing.id === user.id)
|
||||
);
|
||||
if (available.length === 0) return;
|
||||
const joiner = available[Math.floor(Math.random() * available.length)];
|
||||
onlineUsers.value = [...current, joiner];
|
||||
if (notify) {
|
||||
notify({
|
||||
message: `WSS: ${joiner.name} joined`,
|
||||
color: 'grey-8',
|
||||
textColor: 'white',
|
||||
position: 'bottom-right',
|
||||
timeout: 700,
|
||||
icon: 'group_add'
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (current.length > minOnline) {
|
||||
const leaverIndex = Math.floor(Math.random() * current.length);
|
||||
const [leaver] = current.splice(leaverIndex, 1);
|
||||
onlineUsers.value = current;
|
||||
if (notify) {
|
||||
notify({
|
||||
message: `WSS: ${leaver.name} left`,
|
||||
color: 'grey-8',
|
||||
textColor: 'white',
|
||||
position: 'bottom-right',
|
||||
timeout: 700,
|
||||
icon: 'person_remove'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const startOnlineUsersSimulation = (notify, options = {}) => {
|
||||
const minDelay = options.minDelay ?? 1800;
|
||||
const maxDelay = options.maxDelay ?? 5200;
|
||||
let timeoutId = null;
|
||||
let active = true;
|
||||
|
||||
if (onlineUsers.value.length === 0) {
|
||||
seedOnlineUsers(options.seedCount ?? 7);
|
||||
}
|
||||
|
||||
const scheduleNext = () => {
|
||||
if (!active) return;
|
||||
const delay = Math.floor(minDelay + Math.random() * (maxDelay - minDelay));
|
||||
timeoutId = setTimeout(() => {
|
||||
simulateWssOnlineUsersChange(notify);
|
||||
scheduleNext();
|
||||
}, delay);
|
||||
};
|
||||
|
||||
scheduleNext();
|
||||
|
||||
return () => {
|
||||
active = false;
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
};
|
||||
};
|
||||
|
||||
export {
|
||||
HUBS,
|
||||
DEPARTMENTS,
|
||||
ROLES,
|
||||
SKILLS,
|
||||
SHIFTS,
|
||||
agents,
|
||||
loading,
|
||||
lockedCells,
|
||||
onlineUsers,
|
||||
assignments,
|
||||
comments,
|
||||
notes,
|
||||
holidays,
|
||||
specialDays,
|
||||
loadDataFromDatabase,
|
||||
handleWssMessage,
|
||||
simulateWssLock,
|
||||
seedOnlineUsers,
|
||||
simulateWssOnlineUsersChange,
|
||||
startOnlineUsersSimulation
|
||||
};
|
||||
Reference in New Issue
Block a user