Skip to content

feat: search containers and group them by Compose project - #335

Merged
nofuturekid merged 4 commits into
mainfrom
feat/container-search-and-grouping
Nov 13, 2026
Merged

nofuturekid merged 4 commits into
mainfrom
feat/container-search-and-grouping

Conversation

@nofuturekid

Copy link
Copy Markdown
Collaborator

What changed

Search (Docker tab). The tab already had a search box that matched name and image, but it kept its text only inside the tab (lost on every tab switch), had no clear button and showed a blank list when nothing matched. Now:

  • The text is held in MainScreen with rememberSaveable, so it survives tab switches and rotation.
  • The filter is a pure function (filterContainers): case-insensitive, surrounding spaces ignored, blank query returns everything in the original order.
  • A clear (x) button appears while there is text, and an empty-result state ("No matching containers") replaces the blank list. It works in every layout.

Group by Compose project. New Docker view option "Compose" (Settings > Layout > Docker view), next to List / Grid / Grouped. It uses the label com.docker.compose.project; containers without it are listed under "No Compose project", always last. Projects are sorted by name (case-insensitive); containers keep the server's order inside a group. Row actions and the update banner use the same code as the other layouts.

API. GetDockerContainers now also requests labels. Checked against the upstream schema: DockerContainer.labels: JSON is present in unraid/api v4.29.2 and v4.30.0 (the app's documented floor), so older servers within the supported range keep working. It is a field of the docker query, so it needs the same DOCKER read permission the list already needs; no extra permission. The hand-written schema.graphqls gains the field. Not verified against a live server (no server available to this run).

Touched outside the Docker tab, minimal: LayoutMode gets a Compose value (persisted like the others; VMs and Array do not offer it and treat it as Grouped, one-line when change each), Container.composeProject (default null), and UnraidRepository.kt is untouched.

Deliberately left out

  • Grouping by the web interface's own Docker folders (the organizer API): its minimum API version is unverified and a capability model is being designed in parallel. Follow-up noted on Search containers and group them by Compose project or Docker folder #318.
  • Collapsible groups: the existing Grouped layout is not collapsible, so the Compose layout is not either.
  • The Overview, the GraphQL request-limit check and the capability model for read-only keys.

Tests

  • ContainerListingTest (10): search matches name and image, ignores case and spaces, blank query returns everything; grouping is sorted with unlabeled last, stable inside groups, loses no container, a project named like the fallback stays separate.
  • ComposeProjectMappingTest (4): label read, trimming, missing/blank/odd label shapes give no project.
  • ./scripts/local-ci.sh green (lint, both flavors assembled, unit tests).
  • Not tested on a device: the Settings segmented control now has four entries and may wrap its label on very narrow screens.

Closes #318

🤖 Generated with Claude Code

nofuturekid and others added 4 commits November 13, 2026 17:40
…d 7.4

Unraid 7.4.0 refuses requests above a cost of 1,000, depth 20, 100 aliases
and 5,000 GraphQL tokens (unraid/api request-protection.ts, graphql-armor
3.2.0). A query that grows past them would only show up as a failed screen.

GraphqlRequestLimitsTest re-implements the server's formulas (documented
with their source in GraphqlDocumentMetrics), measures every operation in
app/src/main/graphql as Apollo sends it and fails, naming the operation and
the measure, when one passes 70 percent of a limit. Its other tests pin the
formulas to the server's own boundaries. HANDOFF.md records the limits, the
margin and the result measured on a real Unraid 7.4.0.

No app code changes: the largest operation (GetArray) costs 59 of 1,000.

Closes #320

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A card at the top of the Overview lists what needs attention, most urgent
first: an array that is not started or is degraded, a parity operation that is
running, paused or failed, disks with errors, disks at or above their warning
or critical temperature, and unread alert and warning notifications. Tapping a
row opens the Array tab or the notifications. The card is hidden when nothing
needs attention and while the server is offline.

The rules are one pure function in the data layer (attentionItems) that returns
items with a severity, a stable key per condition, a title, a detail and a
target, so background alerts and a widget can reuse it. It reads only data the
app already loads. The array mapper now also keeps how the last parity run
ended (the query already asked for it).

Closes #319

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The Docker tab already filtered by name and image, but the text was lost on
every tab switch, there was no clear button and an empty result showed a
blank list. The search text now lives in MainScreen (rememberSaveable), the
filter is a pure function that ignores case and surrounding spaces, and a
"No matching containers" state appears when nothing matches.

New Docker view option "Compose" groups containers by the label
com.docker.compose.project; containers without it go into "No Compose
project", listed last. GetDockerContainers now also requests the existing
DockerContainer.labels field (present since API 4.29, same docker:read
permission as the rest of the query).

Not built: grouping by the web interface's Docker folders (organizer API);
collapsible groups (the existing grouped layout is not collapsible either).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Correct the labels comment in the schema and the KDoc of the compose
project mapping test: upstream sends an empty object for containers
without labels, the field is only nullable in the schema type.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@nofuturekid
nofuturekid force-pushed the feat/container-search-and-grouping branch from ee06432 to dcfb183 Compare November 13, 2026 16:49
@nofuturekid
nofuturekid merged commit dcfb183 into main Nov 13, 2026
12 checks passed
@nofuturekid
nofuturekid deleted the feat/container-search-and-grouping branch November 13, 2026 16:58
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.

Search containers and group them by Compose project or Docker folder

1 participant