Skip to content

feat(proxy-hosts): group label for organising hosts#5452

Open
BuenGenio wants to merge 4 commits into
NginxProxyManager:developfrom
BuenGenio:feature/proxy-host-group-label
Open

feat(proxy-hosts): group label for organising hosts#5452
BuenGenio wants to merge 4 commits into
NginxProxyManager:developfrom
BuenGenio:feature/proxy-host-group-label

Conversation

@BuenGenio

Copy link
Copy Markdown

Summary

Adds an optional group label on each proxy host so users can organise the list (e.g. by organisation, project, or any free-text label).

Changes

  • Database: migration 20260402000000_host_group_label.js adds host_group_label (string, default empty) to proxy_host.
  • API: OpenAPI / JSON Schema updated on proxy-host object, POST, and PUT.
  • UI: Group label field on the proxy host Details tab; proxy hosts table groups rows by label with section headers; optional group filter dropdown and search includes label text.
  • i18n: English strings only (en.json); other locales fall back or can be added in follow-up.

Upgrade

Migrations run automatically on backend startup (existing NPM upgrade flow).

Notes

Non-English locale files were not updated in this PR.

Add optional host_group_label on proxy_host (migration + OpenAPI).
UI: edit label in proxy host modal, group rows on list page with
filter dropdown. English locale strings included.
Vacuum oas3-valid-schema-example requires examples to include all
required proxy-host-object properties.
@nginxproxymanagerci

Copy link
Copy Markdown

Docker Image for build 2 is available on DockerHub:

nginxproxymanager/nginx-proxy-manager-dev:pr-5452

Note

Ensure you backup your NPM instance before testing this image! Especially if there are database changes.
This is a different docker image namespace than the official image.

Warning

Changes and additions to DNS Providers require verification by at least 2 members of the community!

@jc21

jc21 commented May 14, 2026

Copy link
Copy Markdown
Member

Thanks for this PR — grouping proxy hosts is a frequently requested quality-of-life feature and the overall approach is solid. A few things to address before merging:

Bug — column sorting broken within groups

In Table.tsx, groups are rendered by iterating group.rows (raw data insertion order) and looking up the TanStack Row object via rowsByOriginalId. Because the visual order follows group.rows rather than tableInstance.getRowModel().rows, clicking a column header to sort has no effect on intra-group row order.

The fix is to iterate tableInstance.getRowModel().rows and insert group-header <tr> rows whenever the hostGroupLabel changes (i.e. on label transitions), rather than iterating raw groups and looking up rows by ID. That way TanStack's sort model drives the order natively.

Note: Apologies for the extra work here — table column sorting was only just merged after this PR was created, so this conflict wasn't visible at the time. Sorry for the moving target.

Minor issues

  • Indentation bug in useProxyHost.tshostGroupLabel: "" is indented one level short compared to its siblings.
  • Hardcoded English placeholder in ProxyHostModal.tsx ("e.g. Production, Development, My Project") bypasses the i18n system — should use intl.formatMessage with a key in en.json.
  • No Yup validation rule for hostGroupLabel — the is-invalid CSS class check in the field template will never trigger since there is no validation rule wired up. Browser-level maxLength={150} works but doesn't give users a form-level error message consistent with the rest of the form.
  • Magic string sentinel"__all__" for "show all groups" could technically collide with a real group name. A null state or separate boolean would be safer.

Everything else looks good

  • Migration is correct (NOT NULL DEFAULT '' is safe for existing rows, timestamp ordering is fine).
  • host_group_label added to the required array in the response schema is correct given the DB default.
  • The group filter dropdown and search-includes-label changes are clean.
  • i18n strings are well structured (other locales can follow up separately as noted).

@jc21

jc21 commented May 14, 2026

Copy link
Copy Markdown
Member

This conflicts with #5358 - it would be nice if you both reach a consensus on who's got the best approach. If not I will eventually have to make that call.

BuenGenio added 2 commits May 22, 2026 11:51
- Table: drive group rendering off the table row model (instead of raw
  data + ID lookup) so column sorting can order rows within each group
- ProxyHostModal: i18n the group-label placeholder and add a length
  validation rule with inline error feedback
- TableWrapper: replace the "__all__" group-filter sentinel with a null
  state and collision-free index-based option values
- useProxyHost: fix indentation of the hostGroupLabel default value
Resolves a conflict in ProxyHosts/Table.tsx between this branch's group
labelling and develop's new column-sorting feature (PR NginxProxyManager#5520).

The group label is now a hidden, sort-only column pinned as the primary
sort key, so each group's rows stay contiguous in the row model while a
column the user clicks sorts rows within each group.
@BuenGenio

Copy link
Copy Markdown
Author

Why

Proxy hosts pile up once you manage more than a handful, with no built-in way
to organise them. This adds an optional free-text group label on each proxy
host so the list can be grouped by organisation, project, or any label the user
chooses.

  • Hosts sharing a label are shown together under a group heading in the Proxy
    Hosts table.
  • A group filter dropdown narrows the list to a single group.
  • Search now also matches the group label.

The label is optional and defaults to an empty string, so existing hosts and API
clients are unaffected — the migration adds the column as NOT NULL DEFAULT ''.

Changes

Backend

  • Migration 20260402000000_host_group_label.js adds host_group_label
    (NOT NULL DEFAULT '').
  • OpenAPI schema: host_group_label added to the proxy-host object and to the
    GET / POST / PUT paths.

Frontend

  • ProxyHostModal: new Group Label field with an i18n placeholder and length
    validation (≤ 150 chars) with inline error feedback.
  • ProxyHosts/TableWrapper: group filter dropdown; search includes the label.
  • ProxyHosts/Table: rows are grouped under headings. The group label is a
    hidden, pinned primary sort key, so groups stay contiguous while a column the
    user clicks sorts rows within each group.

This branch has been merged up to current develop, which resolved a conflict
with the newly-merged column-sorting feature (#5520).

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Code refactoring
  • API changes
  • Performance improvement
  • Test addition or update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants