Files
abacus-to-kimai-filler/app/app.html
T
2026-10-07 15:53:12 +02:00

172 lines
7.1 KiB
HTML

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Abacus → Kimai</title>
<link rel="icon" href="../icons/icon.svg">
<link rel="stylesheet" href="app.css">
</head>
<body>
<main>
<h1>Abacus → Kimai</h1>
<nav>
<button data-tab="sync" class="active">Sync</button>
<button data-tab="rules">Recurring rules</button>
<button data-tab="settings">Settings</button>
</nav>
<!-- SYNC -->
<section id="tab-sync">
<div class="panel">
<h2>1. Abacus hours</h2>
<p class="muted" id="extract-info">Open MyAbacus, then click the toolbar icon → “Extract hours from this tab”. Or paste below.</p>
<textarea id="days" rows="10" placeholder="2026-10-05 08:00-12:00 13:00-17:24&#10;2026-10-06 8:24"></textarea>
<div class="row" style="margin-top:8px">
<span id="days-summary" class="muted"></span>
</div>
<details style="margin-top:8px">
<summary>Paste raw text from Abacus</summary>
<p class="muted">Select the table in MyAbacus, copy, paste here. Parsed with the options from Settings.</p>
<textarea id="raw" rows="6"></textarea>
<button id="parse-raw" style="margin-top:6px">Convert → days</button>
</details>
<details style="margin-top:8px">
<summary>Raw text read during last extraction</summary>
<pre id="raw-last" class="muted"></pre>
</details>
</div>
<div class="panel">
<h2>2. Plan</h2>
<div class="row">
<label>From <input type="date" id="from"></label>
<label>To <input type="date" id="to"></label>
<button id="build" class="primary">Compare with Kimai &amp; plan</button>
<span id="plan-status" class="muted"></span>
</div>
</div>
<div class="panel hidden" id="plan-panel">
<table>
<thead><tr><th><input type="checkbox" id="check-all" checked></th><th>Day</th><th>Abacus</th><th>Kimai now</th><th>To create</th><th>Entries</th><th>Status</th></tr></thead>
<tbody id="plan-body"></tbody>
</table>
<div class="row" style="margin-top:12px">
<button id="create" class="primary">Create entries in Kimai</button>
<span id="create-status" class="muted"></span>
</div>
</div>
</section>
<!-- RULES -->
<section id="tab-rules" class="hidden">
<div class="panel">
<h2 id="rule-form-title">New rule</h2>
<p class="muted">Leave <b>hours</b> empty to make it the “remainder” rule for those days (instead of the default project).</p>
<div class="row">
<label>Name <input id="r-name" placeholder="Weekly meeting"></label>
<label>Hours <input id="r-hours" size="6" placeholder="1 / 1:30"></label>
<label>Start time <input id="r-start" type="time"></label>
<label class="inline"><input type="checkbox" id="r-enabled" checked> enabled</label>
</div>
<div class="row" style="margin-top:8px">
<div class="weekdays" id="r-weekdays"></div>
</div>
<div class="row" style="margin-top:8px">
<label>Project <select id="r-project"></select></label>
<label>Activity <select id="r-activity"></select></label>
<label style="flex:1">Description <input id="r-desc"></label>
</div>
<div class="row" style="margin-top:8px">
<label>Every N weeks <input id="r-every" type="number" min="1" value="1" style="width:70px"></label>
<label>Week anchor <input id="r-anchor" type="date"></label>
<label>Valid from <input id="r-from" type="date"></label>
<label>Valid to <input id="r-to" type="date"></label>
</div>
<div class="row" style="margin-top:12px">
<button id="r-save" class="primary">Save rule</button>
<button id="r-cancel">Clear</button>
<span id="r-status" class="muted"></span>
</div>
</div>
<div class="panel">
<table>
<thead><tr><th>On</th><th>Name</th><th>When</th><th>Hours</th><th>Project / Activity</th><th></th></tr></thead>
<tbody id="rules-body"></tbody>
</table>
</div>
</section>
<!-- SETTINGS -->
<section id="tab-settings" class="hidden">
<div class="panel">
<h2>Kimai</h2>
<div class="row">
<label style="flex:1">URL <input id="s-url" placeholder="https://kimai.example.com"></label>
<label>Auth
<select id="s-auth">
<option value="bearer">API token (Kimai 2)</option>
<option value="legacy">Username + API password (legacy)</option>
</select>
</label>
<label id="s-user-wrap">Username <input id="s-user"></label>
<label>Token <input id="s-token" type="password"></label>
<button id="s-test">Test</button>
</div>
<p id="s-test-status" class="muted"></p>
</div>
<div class="panel">
<h2>Defaults</h2>
<p class="muted">Whatever is not covered by a rule goes here.</p>
<div class="row">
<label>Project <select id="s-project"></select></label>
<label>Activity <select id="s-activity"></select></label>
<label style="flex:1">Description <input id="s-desc"></label>
<button id="s-reload">Reload projects</button>
</div>
<div class="row" style="margin-top:8px">
<label>Tags <input id="s-tags"></label>
<label>Day start (when Abacus has only totals) <input id="s-daystart" type="time"></label>
<label class="inline"><input type="checkbox" id="s-skip"> skip a rule if an entry with the same project/activity already exists that day</label>
</div>
</div>
<div class="panel">
<h2>Abacus extraction</h2>
<div class="row">
<label style="flex:1">Row CSS selector <input id="p-selector"></label>
<label>Time mode
<select id="p-mode">
<option value="auto">auto (ranges, else duration)</option>
<option value="ranges">ranges “08:00 - 12:00”</option>
<option value="pairs">pairs “08:00 12:00” (in/out columns)</option>
<option value="duration">duration only</option>
</select>
</label>
<label>Duration column (0 = first, -1 = last) <input id="p-index" type="number" style="width:70px"></label>
<label>Same day on several rows
<select id="p-same">
<option value="sum">sum</option>
<option value="max">max</option>
<option value="last">last</option>
</select>
</label>
<label>Year for “dd.mm.” dates <input id="p-year" placeholder="current" style="width:80px"></label>
</div>
</div>
<div class="row">
<button id="s-save" class="primary">Save settings</button>
<button id="s-export">Export config</button>
<label class="inline"><button id="s-import-btn">Import config</button><input type="file" id="s-import" accept=".json" class="hidden"></label>
<span id="s-status" class="muted"></span>
</div>
</section>
</main>
<script src="../lib/util.js"></script>
<script src="../lib/parse.js"></script>
<script src="../lib/planner.js"></script>
<script src="../lib/kimai.js"></script>
<script src="../lib/store.js"></script>
<script src="app.js"></script>
</body>
</html>