Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to CV Manager will be documented in this file.

Format follows [Keep a Changelog](https://keepachangelog.com/), versioning follows [Semantic Versioning](https://semver.org/).

## [1.13.0] - 2026-03-03

### Added
- Timeline branching toggle in Settings > Advanced — allows disabling the branch visualization for overlapping experiences, rendering a flat timeline instead (enabled by default)

## [1.12.3] - 2026-03-03

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cv-manager",
"version": "1.12.3",
"version": "1.13.0",
"description": "Professional CV Management System",
"main": "src/server.js",
"scripts": {
Expand Down
12 changes: 12 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,18 @@ <h3 class="modal-title" data-i18n="settings.title">Settings</h3>
</label>
</div>

<!-- Timeline Branching Setting -->
<div class="settings-option">
<div class="settings-option-info">
<div class="settings-option-title" data-i18n="settings.advanced.timeline_branching">Timeline: Branching</div>
<div class="settings-option-desc" data-i18n="settings.advanced.timeline_branching_desc">Show overlapping experiences as branches; disable for a flat timeline</div>
</div>
<label class="toggle-switch">
<input type="checkbox" id="settingTimelineBranching" checked>
<span class="toggle-slider"></span>
</label>
</div>

<!-- Search Engine Indexing (Robots Meta) Setting -->
<div class="settings-option" style="align-items: flex-start;">
<div class="settings-option-info">
Expand Down
16 changes: 14 additions & 2 deletions public/shared/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -1941,7 +1941,12 @@ async function loadPublicSettings() {
const timelineYearOnlySetting = await api('/api/settings/timelineYearOnly');
const timelineYearOnlyEl = document.getElementById('settingTimelineYearOnly');
if (timelineYearOnlyEl) timelineYearOnlyEl.checked = timelineYearOnlySetting.value === 'true';


// Load timeline branching setting (default: enabled)
const timelineBranchingSetting = await api('/api/settings/timelineBranching');
const timelineBranchingEl = document.getElementById('settingTimelineBranching');
if (timelineBranchingEl) timelineBranchingEl.checked = timelineBranchingSetting.value !== 'false';

// Load robots meta setting
const robotsMeta = await api('/api/settings/robotsMeta');
const robotsEl = document.getElementById('settingRobotsMeta');
Expand Down Expand Up @@ -2210,7 +2215,14 @@ async function saveSettingsSectionOrder() {
await api('/api/settings/timelineYearOnly', { method: 'PUT', body: { value: timelineYearOnlyEl.checked.toString() } });
timelineYearOnly = timelineYearOnlyEl.checked;
}


// Also save timeline branching
const timelineBranchingEl = document.getElementById('settingTimelineBranching');
if (timelineBranchingEl) {
await api('/api/settings/timelineBranching', { method: 'PUT', body: { value: timelineBranchingEl.checked.toString() } });
timelineBranching = timelineBranchingEl.checked;
}

// Also save robots meta
const robotsMetaEl = document.getElementById('settingRobotsMeta');
if (robotsMetaEl) {
Expand Down
2 changes: 2 additions & 0 deletions public/shared/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@
"settings.advanced.date_year_only": "2020 (nur Jahr)",
"settings.advanced.timeline_years": "Zeitleiste: Nur Jahre",
"settings.advanced.timeline_years_desc": "Nur Jahre (JJJJ) in der Zeitleiste anzeigen, unabhängig vom Datumsformat",
"settings.advanced.timeline_branching": "Zeitleiste: Verzweigung",
"settings.advanced.timeline_branching_desc": "Überlappende Erfahrungen als Verzweigungen anzeigen; deaktivieren für eine flache Zeitleiste",
"settings.advanced.seo_indexing": "Suchmaschinenindexierung",
"settings.advanced.seo_indexing_desc": "Steuern Sie, wie Suchmaschinen Ihre öffentliche Lebenslaufseite behandeln",
"settings.advanced.index_follow": "Indexieren, Folgen",
Expand Down
2 changes: 2 additions & 0 deletions public/shared/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@
"settings.advanced.date_year_only": "2020 (year only)",
"settings.advanced.timeline_years": "Timeline: Years Only",
"settings.advanced.timeline_years_desc": "Display only years (YYYY) in the timeline, regardless of date format",
"settings.advanced.timeline_branching": "Timeline: Branching",
"settings.advanced.timeline_branching_desc": "Show overlapping experiences as branches; disable for a flat timeline",
"settings.advanced.seo_indexing": "Search Engine Indexing",
"settings.advanced.seo_indexing_desc": "Control how search engines handle your public CV page",
"settings.advanced.index_follow": "Index, Follow",
Expand Down
2 changes: 2 additions & 0 deletions public/shared/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@
"settings.advanced.date_year_only": "2020 (solo año)",
"settings.advanced.timeline_years": "Línea de tiempo: solo años",
"settings.advanced.timeline_years_desc": "Mostrar solo años (AAAA) en la línea de tiempo, independientemente del formato de fecha",
"settings.advanced.timeline_branching": "Línea de tiempo: Ramificación",
"settings.advanced.timeline_branching_desc": "Mostrar experiencias superpuestas como ramas; desactivar para una línea de tiempo plana",
"settings.advanced.seo_indexing": "Indexación en motores de búsqueda",
"settings.advanced.seo_indexing_desc": "Controla cómo los motores de búsqueda gestionan tu página pública de CV",
"settings.advanced.index_follow": "Indexar, seguir",
Expand Down
2 changes: 2 additions & 0 deletions public/shared/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@
"settings.advanced.date_year_only": "2020 (année uniquement)",
"settings.advanced.timeline_years": "Chronologie : Années uniquement",
"settings.advanced.timeline_years_desc": "Afficher uniquement les années (AAAA) dans la chronologie, quel que soit le format de date",
"settings.advanced.timeline_branching": "Chronologie : Ramification",
"settings.advanced.timeline_branching_desc": "Afficher les expériences qui se chevauchent sous forme de branches ; désactiver pour une chronologie linéaire",
"settings.advanced.seo_indexing": "Indexation par les moteurs de recherche",
"settings.advanced.seo_indexing_desc": "Contrôlez comment les moteurs de recherche gèrent votre page CV publique",
"settings.advanced.index_follow": "Indexer, Suivre",
Expand Down
2 changes: 2 additions & 0 deletions public/shared/i18n/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@
"settings.advanced.date_year_only": "2020 (solo anno)",
"settings.advanced.timeline_years": "Cronologia: solo anni",
"settings.advanced.timeline_years_desc": "Mostra solo gli anni (AAAA) nella cronologia, indipendentemente dal formato data",
"settings.advanced.timeline_branching": "Cronologia: Ramificazione",
"settings.advanced.timeline_branching_desc": "Mostra le esperienze sovrapposte come rami; disattiva per una cronologia lineare",
"settings.advanced.seo_indexing": "Indicizzazione motori di ricerca",
"settings.advanced.seo_indexing_desc": "Controlla come i motori di ricerca gestiscono la tua pagina CV pubblica",
"settings.advanced.index_follow": "Indicizza, Segui",
Expand Down
2 changes: 2 additions & 0 deletions public/shared/i18n/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@
"settings.advanced.date_year_only": "2020 (alleen jaar)",
"settings.advanced.timeline_years": "Tijdlijn: Alleen jaren",
"settings.advanced.timeline_years_desc": "Toon alleen jaren (JJJJ) in de tijdlijn, ongeacht de datumnotatie",
"settings.advanced.timeline_branching": "Tijdlijn: Vertakking",
"settings.advanced.timeline_branching_desc": "Toon overlappende ervaringen als vertakkingen; schakel uit voor een platte tijdlijn",
"settings.advanced.seo_indexing": "Zoekmachine-indexering",
"settings.advanced.seo_indexing_desc": "Bepaal hoe zoekmachines je openbare CV-pagina behandelen",
"settings.advanced.index_follow": "Indexeren, Volgen",
Expand Down
2 changes: 2 additions & 0 deletions public/shared/i18n/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@
"settings.advanced.date_year_only": "2020 (apenas ano)",
"settings.advanced.timeline_years": "Cronologia: Apenas Anos",
"settings.advanced.timeline_years_desc": "Apresentar apenas anos (AAAA) na cronologia, independentemente do formato de data",
"settings.advanced.timeline_branching": "Cronologia: Ramificação",
"settings.advanced.timeline_branching_desc": "Mostrar experiências sobrepostas como ramificações; desativar para uma cronologia linear",
"settings.advanced.seo_indexing": "Indexação por Motores de Busca",
"settings.advanced.seo_indexing_desc": "Controle como os motores de busca tratam a sua página pública de CV",
"settings.advanced.index_follow": "Indexar, Seguir",
Expand Down
2 changes: 2 additions & 0 deletions public/shared/i18n/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@
"settings.advanced.date_year_only": "2020(仅年份)",
"settings.advanced.timeline_years": "时间线:仅显示年份",
"settings.advanced.timeline_years_desc": "在时间线中仅显示年份(YYYY),不受日期格式影响",
"settings.advanced.timeline_branching": "时间线:分支",
"settings.advanced.timeline_branching_desc": "将重叠的经历显示为分支;禁用后显示为平铺时间线",
"settings.advanced.seo_indexing": "搜索引擎索引",
"settings.advanced.seo_indexing_desc": "控制搜索引擎如何处理您的公开简历页面",
"settings.advanced.index_follow": "索引,跟踪链接",
Expand Down
15 changes: 14 additions & 1 deletion public/shared/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ function escapeHtml(text) {
// Global date format setting - loaded from settings API
let dateFormatSetting = 'MMM YYYY'; // default: "Jan 2020"
let timelineYearOnly = true; // default: show years only in timeline
let timelineBranching = true; // default: show branching for overlapping items

const DATE_FORMAT_OPTIONS = [
{ value: 'MMM YYYY', label: 'Jan 2020', example: 'Jan 2020' },
Expand Down Expand Up @@ -260,6 +261,16 @@ async function loadDateFormatSetting(allSettings) {
} catch (err) {
// Use default (false)
}
try {
if (allSettings && allSettings.timelineBranching !== undefined) {
timelineBranching = allSettings.timelineBranching !== 'false';
} else {
const result = await api('/api/settings/timelineBranching');
timelineBranching = result.value !== 'false';
}
} catch (err) {
// Use default (true)
}
}

// Format timeline period - uses year only if setting enabled, otherwise global date format
Expand Down Expand Up @@ -490,7 +501,9 @@ function renderTimelineItems(items, options) {
// Filter out hidden experiences so the timeline is regenerated dynamically
const visibleItems = items.filter(item => item.visible !== false);

let { branches, segments } = computeTimelineBranches(visibleItems);
let { branches, segments } = timelineBranching
? computeTimelineBranches(visibleItems)
: { branches: [], segments: visibleItems.map(item => ({ item, track: 0, branchGroup: null, startNum: parseDateForSort(item.start_date), endNum: item.end_date ? parseDateForSort(item.end_date) : (new Date().getFullYear() * 100 + (new Date().getMonth() + 1)) })) };

const positions = computeTimePositions(segments);

Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"version": "1.12.3",
"version": "1.13.0",
"changelog": "https://github.com/vincentmakes/cv-manager/blob/main/CHANGELOG.md"
}