115 lines
4.2 KiB
JavaScript
115 lines
4.2 KiB
JavaScript
const AgentRow = {
|
|
props: ['agent', 'dates', 'isCompact', 'weekendsAreWorkingDays'],
|
|
template: `
|
|
<div class="planner-row hover:bg-blue-1">
|
|
<!-- Sticky Left Col -->
|
|
<div class="left-col border-b cursor-pointer transition-colors hover:bg-indigo-50"
|
|
:class="[isCompact ? 'cell-compact' : '']"
|
|
@click="openProfile(agent)">
|
|
<q-avatar :size="isCompact ? '22px' : '30px'">
|
|
<img :src="agent.avatar">
|
|
</q-avatar>
|
|
<div class="q-ml-sm overflow-hidden">
|
|
<div class="text-weight-bold truncate" :style="{fontSize: isCompact ? '11px' : '13px'}">{{ agent.name }}</div>
|
|
<div v-if="!isCompact" class="text-[9px] text-grey-6 uppercase font-bold truncate">{{ agent.role }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Scrollable Cells Area -->
|
|
<div class="cells-area">
|
|
<div v-for="(date, i) in dates" :key="'c'+agent.id+i"
|
|
class="cell"
|
|
:class="getCellClasses(agent, date, i)"
|
|
@click="handleCellClick(agent, date)">
|
|
|
|
<div v-if="(agent.id + i) === 42" class="locked-overlay">
|
|
<q-icon name="lock" color="amber-10" size="14px"></q-icon>
|
|
</div>
|
|
|
|
<div v-if="!!ValidationUtils.hasConflict(getShifts(agent, date))" class="absolute-top-right q-pa-xs" style="z-index:10">
|
|
<q-icon name="error" color="red" size="12px"></q-icon>
|
|
</div>
|
|
|
|
<template v-if="canWork(date)">
|
|
<div v-for="code in getShifts(agent, date)" :key="code"
|
|
class="shift-badge border"
|
|
:class="['bg-' + getShiftColor(code) + '-1', 'text-' + getShiftColor(code) + '-9', 'border-' + getShiftColor(code) + '-2']">
|
|
{{ getShiftLabel(code) }}
|
|
</div>
|
|
</template>
|
|
|
|
<div class="absolute-bottom-right q-pa-xs row no-wrap" style="gap: 2px">
|
|
<q-icon v-if="(agent.id + i) % 11 === 0" name="chat_bubble_outline" size="8px" color="grey-4"></q-icon>
|
|
<q-icon v-if="(agent.id + i) % 13 === 0" name="info_outline" size="8px" color="orange-3"></q-icon>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`,
|
|
setup(props) {
|
|
|
|
const canWork = (date) => {
|
|
return props.weekendsAreWorkingDays || !ValidationUtils.isWeekend(date);
|
|
};
|
|
|
|
const getShifts = (agent, date) => {
|
|
return store.getAgentShifts(agent.id, date);
|
|
};
|
|
|
|
const getShiftColor = (shiftCode) => {
|
|
// Map codes to colors
|
|
const map = {
|
|
'm': 'green',
|
|
'a': 'blue',
|
|
'e': 'pink',
|
|
't': 'orange',
|
|
'v': 'purple'
|
|
};
|
|
return map[shiftCode] || 'grey';
|
|
};
|
|
|
|
const getShiftLabel = (shiftCode) => {
|
|
const map = {
|
|
'm': 'MORNING',
|
|
'a': 'HOTLINE', // As per original design calls Afternoon 'HOTLINE'
|
|
'e': 'EOD',
|
|
't': 'TRAINING',
|
|
'v': 'VACATION'
|
|
};
|
|
return map[shiftCode] || shiftCode;
|
|
};
|
|
|
|
const getCellClasses = (agent, date, i) => {
|
|
const shifts = getShifts(agent, date);
|
|
const hasConflict = !!ValidationUtils.hasConflict(shifts);
|
|
|
|
return [
|
|
props.isCompact ? 'cell-compact' : '',
|
|
(agent.id + i) === 42 ? 'bg-amber-1' : '', // Keep random lock for demo
|
|
!canWork(date) ? 'bg-weekend cursor-not-allowed' : 'cursor-pointer',
|
|
hasConflict ? 'bg-red-1' : ''
|
|
];
|
|
};
|
|
|
|
const handleCellClick = (agent, date) => {
|
|
if (!canWork(date)) return;
|
|
store.openAssignment(agent, date);
|
|
};
|
|
|
|
const openProfile = (agent) => {
|
|
store.openProfile(agent);
|
|
};
|
|
|
|
return {
|
|
getCellClasses,
|
|
handleCellClick,
|
|
openProfile,
|
|
canWork,
|
|
getShifts,
|
|
getShiftColor,
|
|
getShiftLabel,
|
|
ValidationUtils
|
|
};
|
|
}
|
|
};
|