Add timer tags and optional start description

Buttons can carry a Timer Tags select value and prompt for an optional
description before starting. Tag options and the prompt toggle are
configured per-button in the property inspector; startTimer writes the
tag to the Timer Tags select property and the description to the
Description rich_text property when set.
This commit is contained in:
pdmarf
2026-10-08 09:48:03 +01:00
parent 0956b28864
commit c50ee5e822
5 changed files with 201 additions and 39 deletions
@@ -58,6 +58,11 @@
padding-left: 98px;
line-height: 1.4;
}
.info-icon {
color: #888;
font-size: 13px;
cursor: help;
}
.divider {
border: none;
border-top: 1px solid #333;
@@ -142,6 +147,22 @@
<option value="">Loading projects…</option>
</select>
</div>
<div class="row">
<label>Ask description (optional)</label>
<input type="checkbox" id="askDescription" style="flex: none; width: auto;">
<span class="info-icon" title="Prompt for a description when starting this button's timer.">ⓘ</span>
</div>
<div class="row">
<label>Use tag (Pete only)</label>
<input type="checkbox" id="tagEnabled" style="flex: none; width: auto;">
</div>
<div class="row" id="tagRow">
<label></label>
<select id="tagSelect">
<option value="">— No tag —</option>
</select>
</div>
<p class="hint" id="tagHint">Recorded as the entry's Tag in Notion and shown on the button.</p>
<p id="statusText"></p>
<p id="versionText"></p>
@@ -163,6 +184,7 @@
var credConfigured = false;
var globalUserId = "";
var cachedUsers = [];
var cachedTags = [];
function setStatus(msg, cls) {
var el = document.getElementById("statusText");
@@ -224,11 +246,39 @@
});
}
function populateTags(tags) {
cachedTags = tags;
var sel = document.getElementById("tagSelect");
sel.innerHTML = '<option value="">— No tag —</option>';
var values = tags.slice();
// A tag saved on this button before it existed as a Notion select option
// (or since removed there) must still show up, selected, instead of
// silently reverting to "No tag".
if (currentSettings.tag && values.indexOf(currentSettings.tag) === -1) {
values.push(currentSettings.tag);
}
values.forEach(function(t) {
var opt = document.createElement("option");
opt.value = t;
opt.textContent = t;
if (currentSettings.tag === t) opt.selected = true;
sel.appendChild(opt);
});
}
function setTagRowVisible(visible) {
document.getElementById("tagRow").style.display = visible ? "" : "none";
document.getElementById("tagHint").style.display = visible ? "" : "none";
}
function save() {
var sel = document.getElementById("projectSelect");
var opt = sel.options[sel.selectedIndex];
currentSettings.projectId = sel.value;
currentSettings.projectName = sel.value ? opt.textContent.trim() : "";
currentSettings.tagEnabled = document.getElementById("tagEnabled").checked;
currentSettings.tag = currentSettings.tagEnabled ? document.getElementById("tagSelect").value : "";
currentSettings.askDescription = document.getElementById("askDescription").checked;
$PI.setSettings(currentSettings);
$PI.sendToPlugin({ event: "saveSettings", settings: currentSettings });
setStatus(currentSettings.projectName ? "Saved: " + currentSettings.projectName : "", "");
@@ -255,10 +305,19 @@
$PI.onConnected(function(jsn) {
currentSettings = jsn.actionInfo.payload.settings || {};
document.getElementById("tagEnabled").checked = !!currentSettings.tagEnabled;
setTagRowVisible(!!currentSettings.tagEnabled);
document.getElementById("askDescription").checked = !!currentSettings.askDescription;
$PI.getSettings();
$PI.getGlobalSettings();
document.getElementById("projectSelect").addEventListener("change", save);
document.getElementById("tagEnabled").addEventListener("change", function() {
setTagRowVisible(this.checked);
save();
});
document.getElementById("tagSelect").addEventListener("change", save);
document.getElementById("askDescription").addEventListener("change", save);
document.getElementById("notionToken").addEventListener("input", scheduleCredSave);
document.getElementById("userId").addEventListener("change", saveCredentials);
document.getElementById("updateBtn").addEventListener("click", function() {
@@ -296,6 +355,10 @@
if (currentSettings.projectId && sel.options.length > 1) {
sel.value = currentSettings.projectId;
}
document.getElementById("tagEnabled").checked = !!currentSettings.tagEnabled;
setTagRowVisible(!!currentSettings.tagEnabled);
populateTags(cachedTags);
document.getElementById("askDescription").checked = !!currentSettings.askDescription;
if (currentSettings.activeEntryId) {
setStatus("⏱ Timer running", "running");
}
@@ -313,6 +376,9 @@
if (payload.users) {
populateUsers(payload.users, globalUserId);
}
if (payload.tags) {
populateTags(payload.tags);
}
if (payload.error) {
setStatus(payload.error, "error");
} else {