Compare commits

..

5 Commits

Author SHA1 Message Date
CI
f5294eee84 chore: release version v1.90.3 2025-12-11 00:17:06 +00:00
Dmitry Popov
a5c87b6fa4 Merge branch 'main' of github.com:wanderer-industries/wanderer 2025-12-11 01:16:27 +01:00
Dmitry Popov
eae275f515 fix(core): added pagination for long ACL lists 2025-12-11 01:16:24 +01:00
CI
68ae6706dd chore: [skip ci] 2025-12-10 23:56:28 +00:00
CI
a34b30af15 chore: release version v1.90.2 2025-12-10 23:56:28 +00:00
4 changed files with 88 additions and 13 deletions

View File

@@ -2,6 +2,24 @@
<!-- changelog -->
## [v1.90.3](https://github.com/wanderer-industries/wanderer/compare/v1.90.2...v1.90.3) (2025-12-11)
### Bug Fixes:
* core: added pagination for long ACL lists
## [v1.90.2](https://github.com/wanderer-industries/wanderer/compare/v1.90.1...v1.90.2) (2025-12-10)
### Bug Fixes:
* core: added system position updates to SSE
## [v1.90.1](https://github.com/wanderer-industries/wanderer/compare/v1.90.0...v1.90.1) (2025-12-08)

View File

@@ -5,6 +5,8 @@ defmodule WandererAppWeb.AccessListsLive do
require Ash.Query
require Logger
@members_per_page 50
@impl true
def mount(_params, %{"user_id" => user_id} = _session, socket) when not is_nil(user_id) do
{:ok, characters} = WandererApp.Api.Character.active_by_user(%{user_id: user_id})
@@ -25,7 +27,9 @@ defmodule WandererAppWeb.AccessListsLive do
user_id: user_id,
access_lists: access_lists |> Enum.map(fn acl -> map_ui_acl(acl, nil) end),
characters: characters,
members: []
members: [],
members_page: 1,
members_per_page: @members_per_page
)}
end
@@ -39,7 +43,9 @@ defmodule WandererAppWeb.AccessListsLive do
allow_acl_creation: false,
access_lists: [],
characters: [],
members: []
members: [],
members_page: 1,
members_per_page: @members_per_page
)}
end
@@ -93,10 +99,8 @@ defmodule WandererAppWeb.AccessListsLive do
|> assign(:page_title, "Access Lists - Members")
|> assign(:selected_acl_id, acl_id)
|> assign(:access_list, access_list)
|> assign(
:members,
members
)
|> assign(:members, members)
|> assign(:members_page, 1)
else
_ ->
socket
@@ -324,6 +328,20 @@ defmodule WandererAppWeb.AccessListsLive do
{:noreply, assign(socket, form: form)}
end
@impl true
def handle_event("members_prev_page", _, socket) do
new_page = max(1, socket.assigns.members_page - 1)
{:noreply, assign(socket, :members_page, new_page)}
end
@impl true
def handle_event("members_next_page", _, socket) do
total_members = length(socket.assigns.members)
max_page = max(1, ceil(total_members / socket.assigns.members_per_page))
new_page = min(max_page, socket.assigns.members_page + 1)
{:noreply, assign(socket, :members_page, new_page)}
end
@impl true
def handle_event("noop", _, socket) do
{:noreply, socket}
@@ -719,6 +737,17 @@ defmodule WandererAppWeb.AccessListsLive do
acl |> Map.put(:selected, acl.id == selected_id)
end
defp paginated_members(members, page, per_page) do
members
|> Enum.sort_by(&{&1.role, &1.name}, &<=/2)
|> Enum.drop((page - 1) * per_page)
|> Enum.take(per_page)
end
defp total_pages(members, per_page) do
max(1, ceil(length(members) / per_page))
end
# Broadcast ACL update and invalidate map_characters cache for all maps using this ACL
# This ensures the tracking page shows updated members even when map server isn't running
defp broadcast_acl_updated(acl_id) do
@@ -742,7 +771,9 @@ defmodule WandererAppWeb.AccessListsLive do
end)
{:error, error} ->
Logger.warning("Failed to invalidate map_characters cache for ACL #{acl_id}: #{inspect(error)}")
Logger.warning(
"Failed to invalidate map_characters cache for ACL #{acl_id}: #{inspect(error)}"
)
end
end
end

View File

@@ -82,11 +82,14 @@
</h3>
<div
class="dropzone droppable draggable-dropzone--occupied flex flex-col gap-1 w-full rounded-none h-[calc(100vh-211px)] !overflow-y-auto"
class={[
"dropzone droppable draggable-dropzone--occupied flex flex-col gap-1 w-full rounded-none h-[calc(100vh-191px)] !overflow-y-auto",
classes("!h-[calc(100vh-240px)]": length(@members) > @members_per_page)
]}
id="acl_members"
>
<div
:for={member <- @members |> Enum.sort_by(&{&1.role, &1.name}, &<=/2)}
:for={member <- paginated_members(@members, @members_page, @members_per_page)}
draggable="true"
id={member.id}
class="draggable !p-1 h-10 cursor-move bg-black bg-opacity-25 hover:text-white"
@@ -113,10 +116,32 @@
</div>
</div>
</div>
<div>
<div :if={length(@members) > @members_per_page} class="flex items-center justify-between px-3 py-2 border-t border-gray-500 bg-black bg-opacity-25">
<span class="text-sm text-gray-400">
Page {@members_page} of {total_pages(@members, @members_per_page)} ({length(@members)} members)
</span>
<div class="flex gap-2">
<button
phx-click="members_prev_page"
disabled={@members_page <= 1}
class={"btn btn-sm btn-ghost " <> if(@members_page <= 1, do: "btn-disabled", else: "")}
>
<.icon name="hero-chevron-left" class="w-4 h-4" />
</button>
<button
phx-click="members_next_page"
disabled={@members_page >= total_pages(@members, @members_per_page)}
class={"btn btn-sm btn-ghost " <> if(@members_page >= total_pages(@members, @members_per_page), do: "btn-disabled", else: "")}
>
<.icon name="hero-chevron-right" class="w-4 h-4" />
</button>
</div>
</div>
</div>
<.link
:if={@selected_acl_id != "" and can_add_members?(@access_list, @current_user)}
class="btn mt-2 w-full btn-neutral rounded-none"
class="btn w-full btn-neutral rounded-none"
patch={~p"/access-lists/#{@selected_acl_id}/add-members"}
>
<.icon name="hero-plus-solid" class="w-6 h-6" />
@@ -129,6 +154,7 @@
<.icon name="hero-plus-solid" class="w-6 h-6" />
<h3 class="card-title text-center text-md">Add Members</h3>
</div>
</div>
</div>
</main>
</div>
@@ -153,10 +179,10 @@
placeholder="Select an owner"
options={Enum.map(@characters, fn character -> {character.label, character.id} end)}
/>
<!-- Divider between above inputs and the API key section -->
<hr class="my-4 border-gray-600" />
<!-- API Key Section with grid layout -->
<div class="mt-2">
<label class="block text-sm font-medium text-gray-200 mb-1">ACL API key</label>

View File

@@ -3,7 +3,7 @@ defmodule WandererApp.MixProject do
@source_url "https://github.com/wanderer-industries/wanderer"
@version "1.90.1"
@version "1.90.3"
def project do
[