Commit Graph

294 Commits

Author SHA1 Message Date
A. S.
ce61af1483 feat: add :asset property type with thumbnail picker (#12506)
* feat(property): add :asset property type with thumbnail grid picker

Introduces a new user-facing "Asset" property type, modeled on :node but
restricted to blocks tagged with :logseq.class/Asset. Unlike :node's text
search dropdown, the :asset picker opens a 4-column thumbnail grid popup
populated from db-async/<get-tag-objects, filtered to image assets via
common-config/img-formats.

Once a value is set, the property cell renders an inline asset-cp preview
alongside "View" and "Swap" action buttons. View dispatches a new
:asset/show-preview event that opens the image lightbox for images, the
PDF viewer for PDFs (same path as the inline open-pdf-file handler), and
falls back to redirect-to-page! for other asset types. Swap reopens the
grid popup so the user can pick a different asset.

- Register :asset in user-built-in-property-types, user-ref-property-types,
  and property-types-with-db; add asset-entity? validator that requires
  :block/title and :logseq.class/Asset in :block/tags.
- Label the type as "Asset" in property-type-label so it appears in the
  property type sub-pane.
- Add asset-grid-popup-content and asset-value-picker components in
  property/value.cljs, dispatch :asset ahead of the generic select branch
  in property-scalar-value-aux, and include :asset in the reference
  display set used by select-item.
- Wire :asset/show-preview in handler/events/ui.cljs using the existing
  lightbox, pdf-assets, and assets-handler plumbing.

* fix(property): refresh asset thumbnail after Swap

asset-cp captures the asset block in :will-mount, so React reconciling
the same component in place across re-renders left the old thumbnail
rendered even though the underlying property value had been updated
(visible because the View button opened the newly chosen asset).

Keying asset-cp on (:block/uuid value) forces React to remount it on
swap so :will-mount re-runs with the new block.

* fix(property): let image clicks select the asset in picker grid

asset-cp renders an <img> with its own click handler that opens the
image preview lightbox, which swallowed clicks before they could reach
the grid cell's select-this-asset handler. Users had to click the
padding around an image to pick it. Disabling pointer events on the
thumbnail wrapper lets the click bubble straight to the parent button.

* fix(property): fit asset thumbnails without cropping any aspect ratio

asset-cp emits the <img> with explicit width/height attributes (default
250px) wrapped in a div.asset-container that has no size constraint of
its own, so neither square nor tall images respected the thumbnail
bounding box: max-h-full on the img resolved against an auto-sized
parent and tall images overflowed the property row.

Constrain every descendant with !important max-w-full / max-h-full and
force the img to w-auto h-auto object-contain, and give the block
property thumbnail a fixed 80x80 bounding box instead of the previous
120x80 max that let the asset-container stretch. Same override is
applied to grid picker cells so they stay uniform regardless of source
aspect ratio.

* fix(property): stop tall images cropping in asset picker grid

The previous fix applied max-w/max-h-full to all descendants, but
div.asset-container's own height stayed auto, so max-height: 100% on
the img resolved against an auto-sized parent and tall images still
overflowed their grid cell.

Force div.asset-container itself to w-full h-full (and flex-center) so
the img's max-h-full resolves against a real bounded height. Same fix
is applied to the block property thumbnail for consistency.

* feat(property): show all asset types in picker grid with title bar

Drop the image-only filter so the asset picker grid lists every block
tagged :logseq.class/Asset, not just images. Non-image assets render as
a centered tabler icon + uppercase extension label chosen by a new
asset-icon-for-type helper (photo / music / movie / file-type-pdf /
file fallback); image assets keep the existing asset-cp thumbnail.

Each grid cell is now a vertical flex with a small title strip at the
top showing :block/title (truncated) and the thumbnail body filling
the rest of the square. min-height: 0 on the body lets the flex child
shrink inside the aspect-ratio box so square images still fit without
pushing the title off screen.

* feat(property): skip image sizing constraints for non-image asset values

The filled asset-value-picker used to force every asset-cp render into
a fixed 80x80 box with img overrides meant for bitmap thumbnails. That
mangled PDF link icons, audio <audio> controls and video <video>
players because those elements have their own intrinsic layout.

Branch on (:logseq.property.asset/type value): image assets keep the
80x80 constrained box so square/tall/wide bitmaps still fit without
cropping, while every other asset type renders asset-cp in a plain
flex-shrink-0 wrapper at its natural size.

* feat(property): preview video assets in a modal instead of inline

Inline asset-cp for videos rendered a full <video> player in the
property row, which was oversized and awkward next to the View/Swap
buttons. Replace it with a compact shui button showing a movie icon
plus the truncated asset title; clicking the button dispatches the
existing :asset/show-preview event.

The :asset/show-preview handler grows a video branch that resolves the
asset URL via <make-asset-url and opens a centered shui dialog with an
autoplaying <video controls>, capped at 80vh so it never exceeds the
viewport. Image lightbox and PDF viewer paths are untouched.

* refactor(property): drop redundant View button on asset property values

Every asset type already has a native click-to-preview path: image
thumbnails open the lightbox via resizable-image's handler, PDF links
open the PDF viewer via asset-link, audio/video players are clickable
in place, and the video-asset fallback button itself dispatches
:asset/show-preview. The separate View button just duplicated those
actions, so remove it and leave only Swap next to the thumbnail.

* fix(property): let video asset button grow to fit title

The video preview button capped itself at max-w-[240px] with a
truncated title span, cropping any video whose name was longer than
the cap. Drop the cap and truncation so the button sizes to its
content, and add h-auto whitespace-normal text-left so titles that
wrap onto multiple lines stay visible instead of being clipped by
shui's fixed button height.

* refactor(property): review cleanups for :asset property type

Addresses review feedback from the branch self-review:

- Extract the asset-cp-fit CSS escape hatch into an asset-thumb-fit-class
  def with a docstring explaining why .asset-container needs forced
  sizing, and reuse it in both the grid cell and the filled-state
  thumbnail instead of duplicating the 60-char tailwind arbitrary
  variant soup in two places.
- Simplify the two-clause cond in asset-value-picker's filled branch
  to an if now that the :else is the only fallthrough.
- Wrap set-block-property! in the grid picker on-click with p/catch so
  transact failures log and surface a notification toast instead of
  being silently swallowed after the popup hides.
- Replace the bespoke :content-props {:class "max-w-[min(90vw,1200px)]"}
  on the video preview dialog with shui's supported :auto-width? true
  option, which applies max-w-[90vw] w-max sm:max-w-[960px] via the
  data-auto-width CSS hook.
- Add a new logseq.db.frontend.property.type-test ns covering both the
  :asset property type registration (present in user-built-in /
  user-ref / all-ref / property-types-with-db, absent from
  cardinality / closed-value) and the asset-entity? validator against
  a real datascript db built via db-test/create-conn-with-blocks.
- Add a comment above asset-entity? documenting that :logseq.class/Asset
  lives in ldb/private-tags, so the class is used programmatically for
  scoping rather than via #Asset inline tagging.

* fix(property): satisfy CI lint checks for :asset property type

Address two lint failures on PR #12506:

- Drop the unused datascript.core require in property/type_test.cljs
  (clj-kondo unused-namespace warning failed the deps/db lint job).
- Replace four hardcoded user-facing strings in the asset grid picker
  with i18n keys, adding :asset/picker-empty, :asset/picker-fallback-type,
  and :asset/picker-set-failed to the English dictionary; reuse
  :ui/loading for the loading state.

* fix(property): address upstream review on :asset property type

Two follow-ups from the copilot-pull-request-reviewer review on PR #12506:

- Guard :asset picker against edits in publishing mode. show-grid!
  short-circuits when config/publishing? is true so the empty-state click
  and the Swap button can no longer open the picker, and the
  Backspace/Delete branch of the keydown handler no longer fires
  delete-block-property! Mirrors how single-value-select gates its
  popup. Read-only paths (image lightbox, video preview dialog) are
  left intact so published readers can still view embedded assets.

- Localize the Swap button label. Adds :asset/swap "Swap" to en.edn
  and replaces the hard-coded literal with (t :asset/swap), matching
  the other strings in asset-value-picker (picker-empty,
  picker-set-failed, picker-fallback-type).

* fix(property): use letter-a icon for :asset property type

Without an entry in property-icon's case form, :asset properties fell
through to the default "letter-t" glyph, which collides visually with
the Text type. Map :asset to "letter-a" so the column header reads as
"A".

* fix: improve asset property picker

---------

Co-authored-by: Victor239 <12621257+Victor239@users.noreply.github.com>
Co-authored-by: Tienson Qin <tiensonqin@gmail.com>
2026-05-14 22:00:00 +08:00
Tienson Qin
562e56e4c5 fix: delete recycled node cleanup 2026-05-12 18:39:37 +08:00
VictorVow
1423a38062 fix: restore :ref/default-open-blocks-level 0 behavior in DB graphs
Make `:ref/default-open-blocks-level 0` collapse references by default
in the DB version, matching the previous file-graph behavior. The
section fold is scoped to the page-bottom "Linked References" panel
only — the inline "Open block references" popup rendered next to
blocks always shows its references uncollapsed.

1. Collapse the "Linked References" section when the configured level
   is 0, gated on a new `:linked-refs-section?` config flag set only
   by the page-bottom call site in page.cljs. The inline popup at
   block.cljs:3366 passes `{}` and is unaffected.

2. Propagate `:block.temp/has-children?` on the top-level fetched
   block in `get-block-and-children`. The list-view loads linked-
   reference blocks with `:children? false`, so `(:block/_parent ...)`
   is always nil in the client DB and the collapse check in
   `block-default-collapsed?` could never fire. Use a lightweight
   `d/datoms :avet :block/parent` scan that stops at the first match,
   rather than the reverse-ref `(:block/_parent block)` which
   materializes the full child set. Includes a regression test.

3. Fall back to `:block.temp/has-children?` when computing `has-child?`
   in `block-container-inner-aux`. This renders the collapse arrow for
   blocks whose children exist in the worker DB but haven't been
   lazily loaded into the client DB yet (e.g. linked-reference blocks).
   Clicking the arrow calls `expand-block!` which loads them.

The `:ref/default-open-blocks-level 0 → (int? ...)` state.cljs fix
from PR #12228 is already present on this branch.
2026-05-08 11:18:51 +08:00
rcmerci
a610925bca fix(export): ignore legacy-property 2026-05-06 21:03:23 +08:00
Tienson Qin
94ea551ec4 perf(db): optimize recursive uuid title replacement (#12536)
* perf(db): optimize recursive uuid title replacement

* fix: lint

* fix: don't lower-case for search indexed blocks

* fix: typo
2026-04-24 21:09:47 +08:00
Tienson Qin
3414177805 fix: validate client tx and ensures monotonically increasing 2026-04-23 15:52:03 +08:00
Tienson Qin
12e8cc3d36 fix(db): clear tx-tail after batch-transact store 2026-04-23 02:28:55 +08:00
Mega Yu
5eda6a8ab6 Merge master into enhance/i18n 2026-04-14 16:42:19 +08:00
Tienson Qin
ff56c143ab continue to improve view performance 2026-04-14 05:37:45 +08:00
Tienson Qin
995d0bf4a9 enhance(view): speed up large-graph get-view-data 2026-04-14 04:52:10 +08:00
Tienson Qin
e3a974947a perf: views 2026-04-14 04:33:46 +08:00
Mega Yu
5a752ef99d fix multiple logic errors caused by date format switching 2026-04-10 22:58:48 +08:00
Tienson Qin
1d98f1d214 ensure :block/uuid immutability 2026-04-07 04:17:09 +08:00
Tienson Qin
e85addc933 refactor: rename batch-transact! 2026-03-27 16:15:42 +08:00
Tienson Qin
65a0a7dafd code cleanup 2026-03-26 15:30:01 +08:00
Tienson Qin
2b707c1199 refactor: sync based on semantic ops 2026-03-20 20:40:38 +08:00
Tienson Qin
e3e54eba3f tag/property/closed value should be hard retracted 2026-03-18 06:11:04 +08:00
Tienson Qin
1f30693851 fix: tests 2026-03-18 06:11:04 +08:00
Gabriel Horner
8216e1a177 enhance: export-edn exports nested children of text-property values
Should address https://github.com/logseq/db-test/issues/756
2026-02-26 19:28:15 -05:00
Gabriel Horner
5b1bfeed2b fix: db lint
Also silence noisy successful db test which distracts from actual
failing tests
2026-02-26 12:21:56 -05:00
Tienson Qin
cdc1bc1d32 fix: get-bidirectional-properties perf
Root cause:
get-bidirectional-properties was recomputing
bidirectional-property-attr? for every [e a] match, repeatedly calling
d/entity for the same property attr keyword. That made cost scale with
datom count, not unique properties.

Fix:
Added per-call memoization for property-attr bidirectional checks
using a local volatile! cache, so each attr is resolved once per
invocation.
2026-02-26 14:13:31 +08:00
Gabriel Horner
b18056c910 enhance: export-edn exports property history
also ensure that it is idempotent
2026-02-25 14:52:16 -05:00
Gabriel Horner
8b5407a91d fix: db and frontend lint 2026-02-24 15:05:18 -05:00
Gabriel Horner
f0f5911ca7 enhance: export-edn is idempotent for 3 more keys
For keys with non-ordered collections, use sets to consistently produce
idempotent values. Users can still author with vectors for these keys.
This affects :build/tags, :build/property-classes and
:build/class-extends.  Also remove any hacks around making their values
consistent across import->export cycles
2026-02-24 14:26:02 -05:00
Tienson Qin
e6e61e235a fix: cleanup to process all retracted entities (including pages)
related to https://github.com/logseq/db-test/issues/726
related to https://github.com/logseq/db-test/issues/752
2026-02-24 23:00:35 +08:00
Tienson Qin
3c9dee98da fix: invalid data when deleting closed value
fixes https://github.com/logseq/db-test/issues/729
2026-02-24 22:39:15 +08:00
Gabriel Horner
97835eeeb7 enhance: export-edn :build/class-properties sorts properties
both when building and exporting
2026-02-23 17:04:29 -05:00
Gabriel Horner
5e43f89af2 enhance: export-edn supports :build/properties in property values
no matter how many levels deep a property value has properties
2026-02-20 13:49:10 -05:00
Gabriel Horner
991e38419a enhance: export edn handles assets
Addresses https://github.com/logseq/db-test/issues/656.
Should also address most :entity built in properties
2026-02-19 20:24:23 -05:00
Gabriel Horner
3e1745dca7 chore: DRY up export tests with new test fn 2026-02-18 15:23:41 -05:00
Gabriel Horner
16beb18c92 fix: export tests with large graph have duplicate built-in pages
Fixed the setup of these tests and then was able to confirm that
built-in pages are idempotent with import-export process. Also fixed
related docstrings
2026-02-18 15:23:41 -05:00
Gabriel Horner
f28e001b5a enhance: ensure export EDN is idempotent across import and export
An EDN export should consistently produce the same EDN when imported
into a new graph and re-exported. This adds initial fn, cli option and
test to ensure this. There are some known TODOs. diff-graphs script was
removed as it was being used as a subset of the workflow provided by the
--roundtrip option
2026-02-18 15:23:41 -05:00
Gabriel Horner
1ff8a12d35 fix: export-edn shouldn't add empty :build/properties
This results in exports that aren't repeatable across exports a.k.a. roundtripable
2026-02-17 16:27:24 -05:00
Gabriel Horner
3d88cd1fd6 fix: import of multi word tags
Also fixes quirky editor bug for inline multi word tags. Both bugs
reported in https://github.com/logseq/db-test/issues/724
2026-02-16 14:35:53 -05:00
Gabriel Horner
0d1b997fa9 fix: reaction schema results in invalid nodes 2026-02-11 15:07:00 -05:00
Gabriel Horner
1a1896ba5b fix: internal-ident?
Also fix db test
2026-02-05 09:01:04 -05:00
Tienson Qin
05be455371 feat: reactions 2026-02-01 21:45:31 +08:00
Tienson Qin
729ca7fcbf Merge branch 'master' into feat/worker-sync 2026-01-26 18:52:12 +08:00
Gabriel Horner
173898240e fix: remove most file graph uses in deps
except for graph-parser and publish deps

- Removed most mentions of 'repo' in deps, which cleaned up a lot related
  to export cli and worker
- Removed db-based-graph? checks in deps except for unknown use
  in entity-plus?
- Removing db-based-graph? checks resulted in deleting unused file graph
  code paths e.g. get-pid
- Removed file graph handling in cli list command
- Remove file-based-graph? checks from deps
2026-01-22 13:19:58 -05:00
Tienson Qin
cbece9e29f fix: lint 2026-01-22 00:52:47 +08:00
Tienson Qin
bcb9f84469 add tests 2026-01-22 00:52:47 +08:00
Tienson Qin
c03a5183df refactor: fix data in server instead of client 2026-01-12 23:56:50 +08:00
Gabriel Horner
5748905057 fix ref-property tests pointing to property rule
Also add back property tests as it is still a useful rule
2026-01-05 14:44:49 -05:00
Tienson Qin
0f949b739c fix: tests 2026-01-01 14:20:33 +08:00
Tienson Qin
c21f2c7f4f Ensure local graphs have uuid 2025-12-30 14:48:51 +08:00
Tienson Qin
74d136e49c fix: export tests 2025-12-30 00:34:02 +08:00
Tienson Qin
1ae9e2c496 fix: extends tags query and support eid|title|db-ident
Previously `tags` doesn't return blocks that have children tag(s).

Also, `tags` support both db/ident and block/title to make it easy
to use:
(tags ?b #{144})
(tags ?b #{"Task"})
(tags ?b #{:logseq.class/Task})
2025-12-24 14:37:57 +08:00
Tienson Qin
aea9f09fd1 Simple query performance enhancements (#12262)
* perf: separate scalar from ref property query

* fix: query bindings

* perf: separate default value query from others

* fix: import properties first and then other datoms
2025-12-19 19:37:51 +08:00
Gabriel Horner
529be0496c fix: build and export of property values
for a :many property that has additional attributes
e.g. :build/tags
Another possible fix for https://github.com/logseq/db-test/issues/636
2025-12-11 14:46:21 -05:00
Gabriel Horner
b696a84cac fix: export of property value blocks doesn't
keep its uuid when it's referenced as a property value.
Noticed this with a graph from Tienson where a property value had a
view
2025-12-10 15:46:34 -05:00