chore: added editor specs
This commit is contained in:
415
specs/editors.allium
Normal file
415
specs/editors.allium
Normal file
@@ -0,0 +1,415 @@
|
||||
-- allium: 1
|
||||
-- bDS Editor Views
|
||||
-- Scope: UI content area (all waves + extensions)
|
||||
-- Distilled from: PostEditor.tsx, MediaEditor.tsx, Editor.tsx (Dashboard),
|
||||
-- SettingsView.tsx, StyleView.tsx, ChatPanel.tsx, TagsView
|
||||
|
||||
-- Describes the layout and behaviour of each editor view rendered in
|
||||
-- the main content area when a tab is active (or dashboard when no tab).
|
||||
-- Tab routing is in tabs.allium. Sidebar navigation is in sidebar_views.allium.
|
||||
|
||||
use "./tabs.allium" as tabs
|
||||
use "./post.allium" as post
|
||||
use "./media.allium" as media
|
||||
use "./i18n.allium" as i18n
|
||||
|
||||
-- ─── Dashboard (no tab active) ───────────────────────────────
|
||||
|
||||
-- Shown as default/welcome view when no entity tab is active.
|
||||
-- Single centered column.
|
||||
|
||||
value Dashboard {
|
||||
title: String
|
||||
subtitle: String
|
||||
stats: DashboardStats
|
||||
timeline: DashboardTimeline
|
||||
tag_cloud: DashboardTagCloud
|
||||
category_cloud: DashboardCategoryCloud
|
||||
recent_posts: List<DashboardRecentPost>
|
||||
}
|
||||
|
||||
value DashboardStats {
|
||||
-- Three stat cards side by side:
|
||||
total_posts: Integer
|
||||
published_count: Integer
|
||||
draft_count: Integer
|
||||
archived_count: Integer -- shown only if > 0
|
||||
media_count: Integer
|
||||
image_count: Integer
|
||||
total_media_size: String -- formatted B/KB/MB/GB
|
||||
tag_count: Integer
|
||||
category_count: Integer
|
||||
}
|
||||
|
||||
value DashboardTimeline {
|
||||
-- Bar chart of posts over time
|
||||
-- Last 12 months that have data
|
||||
-- Each bar: count label on top, month abbreviation + year below
|
||||
-- Bar height proportional to max count
|
||||
months: List<DashboardTimelineMonth>
|
||||
}
|
||||
|
||||
value DashboardTimelineMonth {
|
||||
label: String -- month abbreviation
|
||||
year: Integer
|
||||
count: Integer
|
||||
}
|
||||
|
||||
value DashboardTagCloud {
|
||||
-- Up to 40 tags, sorted alphabetically
|
||||
-- Font size scaled 11px-22px based on post count
|
||||
-- Tags with colours get coloured background with contrast text
|
||||
-- Hover title shows post count
|
||||
-- "and N more" text if > 40 tags
|
||||
tags: List<DashboardTag>
|
||||
overflow_count: Integer?
|
||||
}
|
||||
|
||||
value DashboardTag {
|
||||
name: String
|
||||
count: Integer
|
||||
color: String?
|
||||
}
|
||||
|
||||
value DashboardCategoryCloud {
|
||||
-- All categories as badge-like tags
|
||||
-- Each shows category name + count
|
||||
categories: List<DashboardCategory>
|
||||
}
|
||||
|
||||
value DashboardCategory {
|
||||
name: String
|
||||
count: Integer
|
||||
}
|
||||
|
||||
value DashboardRecentPost {
|
||||
-- Last 5 posts by updatedAt descending
|
||||
-- Each row: title (or "Untitled"), status badge (draft/published), date
|
||||
-- Single-click: preview tab, double-click: pin tab
|
||||
post_id: String
|
||||
title: String
|
||||
status: String
|
||||
date: String
|
||||
}
|
||||
|
||||
config {
|
||||
dashboard_max_tags: Integer = 40
|
||||
dashboard_tag_min_font: Integer = 11
|
||||
dashboard_tag_max_font: Integer = 22
|
||||
dashboard_recent_count: Integer = 5
|
||||
dashboard_timeline_months: Integer = 12
|
||||
}
|
||||
|
||||
-- ─── Post editor ──────────────────────────────────────────────
|
||||
|
||||
-- Single vertical column. Three regions: header, body, footer.
|
||||
|
||||
-- Header bar:
|
||||
-- Left: post title (or "Untitled") with dirty indicator dot
|
||||
-- Right: status badge, auto-save indicator, Quick Actions dropdown, Publish/Delete buttons
|
||||
-- Quick Actions:
|
||||
-- AI Analysis (suggests title, excerpt, slug)
|
||||
-- Translate Post (opens translation modal)
|
||||
|
||||
-- Collapsible Metadata section (starts expanded when title is empty):
|
||||
-- Two-column layout. Left column: metadata fields. Right column: linked media panel.
|
||||
-- Left column fields:
|
||||
-- Title (text input), Tags (autocomplete chip input), Author (text input),
|
||||
-- Language (select + AI detect button), Do Not Translate (checkbox),
|
||||
-- Slug (read-only), Categories (chip input), Template (select, if templates exist),
|
||||
-- PostLinks (backlinks and outlinks)
|
||||
-- Right column:
|
||||
-- LinkedMediaPanel (media items linked to this post)
|
||||
|
||||
-- Language flags bar (inline with metadata toggle):
|
||||
-- Row of flag emoji buttons for canonical language + each translation
|
||||
-- Styles: status class (draft/published), active indicator
|
||||
-- Clicking switches editor content to that language's draft
|
||||
|
||||
-- Collapsible Excerpt section:
|
||||
-- Excerpt textarea (4 rows)
|
||||
|
||||
-- Editor Body:
|
||||
-- Toolbar: "Content" label | mode toggle (Visual/Markdown/Preview) | action buttons
|
||||
-- Action buttons (markdown mode only): Gallery, Insert Post Link, Insert Media
|
||||
-- Visual mode: rich-text WYSIWYG editor
|
||||
-- Markdown mode: code editor with markdown-with-macros language
|
||||
-- Highlights [[macro ...]] double-bracket syntax
|
||||
-- Word wrap on, minimap off, 14px font
|
||||
-- Preview mode: iframe showing rendered preview
|
||||
-- Supports drag-and-drop of images (imports media, inserts markdown)
|
||||
|
||||
-- Footer:
|
||||
-- Three date stamps: Created, Updated, Published (published only if publishedAt exists)
|
||||
-- Locale-formatted dates
|
||||
|
||||
-- Modals:
|
||||
-- InsertModal for link search (Ctrl+K) and media search
|
||||
-- AISuggestionsModal for AI-generated title/excerpt/slug
|
||||
-- Translation modal: select target language, shows existing status
|
||||
-- Lightbox for content images
|
||||
|
||||
value PostEditorView {
|
||||
post_id: String
|
||||
header: PostEditorHeader
|
||||
metadata_expanded: Boolean
|
||||
excerpt_expanded: Boolean
|
||||
editor_mode: String -- visual | markdown | preview
|
||||
}
|
||||
|
||||
value PostEditorHeader {
|
||||
title: String -- post title or "Untitled"
|
||||
is_dirty: Boolean
|
||||
status: String -- draft | published | archived
|
||||
is_auto_saving: Boolean
|
||||
}
|
||||
|
||||
config {
|
||||
post_auto_save_delay: Integer = 3000
|
||||
-- milliseconds of idle before auto-save triggers
|
||||
}
|
||||
|
||||
invariant PostAutoSave {
|
||||
-- Auto-saves after 3 seconds of idle in the editor
|
||||
-- Also auto-saves on unmount/tab switch
|
||||
-- Ctrl/Cmd+S triggers immediate save
|
||||
}
|
||||
|
||||
invariant PostDirtyTracking {
|
||||
-- Compares canonical draft + translation drafts against saved state
|
||||
-- Dirty indicator shown in header and tab bar
|
||||
}
|
||||
|
||||
-- ─── Media editor ─────────────────────────────────────────────
|
||||
|
||||
-- Single column: preview area on top, metadata form below.
|
||||
|
||||
-- Header bar:
|
||||
-- Media display name
|
||||
-- Actions: Quick Actions dropdown, Replace File, Save, Delete
|
||||
-- Quick Actions:
|
||||
-- AI Image Analysis (image/* types only) - suggests title, alt, caption
|
||||
-- Detect Language (from metadata text)
|
||||
-- Translate Metadata (opens translation target modal)
|
||||
|
||||
-- Preview area:
|
||||
-- Images: rendered via bds-media:// protocol with cache-busting timestamp
|
||||
-- Non-images: SVG file icon placeholder + original filename text
|
||||
|
||||
-- Metadata form fields:
|
||||
-- File Name (read-only), MIME Type (read-only),
|
||||
-- Size (formatted as KB) + Dimensions (W x H, only if width/height exist),
|
||||
-- Title (editable), Alt Text (editable), Caption (textarea 3 rows),
|
||||
-- Tags (comma-separated text input), Author, Language (select)
|
||||
|
||||
-- Translations section (shown only when language is set):
|
||||
-- List of existing translations: flag + language name + title
|
||||
-- Per-translation: click to edit, refresh button, delete button
|
||||
-- "No translations" message when empty
|
||||
|
||||
-- Linked Posts section:
|
||||
-- "Link to Post" button opens post picker overlay
|
||||
-- Post picker: search input, up to 10 unlinked posts, "and N more" if >10
|
||||
-- List of currently linked posts (clickable -> navigates), unlink button
|
||||
-- "Not linked to any posts" when empty
|
||||
|
||||
value MediaEditorView {
|
||||
media_id: String
|
||||
is_image: Boolean
|
||||
file_name: String -- originalName, read-only
|
||||
mime_type: String
|
||||
file_size: String -- formatted
|
||||
dimensions: String? -- "W x H" if available
|
||||
title: String?
|
||||
alt_text: String?
|
||||
caption: String?
|
||||
tags: String? -- comma-separated
|
||||
author: String?
|
||||
language: String?
|
||||
translations: List<MediaTranslationItem>
|
||||
linked_posts: List<LinkedPostItem>
|
||||
}
|
||||
|
||||
value MediaTranslationItem {
|
||||
language: String
|
||||
title: String?
|
||||
}
|
||||
|
||||
value LinkedPostItem {
|
||||
post_id: String
|
||||
title: String
|
||||
}
|
||||
|
||||
-- No auto-save; explicit Save button required.
|
||||
-- Replace File opens a native file dialog.
|
||||
-- Delete shows confirmation with references (linked posts).
|
||||
|
||||
-- ─── Settings view ────────────────────────────────────────────
|
||||
|
||||
-- VS Code-style settings page with header + search bar + scrollable sections.
|
||||
-- Search filters sections by keyword match. "No results" with clear button.
|
||||
|
||||
-- 8 sections (style is a separate tab, not a settings section):
|
||||
|
||||
-- 1. Project Settings:
|
||||
-- Project Name (text), Project Description (textarea 3 rows),
|
||||
-- Data Path (text + Browse + Reset), Public URL (url),
|
||||
-- Main Language (select), Blog Languages (checkboxes, main disabled),
|
||||
-- Default Author (text), Max Posts Per Page (number 1-500 default 50),
|
||||
-- Blogmark Category (select), Blogmark Bookmarklet (copy button), Save
|
||||
|
||||
-- 2. Editor Settings:
|
||||
-- Default Editor Mode (select: WYSIWYG/Markdown/Preview),
|
||||
-- Diff View Style (select: Inline/Side-by-side),
|
||||
-- Wrap Long Lines (checkbox), Hide Unchanged Regions (checkbox)
|
||||
|
||||
-- 3. Content Settings (Categories):
|
||||
-- Table: Category | Title | Render in Lists | Show Titles | Post Template | List Template | Remove
|
||||
-- Protected categories: article, aside, page, picture (cannot be deleted)
|
||||
-- Add Category: text input + Add button. Reset to Defaults button
|
||||
|
||||
-- 4. AI Assistant Settings:
|
||||
-- API keys: OpenCode, Mistral (masked display + Change, or password input + Save)
|
||||
-- Local providers: Ollama enable checkbox + capabilities table,
|
||||
-- LM Studio enable checkbox + capabilities table
|
||||
-- Offline mode: enable checkbox (disabled if no local providers),
|
||||
-- selectors for chat/title/image models (local only)
|
||||
-- Default Model (select with optgroup by provider + refresh),
|
||||
-- shows: max output tokens, context window, pricing
|
||||
-- Title Model (select), Image Analysis Model (vision-capable only)
|
||||
-- System Prompt (textarea 12 rows + Save + Reset to Default)
|
||||
|
||||
-- 5. Technology Settings:
|
||||
-- Python Runtime Mode (select: Web Worker/Main Thread)
|
||||
-- Semantic Similarity (checkbox)
|
||||
|
||||
-- 6. Publishing Settings (SSH):
|
||||
-- Info: SSH key auth only
|
||||
-- SSH Mode (select: scp/rsync), SSH Host, SSH Username, SSH Remote Path
|
||||
-- Save + Clear buttons
|
||||
|
||||
-- 7. Data Maintenance:
|
||||
-- Rebuild buttons (6): Posts from Files, Media from Files, Scripts from Files,
|
||||
-- Templates from Files, Links, Regenerate Missing Thumbnails
|
||||
-- Open Data Folder button
|
||||
|
||||
-- 8. MCP Server Settings:
|
||||
-- Status badge (port or "Not running")
|
||||
-- Per-agent rows: Claude Code, Claude Desktop, GitHub Copilot, Gemini CLI,
|
||||
-- OpenCode, Mistral Vibe, OpenAI Codex — each with Add/Remove toggle
|
||||
|
||||
-- ─── Style view ───────────────────────────────────────────────
|
||||
|
||||
-- Simple vertical layout: header, theme picker, controls row, preview.
|
||||
|
||||
-- Theme Picker: grid of theme buttons (one per Pico CSS theme).
|
||||
-- Each button: swatch with 3 colour tones (accent, light bg, dark bg), theme name.
|
||||
-- Selected theme: highlighted with aria-pressed.
|
||||
|
||||
-- Controls row: Preview Mode dropdown (Auto/Light/Dark), Apply Theme button.
|
||||
|
||||
-- Preview: iframe of style preview page at 127.0.0.1:4123/__style-preview
|
||||
-- with theme and mode query params. Updates live on selection change.
|
||||
|
||||
-- Apply Theme persists to project metadata.
|
||||
|
||||
-- ─── Tags view ────────────────────────────────────────────────
|
||||
|
||||
-- Three sections controlled by sidebar TagsNav:
|
||||
|
||||
-- 1. Cloud: tag cloud visualization. Tags sized by post count,
|
||||
-- coloured by tag colour. Clickable to select for editing.
|
||||
|
||||
-- 2. Manage (Create/Edit): tag name input, colour picker, template select.
|
||||
-- Edit existing tag or create new. Delete button with confirmation.
|
||||
|
||||
-- 3. Merge: source tag select, target tag select, Merge button.
|
||||
-- Merges all posts from source tag into target, removes source.
|
||||
|
||||
-- ─── Chat panel ───────────────────────────────────────────────
|
||||
|
||||
-- Three-region vertical layout: header, message area, input area.
|
||||
|
||||
-- API Key Required screen (shown when no API key):
|
||||
-- Key icon, title, description, "Open Settings" button
|
||||
|
||||
-- Header:
|
||||
-- Left: conversation title (or "New Chat"), CSS ellipsis on overflow
|
||||
-- Right: model selector button + dropdown. Groups models by provider.
|
||||
|
||||
-- Message area:
|
||||
-- Welcome screen (no messages, not streaming): robot icon, tips
|
||||
-- Message list: each has avatar (user=person, assistant=robot), role label, text
|
||||
-- User messages: plain text
|
||||
-- Assistant messages: rendered as GFM Markdown
|
||||
-- External images blocked (CSP), shown as links
|
||||
-- Tool markers: checkmark/dot, tool name, truncated args (30 char strings)
|
||||
-- Streaming: accumulating markdown + tool markers, thinking dots animation
|
||||
-- Auto-scrolls to bottom on new messages
|
||||
|
||||
-- Input area:
|
||||
-- Abort/Stop button (only during streaming, square stop icon)
|
||||
-- Auto-growing textarea (max 200px). Enter sends, Shift+Enter newline
|
||||
-- Send button (up-arrow icon), disabled when empty or streaming
|
||||
|
||||
-- Token usage tracked per conversation (displayed in status bar, not chat panel).
|
||||
-- Per-conversation model override via header selector.
|
||||
|
||||
config {
|
||||
chat_tool_args_max_length: Integer = 30
|
||||
chat_input_max_height: Integer = 200
|
||||
}
|
||||
|
||||
-- ─── Git diff view ────────────────────────────────────────────
|
||||
|
||||
-- Renders diff for a file (working tree vs HEAD) or a commit.
|
||||
-- File diff: id = "git-diff:{filePath}"
|
||||
-- Commit diff: id = "git-diff:commit:{commitHash}"
|
||||
-- Supports inline and side-by-side diff display modes (from editor settings).
|
||||
|
||||
-- ─── Menu editor view ────────────────────────────────────────
|
||||
|
||||
-- Visual editor for the OPML navigation menu (meta/menu.opml).
|
||||
-- Drag-and-drop reordering of menu items.
|
||||
-- Item types: page, submenu, category_archive, home.
|
||||
-- Add/remove items, edit labels and targets.
|
||||
-- See menu.allium for data model.
|
||||
|
||||
-- ─── Metadata diff view ──────────────────────────────────────
|
||||
|
||||
-- Shows DB vs filesystem differences for all entity types.
|
||||
-- Each diff entry: entity type, field name, DB value, file value.
|
||||
-- Actions: apply file value to DB, or apply DB value to file.
|
||||
-- See metadata_diff.allium for diff field definitions.
|
||||
|
||||
-- ─── Documentation views ─────────────────────────────────────
|
||||
|
||||
-- documentation: renders DOCUMENTATION.md as styled HTML
|
||||
-- api_documentation: renders API.md as styled HTML
|
||||
|
||||
-- ─── Validation views ────────────────────────────────────────
|
||||
|
||||
-- site_validation: checks generated site for broken links, missing assets
|
||||
-- translation_validation: checks translation completeness across languages
|
||||
|
||||
-- ─── Find duplicates view ────────────────────────────────────
|
||||
|
||||
-- Uses embedding vectors to find semantically similar posts.
|
||||
-- Shows candidate pairs with similarity score.
|
||||
-- See embedding.allium for vector details.
|
||||
|
||||
-- ─── Script editor view ──────────────────────────────────────
|
||||
|
||||
-- Code editor for Lua scripts (macros, utilities, transforms).
|
||||
-- Header: script title, kind badge, enabled toggle.
|
||||
-- Editor: code editor with Lua syntax highlighting.
|
||||
-- Toolbar: Run button, entrypoint selector.
|
||||
-- See script.allium for entity model.
|
||||
|
||||
-- ─── Template editor view ─────────────────────────────────────
|
||||
|
||||
-- Code editor for Liquid templates (post, list, not_found, partial).
|
||||
-- Header: template title, kind badge, enabled toggle, version.
|
||||
-- Editor: code editor with Liquid syntax highlighting.
|
||||
-- Preview: rendered template output in iframe.
|
||||
-- See template.allium for entity model and Liquid subset.
|
||||
Reference in New Issue
Block a user