mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-01-06 03:30:25 -06:00
feat(tasks): add activity log, Markdown editor, and dark-mode polish
Backend - Add TaskActivity model to record start/pause/review/complete/cancel/reopen - Preserve started_at when reopening tasks; keep timestamps in app-local time - Expose recent activities on task detail view Migrations - Add 004_add_task_activities_table (FKs + indexes) Task detail (UI) - Move Description into its own card and render as Markdown (markdown + bleach) - Restyle Quick Actions to use dashboard btn-action styles - Add custom confirmation modal + tooltips - Recent Time Entries: use dashboard action buttons, add progressive “Show more/less” (10 per click) Tasks list - Fix dark mode for filter UI (inputs, selects, input-group-text, checkboxes) Create/Edit task - Integrate EasyMDE Markdown editor with toolbar - Strong dark-theme overrides (toolbar, editor, preview, status bar, tokens) - Prevent unintended side-by-side persistence - Align “Current Task Info” dark-mode styles with task detail CSS - Add dark-mode tints for action buttons, tooltip light theme in dark mode - Editor layout polish (padding, focus ring, gutters, selection) - Quick actions layout: compact horizontal group Deps - Add: markdown, bleach Run - flask db upgrade # applies 004_add_task_activities_table
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
from flask import Blueprint
|
||||
from app.utils.timezone import utc_to_local, format_local_datetime
|
||||
try:
|
||||
import markdown as _md
|
||||
import bleach
|
||||
except Exception:
|
||||
_md = None
|
||||
bleach = None
|
||||
|
||||
def register_template_filters(app):
|
||||
"""Register custom template filters for the application"""
|
||||
@@ -38,3 +44,27 @@ def register_template_filters(app):
|
||||
if text is None:
|
||||
return ""
|
||||
return text.replace('\n', '<br>')
|
||||
|
||||
@app.template_filter('markdown')
|
||||
def markdown_filter(text):
|
||||
"""Render markdown to safe HTML using bleach sanitation."""
|
||||
if not text:
|
||||
return ""
|
||||
if _md is None:
|
||||
# Fallback: escape and basic nl2br
|
||||
try:
|
||||
from markupsafe import escape
|
||||
except Exception:
|
||||
return text
|
||||
return escape(text).replace('\n', '<br>')
|
||||
|
||||
html = _md.markdown(text, extensions=['extra', 'sane_lists', 'smarty'])
|
||||
if bleach is None:
|
||||
return html
|
||||
allowed_tags = bleach.sanitizer.ALLOWED_TAGS.union({'p','pre','code','img','h1','h2','h3','h4','h5','h6','table','thead','tbody','tr','th','td','hr','br','ul','ol','li','strong','em','blockquote','a'})
|
||||
allowed_attrs = {
|
||||
**bleach.sanitizer.ALLOWED_ATTRIBUTES,
|
||||
'a': ['href', 'title', 'rel', 'target'],
|
||||
'img': ['src', 'alt', 'title'],
|
||||
}
|
||||
return bleach.clean(html, tags=allowed_tags, attributes=allowed_attrs, strip=True)
|
||||
|
||||
Reference in New Issue
Block a user