import { ref, computed, nextTick } from 'https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js'; import { useQuasar } from 'https://cdn.jsdelivr.net/npm/quasar@2.16.0/dist/quasar.umd.prod.js'; import { usePlannerState } from '../../services/planner-state-service.js'; import { HUBS } from '../../services/data-constants.js'; export default { name: 'PlannerGrid', emits: ['toggle-filter-drawer'], setup(props, { emit }) { const { state, methods, getters } = usePlannerState(); const $q = useQuasar(); const viewport = ref(null); const dateMenu = ref(false); const proxyDate = ref(null); const gridStyles = computed(() => ({ '--h-eod': state.showEodTargets ? '42px' : '0px', '--h-status': state.showAvailability ? '34px' : '0px' })); const isFilterActive = computed(() => state.filterRoles.length > 0 || state.filterSkills.length > 0 || state.activeDept !== 'All' || state.activeHub !== 'All' || (state.search && state.search.length > 0) || state.filterByAvailability); const activeFilterCount = computed(() => { let count = 0; if (state.search && state.search.length > 0) count++; if (state.activeDept !== 'All') count++; if (state.activeHub !== 'All') count++; if (state.filterRoles.length > 0) count++; if (state.filterSkills.length > 0) count++; if (state.filterByAvailability) count++; return count; }); const flattenedList = computed(() => { const result = []; const list = [...getters.filteredAgents.value]; const keys = state.groupingSelection; const getLabel = (key, value) => { if (key === 'hub') return HUBS.find(h => h.id === value)?.name || value; if (key === 'dept') return value.toUpperCase() + ' DIVISION'; if (key === 'role') return value + 's'; return value; }; if (keys.length === 0) return list.map(a => ({ type: 'agent', data: a, id: a.id })); list.sort((a, b) => { for (const key of keys) { if (a[key] < b[key]) return -1; if (a[key] > b[key]) return 1; } return 0; }); const currentValues = keys.map(() => null); list.forEach(agent => { let changedLevel = -1; for (let i = 0; i < keys.length; i++) { if (agent[keys[i]] !== currentValues[i]) { changedLevel = i; break; } } if (changedLevel !== -1) { for (let i = changedLevel; i < keys.length; i++) { const key = keys[i]; const val = agent[key]; currentValues[i] = val; result.push({ type: i === 0 ? 'header-l1' : 'header-l2', label: getLabel(key, val), id: `hdr-${key}-${val}-${Math.random()}` }); } } result.push({ type: 'agent', data: agent, id: agent.id }); }); return result; }); const getCellClass = (agentId, date) => { const isRow = state.highlightedRowId === agentId; const isCol = state.highlightedDateStr === methods.formatDateForId(date); const isHoverCol = state.crosshairActive && state.hoveredDateStr === methods.formatDateForId(date); const isWknd = methods.isWeekend(date) && !state.weekendsAreWorkingDays; const isLocked = methods.isCellLocked(agentId, date); const classes = []; if (state.isCompact) classes.push('planner-grid-cell-compact'); if (isWknd) classes.push('planner-grid-bg-weekend'); if (isWknd || isLocked) classes.push('cursor-not-allowed'); else classes.push('cursor-pointer'); if (isRow && isCol) classes.push('planner-grid-bg-reading-mode-intersection'); else if (isRow || isCol) classes.push('planner-grid-bg-reading-mode'); if (isHoverCol) classes.push('planner-grid-col-hovered'); return classes.join(' '); }; const applyDateSelection = () => { methods.applyDateSelection(proxyDate.value); dateMenu.value = false; nextTick(() => { if (viewport.value) viewport.value.scrollLeft = 0; }); }; return { state, methods, getters, $q, viewport, gridStyles, isFilterActive, activeFilterCount, flattenedList, getCellClass, dateMenu, proxyDate, syncProxyDate: () => { proxyDate.value = methods.formatDateForId(state.selectedDate || new Date()); }, applyDateSelection, toggleFilterDrawer: () => emit('toggle-filter-drawer'), }; }, template: `
Loading Agents...
EOD Targets
94%
Availability
{{ isFilterActive ? activeFilterCount + ' filters active' : 'Advanced Filters' }}
Holiday: {{ methods.getHoliday(date) }}Event: {{ methods.getSpecialDay(date) }}
{{ date.toLocaleDateString('en-US', {weekday: 'short'}) }}
{{ date.getDate() }}. {{ date.toLocaleDateString('en-US', { month: 'short' }) }}
{{ state.highlightedDateStr === methods.formatDateForId(date) ? 'Turn off column mode' : 'Highlight Column' }}
` };