2025-12-06 01:22:04 +01:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
<html lang="da">
|
|
|
|
|
|
<head>
|
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
|
<title>Calendar V2</title>
|
|
|
|
|
|
<link rel="stylesheet" href="css/calendar-v2.css">
|
|
|
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
|
|
|
<div class="calendar-wrapper">
|
|
|
|
|
|
<swp-calendar>
|
|
|
|
|
|
<swp-calendar-nav>
|
|
|
|
|
|
<swp-nav-button id="btn-simple">Datoer</swp-nav-button>
|
|
|
|
|
|
<swp-nav-button id="btn-resource">Resources</swp-nav-button>
|
|
|
|
|
|
<swp-nav-button id="btn-team">Teams</swp-nav-button>
|
|
|
|
|
|
<swp-week-info>
|
|
|
|
|
|
<swp-week-number>V2</swp-week-number>
|
|
|
|
|
|
<swp-date-range id="view-info"></swp-date-range>
|
|
|
|
|
|
</swp-week-info>
|
|
|
|
|
|
</swp-calendar-nav>
|
|
|
|
|
|
|
|
|
|
|
|
<swp-calendar-container>
|
|
|
|
|
|
<swp-time-axis>
|
2025-12-06 10:52:20 +01:00
|
|
|
|
<swp-header-spacer></swp-header-spacer>
|
2025-12-06 01:22:04 +01:00
|
|
|
|
<swp-time-axis-content id="time-axis"></swp-time-axis-content>
|
|
|
|
|
|
</swp-time-axis>
|
|
|
|
|
|
<swp-grid-container>
|
|
|
|
|
|
<swp-calendar-header></swp-calendar-header>
|
|
|
|
|
|
<swp-scrollable-content>
|
|
|
|
|
|
<swp-time-grid>
|
|
|
|
|
|
<swp-grid-lines></swp-grid-lines>
|
|
|
|
|
|
<swp-day-columns></swp-day-columns>
|
|
|
|
|
|
</swp-time-grid>
|
|
|
|
|
|
</swp-scrollable-content>
|
|
|
|
|
|
</swp-grid-container>
|
|
|
|
|
|
</swp-calendar-container>
|
|
|
|
|
|
</swp-calendar>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<script type="module">
|
|
|
|
|
|
import {
|
|
|
|
|
|
CalendarOrchestrator,
|
|
|
|
|
|
RendererRegistry,
|
|
|
|
|
|
StoreRegistry,
|
|
|
|
|
|
DateRenderer,
|
|
|
|
|
|
ResourceRenderer,
|
|
|
|
|
|
TeamRenderer
|
|
|
|
|
|
} from './js/calendar-v2.js';
|
|
|
|
|
|
|
|
|
|
|
|
const rendererRegistry = new RendererRegistry([
|
|
|
|
|
|
new DateRenderer(),
|
|
|
|
|
|
new ResourceRenderer(),
|
|
|
|
|
|
new TeamRenderer()
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
const mockTeams = [
|
|
|
|
|
|
{ id: 'alpha', name: 'Team Alpha' },
|
|
|
|
|
|
{ id: 'beta', name: 'Team Beta' }
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const mockResources = [
|
|
|
|
|
|
{ id: 'alice', name: 'Alice', teamId: 'alpha' },
|
|
|
|
|
|
{ id: 'bob', name: 'Bob', teamId: 'alpha' },
|
|
|
|
|
|
{ id: 'carol', name: 'Carol', teamId: 'beta' },
|
|
|
|
|
|
{ id: 'dave', name: 'Dave', teamId: 'beta' }
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const storeRegistry = new StoreRegistry();
|
|
|
|
|
|
storeRegistry.register('team', { getByIds: ids => mockTeams.filter(t => ids.includes(t.id)) });
|
|
|
|
|
|
storeRegistry.register('resource', { getByIds: ids => mockResources.filter(r => ids.includes(r.id)) });
|
|
|
|
|
|
|
|
|
|
|
|
const orchestrator = new CalendarOrchestrator(rendererRegistry, storeRegistry);
|
|
|
|
|
|
const container = document.querySelector('swp-calendar-container');
|
|
|
|
|
|
const viewInfo = document.getElementById('view-info');
|
|
|
|
|
|
|
|
|
|
|
|
function getWeekDates() {
|
|
|
|
|
|
const today = new Date();
|
|
|
|
|
|
const mon = new Date(today);
|
|
|
|
|
|
mon.setDate(today.getDate() - today.getDay() + 1);
|
|
|
|
|
|
return Array.from({ length: 5 }, (_, i) => {
|
|
|
|
|
|
const d = new Date(mon);
|
|
|
|
|
|
d.setDate(mon.getDate() + i);
|
|
|
|
|
|
return d.toISOString().split('T')[0];
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const dates = getWeekDates();
|
|
|
|
|
|
|
|
|
|
|
|
const views = {
|
|
|
|
|
|
simple: {
|
|
|
|
|
|
templateId: 'simple',
|
|
|
|
|
|
groupings: [{ type: 'date', values: dates }]
|
|
|
|
|
|
},
|
|
|
|
|
|
resource: {
|
|
|
|
|
|
templateId: 'resource',
|
|
|
|
|
|
groupings: [
|
|
|
|
|
|
{ type: 'resource', values: ['alice', 'bob', 'carol'] },
|
|
|
|
|
|
{ type: 'date', values: dates.slice(0, 3) }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
team: {
|
|
|
|
|
|
templateId: 'team',
|
|
|
|
|
|
groupings: [
|
|
|
|
|
|
{ type: 'team', values: ['alpha', 'beta'] },
|
|
|
|
|
|
{ type: 'resource', values: ['alice', 'bob', 'carol', 'dave'], parentKey: 'teamId' },
|
|
|
|
|
|
{ type: 'date', values: dates.slice(0, 3) }
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
function generateTimeAxis() {
|
|
|
|
|
|
const el = document.getElementById('time-axis');
|
|
|
|
|
|
el.innerHTML = Array.from({ length: 15 }, (_, i) =>
|
|
|
|
|
|
`<swp-hour-marker>${(6 + i).toString().padStart(2, '0')}:00</swp-hour-marker>`
|
|
|
|
|
|
).join('');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function render(view, label) {
|
|
|
|
|
|
viewInfo.textContent = label;
|
|
|
|
|
|
await orchestrator.render(view, container);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
document.getElementById('btn-simple').onclick = () => render(views.simple, '5 datoer');
|
|
|
|
|
|
document.getElementById('btn-resource').onclick = () => render(views.resource, '3 resources × 3 datoer');
|
|
|
|
|
|
document.getElementById('btn-team').onclick = () => render(views.team, '2 teams × 2 resources × 3 datoer');
|
|
|
|
|
|
|
|
|
|
|
|
generateTimeAxis();
|
|
|
|
|
|
render(views.simple, '5 datoer');
|
|
|
|
|
|
</script>
|
|
|
|
|
|
</body>
|
|
|
|
|
|
</html>
|