Skip to content

Selection and batch operations in search#1447

Draft
alethiophile wants to merge 45 commits intoDifegue:devfrom
alethiophile:search-select-batch
Draft

Selection and batch operations in search#1447
alethiophile wants to merge 45 commits intoDifegue:devfrom
alethiophile:search-select-batch

Conversation

@alethiophile
Copy link
Contributor

This is my UI for doing batch operations on archives from the search page. Currently, this is only used for adding archives to tankoubons, but I intend to add a few more operations on tags and categories.

Each result in a search has a checkbox. When checkboxes are selected, a bar pops up allowing you to do bulk operations on the selection. (Basic pattern inspired by similar operations in file managers.) The selection is maintained across page navigation. Because this is in the search result view, it gives you an easy way to operate on the results of a search: just run the search and select everything.

It's based against my tankoubon-search-and-view tree, since it's intended to work with that code, but is technically separable.

@Difegue Difegue linked an issue Jan 18, 2026 that may be closed by this pull request
If the grouptanks parameter is true, then search results may include a
mix of archives and tankoubons. Tankoubons have different metadata
handling than archives, and so the existing sorting code didn't handle
it correctly.

There's a question here about how sorting by a prefix should be
handled. In some places, tankoubons are considered to have a tagset
equal to the union of all their constituent archives. This is sensible
for bare tags, but problematic for metadata tags with prefixes. In
particular, if a tankoubon has multiple tags prefixed "artist" etc,
then a search sorting on the artist prefix is ambiguous. (This problem
also applies to archives that simply have more than one artist: tag in
their native tagset.)

Currently, the handling of this case for archives is that the system
picks an arbitrary one of the matching tags to use for the sort
key. (Specifically, it's the first one in the serialized tag string.)
Tag string serialization has no defined order, so which tag is
selected will depend on the source of the tag and the order in which
operations are executed.

It's not clear how this problem is correctly handled, in the general
case. For this particular bug fix, I just punt: when sorting by a tag
prefix, tankoubons use only the tank's native set of tags, ignoring
any tags on the constituent archives.
this just uses the thumbnail of the first archive in the tankoubon
This route is used to view tankoubons. In the future, it will display
all tank metadata, allow editing that metadata, and allow
reordering/removing/adding archives to the tankoubon. This commit just
views the current contents.

This does not use DataTables, but builds a similar UI manually. All
tankoubon info is fetched to the client, and UI handling done
client-side. Some functions from index.js and index_datatables.js have
been moved to common.js in order to make them available here.

Tankoubon results in searches are updated to link to this viewing
page, instead of the reader mode (which won't function with tank IDs
anyway).
This adds Sortable.js to the frontend dependencies, then uses it to
enable manually reordering archive entries from the tankoubon view.
previously, the sortedset results of a tankoubon query were ordered in
the result array by a string compare, not a numeric compare. this
would order results as [1, 10, 11, 12, 2, 3, 4...] rather than the
correct [1, 2, 3, 4, 10, 11, 12].

This caused the order to display incorrectly on view. It also caused
instability when editing the order of tankoubon entries, because the
frontend would fetch the incorrect order, then set the new order to be
the incorrect one. Round-tripping the order via GET -> PUT would
therefore shuffle the entries.
This changes the data model in the Redis mock to model sorted sets
properly, adds a few missing methods, and adds some new data necessary
for full tankoubon testing.
Bug the first: when a tank with a mixed-case title was created, it
didn't appear in title searches, because the title was stored in
original case but searches coerce to lower case for
case-insensitivity. Fix: store the title in lower case, like archives
are.

Bug the second: when a tank was deleted, archives in it didn't appear
in tankgrouped searches despite no longer being in a tank, because
they weren't added back to the LRR_TANKGROUPED index. Fix: add them to
that index.
previously, tankoubon tags in search results were created from the
union of all member tags, without including the tank's own tags and
without deduplicating

this includes the tank's tags and deduplicates the whole set
A tankoubon has both its own tags on the tank itself, and imputed tags
from the union of the tags on the contained archives. Tag searches
should use both tagsets.

This requires updating the tag index sets for the imputed tags on a
given tankoubon, after any operation that could change those imputed
tags — i.e. any operation that changes the set of archives in a
tankoubon, or changes the set of tags on any archive in a tankoubon.
The new utility function update_tank_imputed_indexes handles this.

update_tank_imputed_indexes is called in update_archive_list,
add_to_tankoubon, remove_from_tankoubon, and set_tags. Note that for
the last of these, it must call it for every tankoubon that contains a
given archive; get_tankoubons_containing_archive is used for
this. There's potentially a performance issue, because that function
is O(n) in the number of tankoubons in the DB. I have deferred
optimizations until the issue is actually demonstrated.

Note that the $removed_tags parameter to update_tank_imputed_indexes
should contain every tag that this operation theoretically might have
removed from the tank. The function will check all these against the
actual new full tagset before removing any.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a selection mode/mechanism to the main Index

1 participant