Commit Graph
25 Commits
Author SHA1 Message Date
OpenClaw Sub-agent 54a416c63c feat(template links): Sketch-style visual parameter builder
- link_form: template builder under the URL field — preset param chips
  (q/id/page/category/keyword/lang, CN labels) click to insert ?q={q} with
  smart ?/& separators; auto-parsed parameter rows (name + default input +
  remove); custom params (name + default -> append); live dark preview
  filling defaults (green) and flagging required (red); chips grey out
  when used; hidden on Custom/Action tabs; edits existing templates
- redirect_to_original: map GET query params (?q=weather) by name into
  template placeholders, keep path-param backward compat (go/alias/x
  fills every unfilled param), defaults otherwise; query wins over path
- tests: +5 template redirect cases (query map, multi-param, defaults,
  path compat, query-over-path)
2026-08-02 17:28:32 +10:00
OpenClaw Sub-agent 595b99446b feat: ⌘K command palette + restore green nav (fixes mobile menu collapse)
- Command palette (Ctrl/Cmd+K or nav search icon): /search/palette/ groups
  links/pages/posts with jump/detail/edit actions, keyboard navigation
- Hero: stats inline under search pill, ⌘K chip on desktop, Random Images
  broken-image fallback to elegant SVG placeholder (layout untouched)
- Restore original green nav (bg-custom-blue). The frosted-glass nav from
  1.0.401 broke the mobile Menu dropdown: backdrop-filter creates a
  containing block, collapsing the fixed full-screen dropdown to 3px
- Palette tests: +5 cases (grouping, post match, management fields,
  empty query, no results)
2026-08-02 11:20:11 +10:00
OpenClaw Sub-agent dda47ee62e feat(home): search-driven link library with mobile card layout
- /search/aliases/ now matches alias/url/description/text/tags and returns
  id, link_type, detail_url, edit_url, click_count for management actions
- Library filter upgraded from client-side row filtering to live search
  cards: click card -> detail page, inline edit/delete, alias jumps
- Mobile: table rows render as cards (kills 620px horizontal scroll),
  hidden cells stay hidden, no viewport overflow
- Hero search no longer autofocuses on touch devices (no keyboard pop);
  desktop keeps autofocus via hover:fine media query
- Nav bar unified to light frosted-glass (was dark green) across all pages
- Fix hero-glow decorative overflow on mobile
- Add tests/test_search_aliases.py (8 cases)
2026-08-02 10:58:44 +10:00
OpenClaw Sub-agent b67a834def feat(invest): cost basis & P&L, AUD totals, chart ranges, per-ticker page, manual entry, tx search
P1:
- WAC cost basis per (portfolio, ticker): avg_cost / unrealized P&L / P&L%
  - transaction price when recorded, else trade-date market close (estimated, flagged)
  - dashboard: Unrealized P&L card + Avg Cost & P&L columns on holdings tables
  - fx: frankfurter.dev rates (USD/HKD->AUD, 24h cache, UA header required) -> AUD total on Total Value card
  - chart: 1M/3M/6M/YTD/1Y/ALL period buttons (all periods precomputed server-side, top-level payload stays YTD for compat)
P2:
- /invest/stocks/<ticker>/ per-ticker page: cross-account holdings, WAC, P&L, weight, theme, trade history
- manual transaction + cashflow entry forms (source=MANUAL, confidence=1.0)
- dashboard transaction search (?q= ticker/account) + add-transaction buttons
- tickers link to detail page; tabular-nums on all figures
- 8 new tests (WAC sell, estimated price, incomplete, per-portfolio agg, stock page, forms, search)
2026-08-02 08:09:58 +10:00
OpenClaw Sub-agent 8cd92812f7 feat: server-side thumbnails (Pillow/ffmpeg), 3D cover-flow carousel, fix preview close on iOS
- New /ui/files/{pk}/thumb/ endpoint: Pillow resize for images, ffmpeg first-frame for videos, disk-cached with per-record lock
- Grid & carousel render server thumbnails via <img> — fixes blank video thumbs on iOS Safari
- Carousel upgraded to 3D cover-flow: perspective rotateY/scale/opacity driven by scroll position
- Preview <video> gets playsinline + webkit-playsinline — fixes close button unusable after iOS fullscreen playback
- thumbnail_url exposed in serializer, upload response, and client JSON
- 3 new tests: thumb 200/cache, non-media 404, missing-file 404
2026-08-01 23:22:57 +10:00
OpenClaw Sub-agent c4a4b7a299 feat: Apple-style action link edit UI — hide JSON, card picker, live preview
- Hide action_config JSON field from the form (internal storage, not user-editable)
- Replace Action dropdown with an Apple-style radio card (💬 发消息到 Discord)
- Rename Message template → 消息内容 with plain-language help text
- Add live message preview that highlights {query} as a chip
- Tests: edit page renders card + Chinese labels, no JSON exposed (109 passed)
2026-08-01 21:16:00 +10:00
OpenClaw Sub-agent f2f8192fba refactor: make Ask a regular ACTION link instead of fixed route
Remove hardcoded /ask/ routes (core/urls.py), /api/ask/ (api_urls.py),
ask_views.py, and ask.html input page. Ask is now a normal Link record
(alias='ask', link_type=ACTION) created by data migration 0053, so it
behaves exactly like other action links: go/ask/问题 → catch-all →
execute_action → 302 to Discord, editable/deletable in the Links UI.

Tests updated: ask covered as ACTION link (redirect/dedup/empty-query).
2026-08-01 20:43:29 +10:00
OpenClaw Sub-agent 7d89e91319 feat: action links send+redirect to Discord, no result page; 10-min dedup window 2026-07-31 23:37:36 +10:00
OpenClaw Sub-agent 1c18f2b177 feat: add Action link type — configurable send-to-Discord links with UI form 2026-07-31 22:56:06 +10:00
junv 921fd1e0cc Update links 2026-07-30 15:56:31 +10:00
junv d857eb58c5 Add bookmarks 2026-07-30 13:25:36 +10:00
junv e5da25bb01 Update 2026-07-28 21:42:58 +10:00
junv e61da159ac Update 2026-07-28 21:15:48 +10:00
junv 174b296c62 feat(links): log CONTENT_EDIT on text changes (no content persisted)
Previously, editing a custom link's text content created a spurious
URL_CHANGE row (fixed last commit) but no audit entry at all for the
actual content change. The product requirement: a change-log row SHOULD
be created so auditors see content was edited, but should NOT persist
the content itself.

LinkUpdateView now:

- Captures self.original_text in get_initial() alongside
  self.original_url.
- After super().form_valid() writes the new text, compares old vs new
  text. If different, creates a LinkChangeLog with
  change_type=CONTENT_EDIT and metadata={'changed': True} — no content
  payload. Applies to both LINK and CUSTOM link types.
- URL-change logging behaviour is unchanged.

Tests in TestCustomLinkEditUrlChangeLog now cover:
  - custom link text edit creates CONTENT_EDIT, no URL_CHANGE
  - custom link text unchanged creates no log
  - regular link text change creates CONTENT_EDIT
  - regular link URL change still logs URL_CHANGE
2026-07-16 11:24:04 +10:00
junv f7ac32cf4c fix(links): custom link edits spuriously logged URL changes
When editing a CUSTOM link's text content, the ViewUpdateView's
URL-change check was comparing the captured original_url (e.g.
'/custom/mynote') against form.cleaned_data['original_url'], which
for custom links is blank because the original_url input is hidden in
link_form.html and not submitted. They never matched, so every edit
produced a spurious LinkChangeLog 'URL changed' row.

Use the recomputed /custom/{alias} value (already set on
form.instance.original_url) for custom links, and only the submitted
form value for regular links. So the log now fires only when:

- a regular link's URL actually changes, or
- a custom link's alias changes (which derives a new /custom/{alias}).

Add TestCustomLinkEditUrlChangeLog covering:
  - custom link text-edit produces no URL-change log
  - regular link edit leaving URL unchanged produces no log
  - regular link URL change logs once with old/new URL
  - custom link alias change logs once with old/new derived URL
2026-07-16 11:11:25 +10:00
junv bf3e2e80cf feat(links): auto-create non-existent tags on link create, lowercase all
Select2 submits raw text as the value for new tags typed into the tag
box (tags: true + createTag in link_form.html). The previous
ModelMultipleChoiceField silently dropped those values because they
were not PKs of existing tags, so new tags were never persisted.

Add TagInputField, a tolerant ModelMultipleChoiceField subclass:
  - existing tag PKs resolve as before
  - raw text is treated as a new (or case-insensitive-existing) tag
  - names are stripped and lowercased before get_or_create so the tag
    namespace stays consistent and case-insensitive duplicates are
    avoided. The Tag.save() hook still derives the slug.

LinkForm now uses TagInputField for its tags field, so both
LinkCreateView and LinkUpdateView pick up the new behaviour. The
Select2 createTag callback in link_form.html now lowercases the term
so users see immediately what will be stored.

Add 7 regression tests in TestLinkTagAutoCreate covering: new tag
created + lowercased; multiple new tags; existing tag reused (no
duplicate); mixed PK + new-text submission; no tags submitted; empty
or whitespace-only submission ignored; whitespace stripped.
2026-07-16 10:10:07 +10:00
junv 2625ef10b4 test(pricemon): pin telegram notification contract
Add integration tests covering the price-drop → Telegram alert flow:

- Sends Telegram MarkdownV2 message to global SiteSettings chat_id when
  detected price <= watcher.alert_price_threshold.
- No alert when global creds missing.
- No alert when price above threshold.
- No alert when threshold unset on watcher.
- Non-recurring watcher with an undismissed alert is not re-notified.
- Telegram API failure does not break the check (snapshot + alert row
  still persist, last_price updates).
2026-07-16 09:50:37 +10:00
junv 4a5f0f63ee fix(pricemon): load i18n in _alerts partial and pass alerts to include
AlertsPartialView (htmx-polled every 30s from the dashboard) returned
500 because _alerts.html used {% trans %} without {% load i18n %}.
Added the load tag so the partial renders correctly.

The dashboard's inline {% include 'pricemon/_alerts.html' %} also
relied on an undefined 'alerts' context var (DashboardView sets
'active_alerts'), so the alerts panel rendered empty even when alerts
existed. Pass alerts=active_alerts explicitly via the include.

Add regression tests covering both the dashboard render with an alert
and the alerts partial endpoint.
2026-07-16 09:34:15 +10:00
junv 647ce87359 Add price monitor toggle 2026-06-23 16:25:59 +10:00
OpenClaw Sub-agent e87b714f84 fix: show legacy investment reports on invest dashboard 2026-06-14 09:04:43 +10:00
OpenClaw Sub-agent 526868630f feat: add invest chart value mode 2026-06-14 08:47:50 +10:00
OpenClaw Sub-agent f7a3d228c1 feat: add cashflow-adjusted invest dashboard 2026-06-14 08:19:44 +10:00
junv c26c620f78 Add redis caching 2026-03-29 10:23:46 +11:00
copilot-swe-agent[bot]andwahyd4 3c57f4afb9 Allow static Unicode text mixed with template params in template URLs
Agent-Logs-Url: https://github.com/wahyd4/links/sessions/b1b352f0-55a8-4973-9df9-5e1f6a8e3768

Co-authored-by: wahyd4 <836576+wahyd4@users.noreply.github.com>
2026-03-27 00:17:34 +00:00
junv 2ff7ab85ed Add tests 2026-03-21 21:00:38 +11:00