v0.6.3: UI wording -> "messages"; folder spacing + tint
- User-facing "artifact(s)" -> "messages" across the UI (feed count, empty states, preview, About, Storage). Model/API/skill keep "artifact" internally — no agent-contract change. - Sidebar: Keep/Deleted folders get spacing between them and share the "All sources" bold + blue-tint styling (special folders). - Fix: About page points to Settings -> API Keys (was stale "Settings -> Account / API token"). 152 tests pass; inline JS re-validated with node --check. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c1be2face7
commit
f6f607f476
7 changed files with 52 additions and 32 deletions
17
CHANGELOG.md
17
CHANGELOG.md
|
|
@ -9,6 +9,20 @@ former name, "Daybook".)
|
|||
|
||||
_Nothing yet._
|
||||
|
||||
## [0.6.3] — 2026-09-07
|
||||
|
||||
### Changed
|
||||
- **User-facing wording: "artifact(s)" → "messages"** throughout the UI (feed
|
||||
count, empty states, preview, About, Storage). The model, API
|
||||
(`/api/artifacts`), and posting skill keep "artifact" as the internal term —
|
||||
no contract change for agents.
|
||||
- Sidebar: the Keep/Deleted folders now have spacing between them and share the
|
||||
"All sources" bold+blue-tint styling (they're special folders).
|
||||
|
||||
### Fixed
|
||||
- About page now points to Settings → API Keys (was the stale "Settings →
|
||||
Account / personal API token").
|
||||
|
||||
## [0.6.2] — 2026-09-07
|
||||
|
||||
### Changed
|
||||
|
|
@ -221,7 +235,8 @@ First tagged release.
|
|||
- Dockerised (Gunicorn + whitenoise), SQLite, `git`-based deploy with a
|
||||
runbook (`deploy/cloud_agent_deploy.md`) and health check.
|
||||
|
||||
[Unreleased]: https://git.cygnus.systems/peter/daybook/compare/v0.6.2...HEAD
|
||||
[Unreleased]: https://git.cygnus.systems/peter/daybook/compare/v0.6.3...HEAD
|
||||
[0.6.3]: https://git.cygnus.systems/peter/daybook/compare/v0.6.2...v0.6.3
|
||||
[0.6.2]: https://git.cygnus.systems/peter/daybook/compare/v0.6.1...v0.6.2
|
||||
[0.6.1]: https://git.cygnus.systems/peter/daybook/compare/v0.6.0...v0.6.1
|
||||
[0.6.0]: https://git.cygnus.systems/peter/daybook/compare/v0.5.1...v0.6.0
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Single source of truth for the app version. Bump this, commit, then tag the
|
||||
# commit `vX.Y.Z` and deploy. Surfaced on Settings -> About and in
|
||||
# GET /api/capabilities ("version").
|
||||
__version__ = "0.6.2"
|
||||
__version__ = "0.6.3"
|
||||
|
|
|
|||
|
|
@ -1139,20 +1139,25 @@ kbd {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
padding: 0.4rem 0.6rem 0.2rem;
|
||||
gap: 0.25rem; /* space Keep / Deleted apart */
|
||||
padding: 0.4rem 0.6rem 0.3rem;
|
||||
}
|
||||
|
||||
/* "All sources" — the primary entry, visually distinct from individual sources:
|
||||
bold, with a subtle blue tint (works over both light and dark surfaces). */
|
||||
.all-sources-link {
|
||||
/* "Special" sidebar entries — "All sources" and the Keep/Deleted folders —
|
||||
share a distinct look (bold + subtle blue tint) to set them apart from the
|
||||
individual sources. */
|
||||
.all-sources-link,
|
||||
.folder-link {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.all-sources-link:not(.selected) {
|
||||
.all-sources-link:not(.selected),
|
||||
.folder-link:not(.selected) {
|
||||
background: rgba(74, 110, 168, 0.14);
|
||||
}
|
||||
|
||||
.all-sources-link:not(.selected):hover {
|
||||
.all-sources-link:not(.selected):hover,
|
||||
.folder-link:not(.selected):hover {
|
||||
background: rgba(74, 110, 168, 0.22);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
{% if selected_folder == 'deleted' %}
|
||||
<button type="button" class="empty-trash-button" data-empty-trash>Empty Trash</button>
|
||||
{% else %}
|
||||
<span>{{ artifacts|length }} artifact{{ artifacts|length|pluralize }}</span>
|
||||
<span>{{ artifacts|length }} message{{ artifacts|length|pluralize }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
{% include "artifacts/_day_groups.html" with has_more=older_count next_before=window_start|date:"Y-m-d" %}
|
||||
{% else %}
|
||||
<div class="empty compact">
|
||||
<h3>No artifacts</h3>
|
||||
<h3>No messages</h3>
|
||||
<p>Nothing in the last {{ 7 }} days for these filters.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
@ -94,7 +94,7 @@
|
|||
<section class="preview-pane">
|
||||
<header class="pane-bar preview-actions" data-actions>
|
||||
<div class="preview-title" data-preview-title {% if selected_artifact %}title="{{ selected_artifact.title }}"{% endif %}>
|
||||
{% if selected_artifact %}{{ selected_artifact.title }}{% else %}No artifact loaded{% endif %}
|
||||
{% if selected_artifact %}{{ selected_artifact.title }}{% else %}No message loaded{% endif %}
|
||||
</div>
|
||||
<nav class="view-toggle" aria-label="Preview mode">
|
||||
<a class="{% if selected_view == 'rendered' %}selected{% endif %}{% if not selected_artifact %} disabled{% endif %}" href="{% if selected_artifact %}{{ rendered_url }}{% else %}#{% endif %}" data-view="rendered" {% if not selected_artifact %}aria-disabled="true"{% endif %}>Rendered</a>
|
||||
|
|
@ -124,8 +124,8 @@
|
|||
<img class="preview-image" src="{% url 'artifact' selected_artifact.id %}" alt="{{ selected_artifact.title }}">
|
||||
{% elif selected_artifact.kind == "binary" %}
|
||||
<div class="empty preview-empty">
|
||||
<h2>Binary Artifact</h2>
|
||||
<p>This artifact type cannot be previewed inline yet.</p>
|
||||
<h2>Binary Message</h2>
|
||||
<p>This message type cannot be previewed inline yet.</p>
|
||||
<p><a href="{% url 'artifact' selected_artifact.id %}">Open or download it</a>.</p>
|
||||
</div>
|
||||
{% else %}
|
||||
|
|
@ -135,10 +135,10 @@
|
|||
{% else %}
|
||||
<div class="empty preview-empty">
|
||||
{% if artifacts %}
|
||||
<h2>No artifact loaded</h2>
|
||||
<p>Press <kbd>Right Arrow</kbd> or select an artifact from the middle column to preview it.</p>
|
||||
<h2>No message loaded</h2>
|
||||
<p>Press <kbd>Right Arrow</kbd> or select a message from the middle column to preview it.</p>
|
||||
{% else %}
|
||||
<h2>No artifacts for this day</h2>
|
||||
<h2>No messages for this day</h2>
|
||||
<p>This day is ready for new agent output.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
@ -239,7 +239,7 @@
|
|||
try {
|
||||
await navigator.clipboard.writeText(absoluteUrl);
|
||||
} catch {
|
||||
window.prompt("Copy artifact link", absoluteUrl);
|
||||
window.prompt("Copy message link", absoluteUrl);
|
||||
}
|
||||
const original = button.textContent;
|
||||
button.textContent = "Copied";
|
||||
|
|
@ -348,7 +348,7 @@
|
|||
if (!actions) return;
|
||||
const previewTitle = actions.querySelector("[data-preview-title]");
|
||||
if (previewTitle) {
|
||||
previewTitle.textContent = "No artifact loaded";
|
||||
previewTitle.textContent = "No message loaded";
|
||||
previewTitle.removeAttribute("title");
|
||||
}
|
||||
actions.querySelectorAll("[data-view]").forEach((link) => {
|
||||
|
|
@ -484,7 +484,7 @@
|
|||
const header = document.querySelector(".artifact-sidebar .pane-heading span");
|
||||
if (!header) return;
|
||||
const total = Math.max(0, (parseInt(header.textContent, 10) || 0) + delta);
|
||||
header.textContent = `${total} artifact${total === 1 ? "" : "s"}`;
|
||||
header.textContent = `${total} message${total === 1 ? "" : "s"}`;
|
||||
};
|
||||
|
||||
const bumpFolderCount = (folder, delta) => {
|
||||
|
|
@ -632,7 +632,7 @@
|
|||
: kind === "image"
|
||||
? `<img class="preview-image" src="${source}" alt="${title}">`
|
||||
: kind === "binary"
|
||||
? `<div class="empty preview-empty"><h2>Binary Artifact</h2><p>This artifact type cannot be previewed inline yet.</p><p><a href="${source}">Open or download it</a>.</p></div>`
|
||||
? `<div class="empty preview-empty"><h2>Binary Message</h2><p>This message type cannot be previewed inline yet.</p><p><a href="${source}">Open or download it</a>.</p></div>`
|
||||
: `<iframe class="preview-frame" src="${source}" title="${title}"></iframe>`;
|
||||
|
||||
previewBody.innerHTML = `<div class="preview-frame-wrap">${content}</div>`;
|
||||
|
|
@ -647,7 +647,7 @@
|
|||
}
|
||||
allRows().forEach((candidate) => candidate.classList.remove("selected"));
|
||||
disableActions();
|
||||
previewBody.innerHTML = `<div class="empty preview-empty"><h2>No artifact loaded</h2><p>Press <kbd>Right Arrow</kbd> or select an artifact from the middle column to preview it.</p></div>`;
|
||||
previewBody.innerHTML = `<div class="empty preview-empty"><h2>No message loaded</h2><p>Press <kbd>Right Arrow</kbd> or select a message from the middle column to preview it.</p></div>`;
|
||||
window.history.pushState({}, "", noPreviewUrl());
|
||||
const currentSource = document.querySelector(".source-link.selected");
|
||||
if (currentSource) currentSource.focus({preventScroll: true});
|
||||
|
|
@ -885,7 +885,7 @@
|
|||
const header = document.querySelector(".artifact-sidebar .pane-heading span");
|
||||
if (header) {
|
||||
const total = (parseInt(header.textContent, 10) || 0) + data.count;
|
||||
header.textContent = `${total} artifact${total === 1 ? "" : "s"}`;
|
||||
header.textContent = `${total} message${total === 1 ? "" : "s"}`;
|
||||
}
|
||||
} catch {
|
||||
// ignore; retry next tick
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@
|
|||
</div>
|
||||
|
||||
<p>A self-hosted, multi-user journal where AI agents, scripts, or people
|
||||
publish artifacts — reports, HTML, decks, images, PDFs, JSON, CSV — and each
|
||||
publish messages — reports, HTML, decks, images, PDFs, JSON, CSV — and each
|
||||
logged-in user browses their own time-ordered, label-filterable feed. The
|
||||
server owns IDs, styling, and storage; agents publish content, not files.</p>
|
||||
|
||||
<p class="storage-note">Post to it with a personal API token from
|
||||
Settings → Account; the current API capabilities (including this
|
||||
version) are available at <code>/api/capabilities</code>.</p>
|
||||
<p class="storage-note">Post to it with a personal API key from
|
||||
Settings → API Keys; the current API capabilities (including
|
||||
this version) are available at <code>/api/capabilities</code>.</p>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{% block settings_content %}
|
||||
<h2>Demo Data</h2>
|
||||
<p>Generate one sample artifact of every supported kind (markdown, HTML fragment, full HTML, deck, image, PDF, binary), tagged "demo" and dated today.</p>
|
||||
<p>Generate one sample message of every supported kind (markdown, HTML fragment, full HTML, deck, image, PDF, binary), tagged "demo" and dated today.</p>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<button type="submit">Generate Demo Data</button>
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@
|
|||
</p>
|
||||
|
||||
<ul class="storage-facts">
|
||||
<li>{{ artifact_count }} artifact{{ artifact_count|pluralize }} total</li>
|
||||
<li>{{ artifact_count }} message{{ artifact_count|pluralize }} total</li>
|
||||
<li>{{ kept_count }} kept ({{ kept_bytes|filesizeformat }}) — never auto-deleted</li>
|
||||
</ul>
|
||||
|
||||
<p class="storage-note">
|
||||
When your quota fills, the oldest <strong>unkept</strong> artifacts are deleted
|
||||
automatically to make room for new ones. Click <strong>Keep</strong> on an artifact
|
||||
to protect it. If the quota is full of kept artifacts, new posts are rejected until
|
||||
When your quota fills, the oldest <strong>unkept</strong> messages are deleted
|
||||
automatically to make room for new ones. Click <strong>Keep</strong> on a message
|
||||
to protect it. If the quota is full of kept messages, new posts are rejected until
|
||||
you free space.
|
||||
</p>
|
||||
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
<h3>Admin</h3>
|
||||
<ul class="storage-facts">
|
||||
<li>Total quota allocated across all users: <strong>{{ total_allocated|filesizeformat }}</strong></li>
|
||||
<li>Free space on the artifact disk: <strong>{{ disk_free|filesizeformat }}</strong></li>
|
||||
<li>Free space on the storage disk: <strong>{{ disk_free|filesizeformat }}</strong></li>
|
||||
</ul>
|
||||
{% if total_allocated > disk_free %}
|
||||
<p class="storage-warning">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue