enhance: integrated UI with visual loading feedback

- Integrate file upload controls with status display for cleaner UX
- Add dark grey internal styling vs. dark green external theme
- Create enhanced SVG template with prominent month indicators
- Improve file loading error detection and user guidance
- Add visual confirmation system for external resource loading
- Update generator to support enhanced template styling
- Fix CSV/template loading context binding issues

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-19 00:20:22 +01:00
parent fdb3ab2044
commit 02bcf69096
5 changed files with 703 additions and 104 deletions

View File

@@ -45,8 +45,22 @@ window.timelineGenerator = {
months.forEach((m, i) => {
const x = left + i * monthWidth;
const label = m.toLocaleString("de-DE", { month: "short", year: "2-digit" });
monthGraphics += `<line x1="${x}" y1="${gridTop}" x2="${x}" y2="${gridBottom}" stroke="#E3E8EF" />`;
monthGraphics += `<text x="${x + 4}" y="${monthLabelY}" fill="#5C6B7A" font-size="12">${label}</text>`;
// Enhanced styling when using external template
if (template && template.includes('Enhanced')) {
// More prominent month indicators for external template
monthGraphics += `<line x1="${x}" y1="${gridTop}" x2="${x}" y2="${gridBottom}" stroke="#4a9b6b" stroke-width="2" opacity="0.6" />`;
monthGraphics += `<rect x="${x-30}" y="${monthLabelY-20}" width="60" height="25" fill="#2d8659" opacity="0.1" rx="4" />`;
monthGraphics += `<text x="${x + 4}" y="${monthLabelY}" fill="#2d8659" font-size="13" font-weight="600">${label}</text>`;
// Add month separator
if (i > 0) {
monthGraphics += `<rect x="${x-1}" y="${gridTop}" width="2" height="${gridBottom-gridTop}" fill="#4a9b6b" opacity="0.3" />`;
}
} else {
// Default styling
monthGraphics += `<line x1="${x}" y1="${gridTop}" x2="${x}" y2="${gridBottom}" stroke="#E3E8EF" />`;
monthGraphics += `<text x="${x + 4}" y="${monthLabelY}" fill="#5C6B7A" font-size="12">${label}</text>`;
}
});
// Helper to compute month index
@@ -60,10 +74,18 @@ window.timelineGenerator = {
laneNames.forEach((laneName, laneIdx) => {
const laneY = top + laneIdx * (laneHeight + laneGap);
// Background band for lane
laneBlocks += `<rect x="40" y="${laneY - 24}" width="${left + months.length * monthWidth}" height="${laneHeight}" fill="#FFFFFF" stroke="#E3E8EF" rx="10" />`;
// Lane label
laneBlocks += `<text x="56" y="${laneY - 4}" fill="#0B1F3B" font-size="14" font-weight="600">${this.escapeXml(laneName)}</text>`;
// Enhanced styling when using external template
if (template && template.includes('Enhanced')) {
// More subtle lane borders for enhanced template
laneBlocks += `<rect x="40" y="${laneY - 24}" width="${left + months.length * monthWidth}" height="${laneHeight}" fill="rgba(255,255,255,0.7)" stroke="#4a9b6b" stroke-width="1" opacity="0.5" rx="8" />`;
// Enhanced lane label
laneBlocks += `<text x="56" y="${laneY - 4}" fill="#2d8659" font-size="14" font-weight="700">${this.escapeXml(laneName)}</text>`;
} else {
// Default lane styling
laneBlocks += `<rect x="40" y="${laneY - 24}" width="${left + months.length * monthWidth}" height="${laneHeight}" fill="#FFFFFF" stroke="#E3E8EF" rx="10" />`;
// Default lane label
laneBlocks += `<text x="56" y="${laneY - 4}" fill="#0B1F3B" font-size="14" font-weight="600">${this.escapeXml(laneName)}</text>`;
}
const laneItems = laneMap.get(laneName).sort((a, b) => a.due - b.due);
laneItems.forEach((it, idx) => {
@@ -72,11 +94,21 @@ window.timelineGenerator = {
const cx = left + clampedMi * monthWidth + monthWidth * 0.5;
const cy = laneY + 10 + idx * 18;
laneBlocks += `<circle cx="${cx}" cy="${cy}" r="5" fill="#0A4D8C" />`;
laneBlocks += `<text x="${cx + 10}" y="${cy + 4}" font-size="12" fill="#0B1F3B">
<tspan class="item-id">${this.escapeXml(it.id || "")}: </tspan>
<tspan class="item-title">${this.escapeXml(it.title || "")}</tspan>
</text>`;
// Enhanced task item styling for external template
if (template && template.includes('Enhanced')) {
laneBlocks += `<circle cx="${cx}" cy="${cy}" r="6" fill="#2d8659" stroke="#4a9b6b" stroke-width="2" />`;
laneBlocks += `<text x="${cx + 12}" y="${cy + 4}" font-size="12" fill="#2d8659" font-weight="500">
<tspan class="item-id">${this.escapeXml(it.id || "")}: </tspan>
<tspan class="item-title" fill="#1e5a3d">${this.escapeXml(it.title || "")}</tspan>
</text>`;
} else {
// Default task item styling
laneBlocks += `<circle cx="${cx}" cy="${cy}" r="5" fill="#0A4D8C" />`;
laneBlocks += `<text x="${cx + 10}" y="${cy + 4}" font-size="12" fill="#0B1F3B">
<tspan class="item-id">${this.escapeXml(it.id || "")}: </tspan>
<tspan class="item-title">${this.escapeXml(it.title || "")}</tspan>
</text>`;
}
});
});