refactor: centralize shared date/name helpers in utils.js (#12)
New js/utils.js exports toISO, monthPrefix, getWeekday, formatDateDE and buildNameMap. algorithm.js, calendar.js, excel.js and history.js now import these instead of re-implementing ISO construction, weekday math, DD.MM.YYYY formatting and the id→name map inline. Adds tests/utils.test.mjs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
0efb9cb853
commit
fd9870871b
7 files changed
+71
-26
No files matched your search
+8
-7
@@ -2,6 +2,7 @@ import { state, saveState } from './app.js';
|
||||
import { getWorkdays, generatePlan } from './algorithm.js';
|
||||
import { toggleHoliday, toggleClosure, addHistoryEntries, removeHistoryEntry } from './data.js';
|
||||
import { exportSchedule, downloadBlob } from './excel.js';
|
||||
import { toISO, monthPrefix, getWeekday, buildNameMap } from './utils.js';
|
||||
|
||||
const MONTHS = ['Januar','Februar','März','April','Mai','Juni',
|
||||
'Juli','August','September','Oktober','November','Dezember'];
|
||||
@@ -122,7 +123,7 @@ export function renderCalendar() {
|
||||
}
|
||||
const workdays = getWorkdays(currentYear, currentMonth,
|
||||
state.calendar.holidays, state.calendar.companyClosures);
|
||||
const prefix = currentYear + '-' + String(currentMonth).padStart(2, '0');
|
||||
const prefix = monthPrefix(currentYear, currentMonth);
|
||||
// Preserve manual picks for this month; only auto-entries get regenerated.
|
||||
const manualEntries = state.history.filter(h => h.date.startsWith(prefix) && h.manual);
|
||||
const historyWithoutMonth = state.history.filter(h => !h.date.startsWith(prefix));
|
||||
@@ -148,7 +149,7 @@ export function renderCalendar() {
|
||||
}
|
||||
|
||||
function loadPlanFromHistory() {
|
||||
const prefix = currentYear + '-' + String(currentMonth).padStart(2,'0');
|
||||
const prefix = monthPrefix(currentYear, currentMonth);
|
||||
currentPlan = state.history
|
||||
.filter(h => h.date.startsWith(prefix))
|
||||
.map(h => ({ ...h }));
|
||||
@@ -158,7 +159,7 @@ function renderGrid(wrapper, exportBtn) {
|
||||
wrapper.replaceChildren();
|
||||
|
||||
const daysInMonth = new Date(currentYear, currentMonth, 0).getDate();
|
||||
const empNameById = Object.fromEntries(state.employees.map(e => [e.id, e.name]));
|
||||
const empNameById = buildNameMap(state.employees);
|
||||
const updateExportVisibility = () => {
|
||||
exportBtn.style.display = currentPlan.length > 0 ? 'inline-block' : 'none';
|
||||
};
|
||||
@@ -166,8 +167,8 @@ function renderGrid(wrapper, exportBtn) {
|
||||
// Build one day cell. Self-contained so a change to a single day re-renders
|
||||
// just that cell (cell.replaceWith) instead of rebuilding the whole grid.
|
||||
function makeDayCell(d) {
|
||||
const iso = currentYear + '-' + String(currentMonth).padStart(2,'0') + '-' + String(d).padStart(2,'0');
|
||||
const wdNum = (() => { const x = new Date(iso + 'T12:00:00Z').getUTCDay(); return x === 0 ? 7 : x; })();
|
||||
const iso = toISO(currentYear, currentMonth, d);
|
||||
const wdNum = getWeekday(iso);
|
||||
const isWeekend = wdNum >= 6;
|
||||
const isHoliday = state.calendar.holidays.includes(iso);
|
||||
const isClosure = state.calendar.companyClosures.includes(iso);
|
||||
@@ -291,8 +292,8 @@ function renderGrid(wrapper, exportBtn) {
|
||||
bodyGrid.className = 'calendar-body-grid';
|
||||
|
||||
// Offset empty cells before first day
|
||||
const firstISO = currentYear + '-' + String(currentMonth).padStart(2,'0') + '-01';
|
||||
const firstWD = (() => { const d = new Date(firstISO + 'T12:00:00Z').getUTCDay(); return d === 0 ? 7 : d; })();
|
||||
const firstISO = toISO(currentYear, currentMonth, 1);
|
||||
const firstWD = getWeekday(firstISO);
|
||||
for (let i = 1; i < firstWD; i++) {
|
||||
const empty = document.createElement('div');
|
||||
empty.className = 'cal-day empty-cell';
|
||||
|
||||
Reference in new issue
Block a user