252 lines
8.8 KiB
Plaintext
252 lines
8.8 KiB
Plaintext
-- allium: 1
|
|
-- bDS Shared Modals
|
|
-- Scope: UI overlays used across multiple editor views
|
|
-- Distilled from: PostEditor.tsx, MediaEditor.tsx
|
|
|
|
-- Shared modal components used by multiple editors.
|
|
-- Editor-specific modals live in their respective editor spec files.
|
|
|
|
use "./i18n.allium" as i18n
|
|
|
|
-- ─── AI Suggestions Modal ────────────────────────────────────
|
|
|
|
-- Shared modal for presenting AI suggestions with per-field accept/reject.
|
|
-- Used by PostAIAnalysis (editor_post.allium) and
|
|
-- MediaAIImageAnalysis (editor_media.allium).
|
|
|
|
value AISuggestionsModal {
|
|
fields: List<AISuggestionField>
|
|
-- Layout: title bar ("AI Suggestions"), scrollable field list, button row
|
|
-- Each field rendered as a row:
|
|
-- Left: checkbox (accept/reject), label
|
|
-- Center: current value (read-only, muted), arrow, suggested value (highlighted)
|
|
-- Special: slug field checkbox disabled if post was ever published
|
|
-- Buttons: Cancel (secondary), Apply Selected (primary)
|
|
-- Cancel discards all; Apply writes only accepted fields to entity
|
|
}
|
|
|
|
surface AISuggestionsModalSurface {
|
|
context modal: AISuggestionsModal
|
|
|
|
exposes:
|
|
modal.fields.count
|
|
}
|
|
|
|
value AISuggestionField {
|
|
label: String
|
|
current_value: String
|
|
suggested_value: String
|
|
accepted: Boolean -- checkbox, default true
|
|
locked: Boolean -- if true, checkbox disabled (e.g. published slug)
|
|
}
|
|
|
|
-- ─── Insert Post Link Modal ──────────────────────────────────
|
|
|
|
value InsertPostLinkModal {
|
|
-- Two-tab modal opened by Ctrl/Cmd+K in post editor (markdown mode).
|
|
-- Tab 1 - Internal:
|
|
-- Search input (debounced 300ms, queries post titles via FTS)
|
|
--
|
|
-- Empty query state (search_query < 2 chars):
|
|
-- If semanticSimilarityEnabled: shows up to 5 related posts via
|
|
-- FindSimilar(current_post, 5) ranked by embedding similarity
|
|
-- Else: shows nothing (empty results)
|
|
--
|
|
-- Active query state (search_query >= 2 chars):
|
|
-- Results from FTS title search
|
|
-- If semanticSimilarityEnabled: each result augmented with similarity
|
|
-- score from ComputeSimilarities(current_post, result_post_ids)
|
|
-- Scores displayed as visual indicator per result row
|
|
-- Results list: post title + status badge + optional similarity score
|
|
--
|
|
-- Click result: inserts [title](/YYYY/MM/DD/slug) at cursor, closes modal
|
|
-- "Create Post" row at bottom of results:
|
|
-- Creates new post with search query as title, inserts link to it
|
|
-- Tab 2 - External:
|
|
-- URL input field (required)
|
|
-- Display text input field (optional)
|
|
-- Insert button: inserts [text](url) or bare url if no text, closes modal
|
|
active_tab: String -- internal | external
|
|
search_query: String
|
|
results: List<InsertLinkResult>
|
|
related_posts: List<InsertLinkResult> -- similarity-based, shown when query empty
|
|
}
|
|
|
|
surface InsertPostLinkModalSurface {
|
|
context modal: InsertPostLinkModal
|
|
|
|
exposes:
|
|
modal.active_tab
|
|
modal.search_query
|
|
modal.results.count
|
|
modal.related_posts.count
|
|
}
|
|
|
|
value InsertLinkResult {
|
|
post_id: String
|
|
title: String
|
|
status: String -- draft | published | archived
|
|
canonical_url: String -- /YYYY/MM/DD/slug
|
|
similarity_score: Decimal? -- 0.0-1.0, present when embeddings enabled
|
|
}
|
|
|
|
-- ─── Insert Media Modal ──────────────────────────────────────
|
|
|
|
value InsertMediaModal {
|
|
-- Grid modal for inserting media references into post content.
|
|
-- Search input filtering by media title and original filename.
|
|
-- Grid of media items: bds-thumb:// thumbnail (medium 400px), title below.
|
|
-- Click item:
|
|
-- Images: inserts  at cursor
|
|
-- Non-images: inserts [originalName](bds-media://id) at cursor
|
|
-- Closes modal after insertion.
|
|
search_query: String
|
|
results: List<InsertMediaResult>
|
|
}
|
|
|
|
surface InsertMediaModalSurface {
|
|
context modal: InsertMediaModal
|
|
|
|
exposes:
|
|
modal.search_query
|
|
modal.results.count
|
|
}
|
|
|
|
value InsertMediaResult {
|
|
media_id: String
|
|
title: String
|
|
original_name: String
|
|
is_image: Boolean
|
|
thumbnail_url: String? -- bds-thumb:// for images, null for others
|
|
}
|
|
|
|
-- ─── Language Picker Modal ───────────────────────────────────
|
|
|
|
value LanguagePickerModal {
|
|
-- Shown for Translate Post and Translate Media Metadata actions.
|
|
-- Lists all configured blogLanguages except source language.
|
|
-- Each row: flag emoji, language name, status badge if translation exists.
|
|
-- Existing translations show "(draft)" or "(published)" badge.
|
|
-- Click selects target language and initiates translation flow.
|
|
-- Cancel closes without action.
|
|
source_language: String
|
|
available_targets: List<LanguageTarget>
|
|
}
|
|
|
|
surface LanguagePickerModalSurface {
|
|
context modal: LanguagePickerModal
|
|
|
|
exposes:
|
|
modal.source_language
|
|
modal.available_targets.count
|
|
}
|
|
|
|
value LanguageTarget {
|
|
code: String
|
|
name: String
|
|
flag_emoji: String
|
|
has_existing_translation: Boolean
|
|
existing_status: String? -- draft | published, if translation exists
|
|
}
|
|
|
|
-- ─── Confirm Delete Modal ────────────────────────────────────
|
|
|
|
value ConfirmDeleteModal {
|
|
-- Custom styled modal for destructive operations with reference info.
|
|
-- Used by: MediaDelete (shows linked posts), TagDelete (shows post count).
|
|
-- Layout: warning icon, title, entity name, reference section, buttons.
|
|
-- Reference section: "This item is referenced by:" + bulleted list.
|
|
-- Buttons: Cancel (secondary), Delete (destructive red).
|
|
entity_name: String
|
|
entity_type: String -- media | tag
|
|
reference_count: Integer
|
|
reference_list: List<String> -- titles of referencing entities
|
|
}
|
|
|
|
surface ConfirmDeleteModalSurface {
|
|
context modal: ConfirmDeleteModal
|
|
|
|
exposes:
|
|
modal.entity_name
|
|
modal.entity_type
|
|
modal.reference_count
|
|
modal.reference_list
|
|
}
|
|
|
|
-- ─── Confirm Dialog ──────────────────────────────────────────
|
|
|
|
value ConfirmDialog {
|
|
-- Custom styled modal for non-delete confirmations.
|
|
-- Used by: TagMerge ("Merge N tags into {target}? Cannot be undone.").
|
|
-- Layout: title, descriptive message, buttons.
|
|
-- Buttons: Cancel (secondary), Confirm (primary).
|
|
title: String
|
|
message: String
|
|
}
|
|
|
|
surface ConfirmDialogSurface {
|
|
context modal: ConfirmDialog
|
|
|
|
exposes:
|
|
modal.title
|
|
modal.message
|
|
}
|
|
|
|
-- System confirm dialogs are NOT modelled as values.
|
|
-- They are simple yes/no system dialogs with a message string.
|
|
-- Used by: PostDelete, PostDiscard, TemplateDelete (with references).
|
|
|
|
-- ─── Gallery Overlay ─────────────────────────────────────────
|
|
|
|
value GalleryOverlay {
|
|
-- Full-screen overlay showing all media linked to a post.
|
|
-- Opened from Gallery button in post editor toolbar (markdown mode).
|
|
-- Image grid: bds-thumb:// thumbnails (medium 400px), 3-4 columns.
|
|
-- Click image: opens LightboxView for that image.
|
|
-- Close: X button or ESC key.
|
|
post_id: String
|
|
images: List<GalleryImage>
|
|
}
|
|
|
|
surface GalleryOverlaySurface {
|
|
context overlay: GalleryOverlay
|
|
|
|
exposes:
|
|
overlay.post_id
|
|
overlay.images.count
|
|
}
|
|
|
|
value GalleryImage {
|
|
media_id: String
|
|
thumbnail_url: String -- bds-thumb://media_id
|
|
alt_text: String?
|
|
}
|
|
|
|
value LightboxView {
|
|
-- Full-screen image viewer, sub-view of GalleryOverlay.
|
|
-- Shows single image at full resolution via bds-media:// protocol.
|
|
-- Navigation: left/right arrow buttons, keyboard left/right arrow keys.
|
|
-- Close: X button, ESC key, or click outside image area.
|
|
-- Header: image title or filename, index counter "3 of 12".
|
|
current_index: Integer
|
|
total_count: Integer
|
|
media_id: String
|
|
image_url: String -- bds-media://media_id
|
|
alt_text: String?
|
|
}
|
|
|
|
surface LightboxViewSurface {
|
|
context view: LightboxView
|
|
|
|
exposes:
|
|
view.current_index
|
|
view.total_count
|
|
view.media_id
|
|
view.image_url
|
|
view.alt_text when view.alt_text != null
|
|
}
|
|
|
|
-- All modals rendered as centered overlay with backdrop dimming.
|
|
-- ESC key or backdrop click closes modal (cancel semantics).
|
|
-- Overlays (PostPicker, ColourPicker) are positioned inline near trigger.
|