3x-ui/web/controller
MHSanaei 530e338c66
refactor(clients): coherent group management — rename, split, extract
This bundles a set of group-related improvements that built up across
one session and only make sense together.

Terminology / API surface:
- Rename "assign group" → "add to group" everywhere: i18n keys,
  callback names (bulkAddToGroup), component + file names
  (BulkAddToGroupModal, AddClientsToGroupModal), Go controller/struct
  names (bulkAddToGroup, AddToGroup), OpenAPI summaries. Nothing keeps
  the word "assign" anymore.
- Move group routes under /panel/api/clients/groups/* (was
  /bulkAssignGroup at the clients root).
- Split add and remove into two endpoints: /groups/bulkAdd now rejects
  empty group; new /groups/bulkRemove clears the label for the given
  emails. The old "submit empty to clear" UX is gone — Ungroup is its
  own action.

UI affordances on Clients page:
- Promote Group + Ungroup to visible bar buttons next to Attach +
  Detach. Group reuses BulkAddToGroupModal; Ungroup pops a danger
  confirm and calls bulkRemoveFromGroup.
- Custom UngroupIcon (TagsOutlined with a diagonal strike) for the
  Ungroup button so the pairing reads at a glance.
- Hide the Group column when no clients have a group label yet —
  removes a column of em-dashes on fresh installs.

UI on Groups page:
- New per-row Add clients… / Remove clients… actions backed by
  GroupAddClientsModal and GroupRemoveClientsModal: rich client picker
  (email / comment / current group / enable) with search and
  preserveSelectedRowKeys, mirroring the inbounds Attach modal UX.

Controller split:
- Move all /groups/* routes, handlers, and request bodies out of
  web/controller/client.go into a dedicated web/controller/group.go
  (GroupController with leaner clientService + xrayService
  dependencies). URLs are byte-identical because the new controller
  registers on the same parent gin.RouterGroup; api_docs_test.go gets
  a group.go → /panel/api/clients basePath entry so its route
  extraction keeps working.

Invalidation dedup:
- Removing a client from a group on the Groups page used to refetch
  /clients/groups and /clients/onlines three times: once from the
  mutation's onSuccess, once from a redundant invalidate() in the
  page's onSubmit, once from the WebSocket invalidate broadcast that
  the backend fires after every mutation. The manual invalidate() is
  gone, and a small invalidationTracker module lets websocketBridge
  skip WS-driven invalidates that arrive within 1.5s of a local
  invalidate — bringing the refetch count down to one. The WS path
  still works for changes made by another tab or user.
2026-05-28 12:59:20 +02:00
..
api.go refactor(clients): coherent group management — rename, split, extract 2026-05-28 12:59:20 +02:00
api_docs_test.go refactor(clients): coherent group management — rename, split, extract 2026-05-28 12:59:20 +02:00
base.go v3 2026-05-10 02:13:42 +02:00
client.go refactor(clients): coherent group management — rename, split, extract 2026-05-28 12:59:20 +02:00
custom_geo.go v3 2026-05-10 02:13:42 +02:00
dist.go feat(frontend): TanStack Query + React Router migration & in-panel API docs (#4541) 2026-05-24 21:34:52 +02:00
group.go refactor(clients): coherent group management — rename, split, extract 2026-05-28 12:59:20 +02:00
inbound.go refactor(inbound-tag): node-prefixed + transport-suffixed canonical shape 2026-05-27 19:14:22 +02:00
index.go fix(auth): invalidate sessions when 2FA is enabled, fix dev 401 loop 2026-05-13 14:08:16 +02:00
login_limiter.go Implement CSRF protection and security hardening across the application (#4179) 2026-05-07 23:36:11 +02:00
login_limiter_test.go refactor(websocket): split controller into service + thin controller 2026-05-08 00:00:44 +02:00
node.go feat: complete Zod migration of frontend + bulk client batching (#4599) 2026-05-27 04:26:50 +02:00
server.go Feat/multi inbound clients (#4469) 2026-05-19 12:20:24 +02:00
setting.go feat: complete Zod migration of frontend + bulk client batching (#4599) 2026-05-27 04:26:50 +02:00
util.go Client/inbound resilience + Postgres pool tuning + schema fixes (#4607) 2026-05-27 22:51:37 +02:00
util_test.go Security hardening: sessions, SSRF, CSP nonce, CSRF logout, trusted proxies (#4275) 2026-05-13 12:52:52 +02:00
websocket.go v3 2026-05-10 02:13:42 +02:00
xray_setting.go Security hardening: sessions, SSRF, CSP nonce, CSRF logout, trusted proxies (#4275) 2026-05-13 12:52:52 +02:00
xui.go feat(frontend): TanStack Query + React Router migration & in-panel API docs (#4541) 2026-05-24 21:34:52 +02:00