Tag functionality added

This commit is contained in:
Olaf
2026-08-24 20:42:15 +02:00
parent f96a4ab3ad
commit 2810fd914d
16 changed files with 448 additions and 18 deletions
+27
View File
@@ -43,6 +43,33 @@ textarea {
resize: vertical;
}
fieldset {
display: grid;
gap: 8px;
margin: 0;
padding: 10px;
border: 1px solid #cbd5e1;
border-radius: 8px;
}
legend {
padding: 0 4px;
font-weight: 600;
}
.tag-options {
display: flex;
flex-wrap: wrap;
gap: 6px 10px;
}
.tag-options label {
display: flex;
align-items: center;
gap: 4px;
font-weight: 400;
}
.actions {
display: flex;
gap: 8px;
+6
View File
@@ -29,6 +29,12 @@
<textarea id="comment" name="comment" rows="3" placeholder="Your comment"></textarea>
</label>
<fieldset>
<legend>Tags</legend>
<div id="existing-tags" class="tag-options">Loading tags...</div>
<input id="new-tags" type="text" pattern="#[^, ]+(,\s*#[^, ]+)*" placeholder="#new-tag, #another-tag" />
</fieldset>
<div class="actions">
<button type="submit" id="submit-link">Save link</button>
<button type="button" id="open-settings" class="secondary">Settings</button>
+34
View File
@@ -4,6 +4,8 @@ const titleInput = document.getElementById('title');
const urlInput = document.getElementById('url');
const commentInput = document.getElementById('comment');
const openSettingsButton = document.getElementById('open-settings');
const existingTags = document.getElementById('existing-tags');
const newTagsInput = document.getElementById('new-tags');
function setStatus(message, isError = false) {
statusEl.textContent = message;
@@ -21,6 +23,36 @@ async function getSettings() {
return result;
}
async function loadExistingTags() {
const settings = await getSettings();
if (!settings.backendUrl || !settings.accessToken) {
existingTags.textContent = 'Sign in to select existing tags.';
return;
}
const response = await fetch(`${settings.backendUrl}/api/tags`, {
headers: {'Authorization': `Bearer ${settings.accessToken}`},
});
if (!response.ok) {
existingTags.textContent = 'Could not load existing tags.';
return;
}
const tags = await response.json();
existingTags.replaceChildren(...tags.map((tag) => {
const label = document.createElement('label');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.value = tag;
label.append(checkbox, document.createTextNode(` ${tag}`));
return label;
}));
}
function getTags() {
const selected = [...existingTags.querySelectorAll('input:checked')].map((input) => input.value);
const newTags = newTagsInput.value.split(',').map((tag) => tag.trim()).filter((tag) => tag.startsWith('#'));
return [...new Set([...selected, ...newTags])].slice(0, 10);
}
function removeKnownTrackingParams(urlString) {
try {
const url = new URL(urlString);
@@ -72,6 +104,7 @@ async function handleSubmit(event) {
url: removeKnownTrackingParams(urlInput.value),
comment: commentInput.value,
timestamp: new Date().toISOString(),
tags: getTags(),
})
});
@@ -94,3 +127,4 @@ async function handleSubmit(event) {
openSettingsButton.addEventListener('click', () => browser.runtime.openOptionsPage());
form.addEventListener('submit', handleSubmit);
populateCurrentTab();
loadExistingTags();