Compare commits

...

12 Commits

Author SHA1 Message Date
CI
ef9fa80b76 chore: release version v1.0.18 2024-09-22 09:14:52 +00:00
Dmitry Popov
dc2ea625ec fix(ACL): Cant delete ACL list after map deletion #5
Fixes #6
2024-09-22 13:11:03 +04:00
Dmitry Popov
17df2c188a chore: release version v1.0.16 2024-09-22 12:11:46 +04:00
Dmitry Popov
6e050bccdf Merge branch 'main' of github.com:wanderer-industries/wanderer 2024-09-22 11:48:10 +04:00
Dmitry Popov
8afbf3ce91 chore: release version v1.0.16 2024-09-22 11:48:07 +04:00
CI
9f57bf46a1 chore: release version v1.0.17 2024-09-21 11:23:48 +00:00
Dmitry Popov
4ce47da521 chore: release version v1.0.16 2024-09-21 15:23:09 +04:00
CI
4dc6382402 chore: release version v1.0.16 2024-09-21 09:24:55 +00:00
Aleksei Chichenkov
cb8c1e32d9 Merge pull request #10 from wanderer-industries/fix-wnd-6
fix(Map): add key for cache changes detecting
2024-09-21 12:24:30 +03:00
achichenkov
bf534be128 fix(Map): commented console log
Fixes #6
2024-09-21 12:19:48 +03:00
achichenkov
c0ceff1eec fix(Map): add console log for check sys loading
Fixes #6
2024-09-21 11:47:19 +03:00
achichenkov
c7866a1270 fix(Map): add key for cache changes detecting
Fixes #6
2024-09-21 11:26:25 +03:00
15 changed files with 895 additions and 246 deletions

View File

@@ -2,6 +2,33 @@
<!-- changelog -->
## [v1.0.18](https://github.com/wanderer-industries/wanderer/compare/v1.0.17...v1.0.18) (2024-09-22)
### Bug Fixes:
* ACL: Cant delete ACL list after map deletion #5
## [v1.0.17](https://github.com/wanderer-industries/wanderer/compare/v1.0.16...v1.0.17) (2024-09-21)
## [v1.0.16](https://github.com/wanderer-industries/wanderer/compare/v1.0.15...v1.0.16) (2024-09-21)
### Bug Fixes:
* Map: commented console log
* Map: add console log for check sys loading
* Map: add key for cache changes detecting
## [v1.0.15](https://github.com/wanderer-industries/wanderer/compare/v1.0.14...v1.0.15) (2024-09-21)

View File

@@ -38,7 +38,7 @@ export const RoutesWidgetContent = () => {
const { loading } = useLoadRoutes();
const { systems: systemStatics, loadSystems } = useLoadSystemStatic({ systems: hubs ?? [] });
const { systems: systemStatics, loadSystems, lastUpdateKey } = useLoadSystemStatic({ systems: hubs ?? [] });
const { open, ...systemCtxProps } = useContextMenuSystemInfoHandlers({
outCommand,
hubs,
@@ -51,7 +51,8 @@ export const RoutesWidgetContent = () => {
return { ...systemStatics.get(parseInt(x))!, ...(sys && { customName: sys.name ?? '' }) };
});
}, [hubs, systems, systemStatics]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hubs, systems, systemStatics, lastUpdateKey]);
const preparedRoutes = useMemo(() => {
return (
@@ -114,6 +115,10 @@ export const RoutesWidgetContent = () => {
{preparedRoutes.map(route => {
const sys = preparedHubs.find(x => x.solar_system_id === route.destination)!;
// TODO do not delte this console log
// eslint-disable-next-line no-console
// console.log('JOipP', `Check sys [${route.destination}]:`, sys);
return (
<>
<div className="flex gap-2 items-center">

View File

@@ -27,12 +27,14 @@ interface UseLoadSystemStaticProps {
export const useLoadSystemStatic = ({ systems }: UseLoadSystemStaticProps) => {
const { outCommand } = useMapRootState();
const [loading, setLoading] = useState(false);
const [lastUpdateKey, setLastUpdateKey] = useState(0);
const ref = useRef({ outCommand });
ref.current = { outCommand };
const addSystemStatic = useCallback((static_info: SolarSystemStaticInfoRaw) => {
cache.set(static_info.solar_system_id, static_info);
setLastUpdateKey(new Date().getTime());
}, []);
const loadSystems = useCallback(async (systems: (number | string)[]) => {
@@ -43,6 +45,7 @@ export const useLoadSystemStatic = ({ systems }: UseLoadSystemStaticProps) => {
if (toLoad.length > 0) {
const res = await loadSystemStaticInfo(ref.current.outCommand, toLoad);
res.forEach(x => cache.set(x.solar_system_id, x));
setLastUpdateKey(new Date().getTime());
}
setLoading(false);
}, []);
@@ -52,5 +55,5 @@ export const useLoadSystemStatic = ({ systems }: UseLoadSystemStaticProps) => {
// eslint-disable-next-line
}, [systems]);
return { addSystemStatic, systems: cache, loading, loadSystems };
return { addSystemStatic, systems: cache, lastUpdateKey, loading, loadSystems };
};

61
flake.lock generated Normal file
View File

@@ -0,0 +1,61 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1726560853,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1726871744,
"narHash": "sha256-V5LpfdHyQkUF7RfOaDPrZDP+oqz88lTJrMT1+stXNwo=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "a1d92660c6b3b7c26fb883500a80ea9d33321be2",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View File

@@ -104,6 +104,12 @@ defmodule WandererApp.Api.AccessListMember do
end
end
postgres do
references do
reference :access_list, on_delete: :delete
end
end
identities do
identity :uniq_acl_character_id, [:access_list_id, :eve_character_id] do
pre_check?(true)

View File

@@ -44,6 +44,13 @@ defmodule WandererApp.Api.MapAccessList do
belongs_to :access_list, WandererApp.Api.AccessList, primary_key?: true, allow_nil?: false
end
postgres do
references do
reference :map, on_delete: :delete
reference :access_list, on_delete: :delete
end
end
identities do
identity :unique_map_acl, [:map_id, :access_list_id] do
pre_check?(false)

View File

@@ -238,8 +238,8 @@ defmodule WandererAppWeb.AccessListsLive do
def handle_event("delete-acl", %{"id" => acl_id} = _params, socket) do
case socket.assigns.access_lists
|> Enum.find(&(&1.id == acl_id))
|> WandererApp.Api.AccessList.destroy() do
{:ok, _acl} ->
|> WandererApp.Api.AccessList.destroy!() do
:ok ->
Phoenix.PubSub.broadcast(
WandererApp.PubSub,
"acls:#{acl_id}",
@@ -252,7 +252,7 @@ defmodule WandererAppWeb.AccessListsLive do
socket
|> assign(access_lists: access_lists |> Enum.map(fn acl -> map_ui_acl(acl, nil) end))}
_error ->
error ->
{:noreply,
socket
|> put_flash(
@@ -261,7 +261,7 @@ defmodule WandererAppWeb.AccessListsLive do
)}
end
rescue
_ ->
_error ->
{:noreply,
socket
|> put_flash(

View File

@@ -65,10 +65,9 @@ defmodule WandererAppWeb.MapLive do
})
{:ok,
%{
deleted: true
} = map} ->
%{
deleted: true
} = map} ->
socket
|> put_flash(
:error,
@@ -419,7 +418,11 @@ defmodule WandererAppWeb.MapLive do
{:noreply,
socket
|> assign(map_loaded?: true, user_characters: user_character_eve_ids, has_tracked_characters?: _has_tracked_characters?(user_character_eve_ids))
|> assign(
map_loaded?: true,
user_characters: user_character_eve_ids,
has_tracked_characters?: _has_tracked_characters?(user_character_eve_ids)
)
|> _push_map_event("init", initial_data)
|> push_event("js-exec", %{
to: "#map-loader",
@@ -489,24 +492,31 @@ defmodule WandererAppWeb.MapLive do
end
@impl true
def handle_event("manual_add_system", %{"coordinates" => coordinates} = _event, %{assigns: %{has_tracked_characters?: has_tracked_characters?}} = socket) do
def handle_event(
"manual_add_system",
%{"coordinates" => coordinates} = _event,
%{assigns: %{has_tracked_characters?: has_tracked_characters?}} = socket
) do
case has_tracked_characters? do
true ->
case _check_user_permissions(socket, :add_system) do
true ->
{:noreply,
socket
|> assign(coordinates: coordinates)
|> push_patch(to: ~p"/#{socket.assigns.map_slug}/add-system")}
socket
|> assign(coordinates: coordinates)
|> push_patch(to: ~p"/#{socket.assigns.map_slug}/add-system")}
_ ->
{:noreply, socket}
end
_ ->
{:noreply, socket |> put_flash(
:error,
"You should enable tracking for at least one character to add system."
)}
{:noreply,
socket
|> put_flash(
:error,
"You should enable tracking for at least one character to add system."
)}
end
end
@@ -514,189 +524,225 @@ defmodule WandererAppWeb.MapLive do
def handle_event(
"manual_add_connection",
%{"source" => solar_system_source_id, "target" => solar_system_target_id} = _event,
%{assigns: %{current_user: current_user, tracked_character_ids: tracked_character_ids, has_tracked_characters?: has_tracked_characters?}} =
%{
assigns: %{
current_user: current_user,
tracked_character_ids: tracked_character_ids,
has_tracked_characters?: has_tracked_characters?
}
} =
socket
) do
case has_tracked_characters? do
true ->
case _check_user_permissions(socket, :add_connection) do
true ->
map_id =
socket
|> map_id()
case has_tracked_characters? do
true ->
case _check_user_permissions(socket, :add_connection) do
true ->
map_id =
socket
|> map_id()
map_id
|> WandererApp.Map.Server.add_connection(%{
solar_system_source_id: solar_system_source_id |> String.to_integer(),
solar_system_target_id: solar_system_target_id |> String.to_integer()
})
map_id
|> WandererApp.Map.Server.add_connection(%{
solar_system_source_id: solar_system_source_id |> String.to_integer(),
solar_system_target_id: solar_system_target_id |> String.to_integer()
})
:telemetry.execute([:wanderer_app, :map, :connection, :add], %{count: 1}, %{
character_id: tracked_character_ids |> List.first(),
user_id: current_user.id,
map_id: map_id,
solar_system_source_id: "#{solar_system_source_id}" |> String.to_integer(),
solar_system_target_id: "#{solar_system_target_id}" |> String.to_integer()
})
:telemetry.execute([:wanderer_app, :map, :connection, :add], %{count: 1}, %{
character_id: tracked_character_ids |> List.first(),
user_id: current_user.id,
map_id: map_id,
solar_system_source_id: "#{solar_system_source_id}" |> String.to_integer(),
solar_system_target_id: "#{solar_system_target_id}" |> String.to_integer()
})
{:noreply, socket}
{:noreply, socket}
_ ->
{:noreply, socket}
end
_ ->
{:noreply, socket |> put_flash(
:error,
"You should enable tracking for at least one character to add connection."
)}
end
_ ->
{:noreply, socket}
end
_ ->
{:noreply,
socket
|> put_flash(
:error,
"You should enable tracking for at least one character to add connection."
)}
end
end
@impl true
def handle_event(
"add_hub",
%{"system_id" => solar_system_id} = _event,
%{assigns: %{current_user: current_user, tracked_character_ids: tracked_character_ids, has_tracked_characters?: has_tracked_characters?}} =
%{
assigns: %{
current_user: current_user,
tracked_character_ids: tracked_character_ids,
has_tracked_characters?: has_tracked_characters?
}
} =
socket
) do
case has_tracked_characters? do
case has_tracked_characters? do
true ->
case _check_user_permissions(socket, :update_system) do
true ->
case _check_user_permissions(socket, :update_system) do
true ->
map_id =
socket
|> map_id()
map_id =
socket
|> map_id()
:telemetry.execute([:wanderer_app, :map, :hub, :add], %{count: 1}, %{
character_id: tracked_character_ids |> List.first(),
user_id: current_user.id,
map_id: map_id,
solar_system_id: solar_system_id
})
:telemetry.execute([:wanderer_app, :map, :hub, :add], %{count: 1}, %{
character_id: tracked_character_ids |> List.first(),
user_id: current_user.id,
map_id: map_id,
solar_system_id: solar_system_id
})
map_id
|> WandererApp.Map.Server.add_hub(%{
solar_system_id: solar_system_id
})
map_id
|> WandererApp.Map.Server.add_hub(%{
solar_system_id: solar_system_id
})
{:noreply, socket}
{:noreply, socket}
_ ->
{:noreply, socket}
end
_ ->
{:noreply, socket |> put_flash(
:error,
"You should enable tracking for at least one character to add hub."
)}
{:noreply, socket}
end
_ ->
{:noreply,
socket
|> put_flash(
:error,
"You should enable tracking for at least one character to add hub."
)}
end
end
@impl true
def handle_event(
"delete_hub",
%{"system_id" => solar_system_id} = _event,
%{assigns: %{current_user: current_user, tracked_character_ids: tracked_character_ids, has_tracked_characters?: has_tracked_characters?}} =
%{
assigns: %{
current_user: current_user,
tracked_character_ids: tracked_character_ids,
has_tracked_characters?: has_tracked_characters?
}
} =
socket
) do
case has_tracked_characters? do
case has_tracked_characters? do
true ->
case _check_user_permissions(socket, :update_system) do
true ->
case _check_user_permissions(socket, :update_system) do
true ->
map_id =
socket
|> map_id()
map_id =
socket
|> map_id()
:telemetry.execute([:wanderer_app, :map, :hub, :remove], %{count: 1}, %{
character_id: tracked_character_ids |> List.first(),
user_id: current_user.id,
map_id: map_id,
solar_system_id: solar_system_id
})
:telemetry.execute([:wanderer_app, :map, :hub, :remove], %{count: 1}, %{
character_id: tracked_character_ids |> List.first(),
user_id: current_user.id,
map_id: map_id,
solar_system_id: solar_system_id
})
map_id
|> WandererApp.Map.Server.remove_hub(%{
solar_system_id: solar_system_id
})
map_id
|> WandererApp.Map.Server.remove_hub(%{
solar_system_id: solar_system_id
})
{:noreply, socket}
{:noreply, socket}
_ ->
{:noreply, socket}
end
_ ->
{:noreply, socket |> put_flash(
:error,
"You should enable tracking for at least one character to remove hub."
)}
{:noreply, socket}
end
_ ->
{:noreply,
socket
|> put_flash(
:error,
"You should enable tracking for at least one character to remove hub."
)}
end
end
@impl true
def handle_event(
"update_system_" <> param,
%{"system_id" => solar_system_id, "value" => value} = _event,
%{assigns: %{current_user: current_user, tracked_character_ids: tracked_character_ids, has_tracked_characters?: has_tracked_characters?}} =
%{
assigns: %{
current_user: current_user,
tracked_character_ids: tracked_character_ids,
has_tracked_characters?: has_tracked_characters?
}
} =
socket
) do
case has_tracked_characters? do
case has_tracked_characters? do
true ->
case _check_user_permissions(socket, :update_system) do
true ->
case _check_user_permissions(socket, :update_system) do
true ->
method_atom =
case param do
"name" -> :update_system_name
"description" -> :update_system_description
"labels" -> :update_system_labels
"locked" -> :update_system_locked
"tag" -> :update_system_tag
"status" -> :update_system_status
_ -> nil
end
method_atom =
case param do
"name" -> :update_system_name
"description" -> :update_system_description
"labels" -> :update_system_labels
"locked" -> :update_system_locked
"tag" -> :update_system_tag
"status" -> :update_system_status
_ -> nil
end
key_atom =
case param do
"name" -> :name
"description" -> :description
"labels" -> :labels
"locked" -> :locked
"tag" -> :tag
"status" -> :status
_ -> :none
end
key_atom =
case param do
"name" -> :name
"description" -> :description
"labels" -> :labels
"locked" -> :locked
"tag" -> :tag
"status" -> :status
_ -> :none
end
map_id =
socket
|> map_id()
map_id =
socket
|> map_id()
:telemetry.execute([:wanderer_app, :map, :system, :update], %{count: 1}, %{
character_id: tracked_character_ids |> List.first(),
user_id: current_user.id,
map_id: map_id,
solar_system_id: "#{solar_system_id}" |> String.to_integer(),
key: key_atom,
value: value
})
:telemetry.execute([:wanderer_app, :map, :system, :update], %{count: 1}, %{
character_id: tracked_character_ids |> List.first(),
user_id: current_user.id,
map_id: map_id,
solar_system_id: "#{solar_system_id}" |> String.to_integer(),
key: key_atom,
value: value
})
apply(WandererApp.Map.Server, method_atom, [
map_id,
%{
solar_system_id: "#{solar_system_id}" |> String.to_integer()
}
|> Map.put_new(key_atom, value)
])
apply(WandererApp.Map.Server, method_atom, [
map_id,
%{
solar_system_id: "#{solar_system_id}" |> String.to_integer()
}
|> Map.put_new(key_atom, value)
])
{:noreply, socket}
{:noreply, socket}
_ ->
{:noreply, socket}
end
_ ->
{:noreply, socket |> put_flash(
:error,
"You should enable tracking for at least one character to update system."
)}
{:noreply, socket}
end
_ ->
{:noreply,
socket
|> put_flash(
:error,
"You should enable tracking for at least one character to update system."
)}
end
end
@impl true
@@ -707,65 +753,74 @@ defmodule WandererAppWeb.MapLive do
"target" => solar_system_target_id,
"value" => value
} = _event,
%{assigns: %{current_user: current_user, tracked_character_ids: tracked_character_ids, has_tracked_characters?: has_tracked_characters?}} =
%{
assigns: %{
current_user: current_user,
tracked_character_ids: tracked_character_ids,
has_tracked_characters?: has_tracked_characters?
}
} =
socket
) do
case has_tracked_characters? do
case has_tracked_characters? do
true ->
case _check_user_permissions(socket, :update_system) do
true ->
case _check_user_permissions(socket, :update_system) do
true ->
method_atom =
case param do
"time_status" -> :update_connection_time_status
"mass_status" -> :update_connection_mass_status
"ship_size_type" -> :update_connection_ship_size_type
"locked" -> :update_connection_locked
_ -> nil
end
method_atom =
case param do
"time_status" -> :update_connection_time_status
"mass_status" -> :update_connection_mass_status
"ship_size_type" -> :update_connection_ship_size_type
"locked" -> :update_connection_locked
_ -> nil
end
key_atom =
case param do
"time_status" -> :time_status
"mass_status" -> :mass_status
"ship_size_type" -> :ship_size_type
"locked" -> :locked
_ -> nil
end
key_atom =
case param do
"time_status" -> :time_status
"mass_status" -> :mass_status
"ship_size_type" -> :ship_size_type
"locked" -> :locked
_ -> nil
end
map_id =
socket
|> map_id()
map_id =
socket
|> map_id()
:telemetry.execute([:wanderer_app, :map, :connection, :update], %{count: 1}, %{
character_id: tracked_character_ids |> List.first(),
user_id: current_user.id,
map_id: map_id,
solar_system_source_id: "#{solar_system_source_id}" |> String.to_integer(),
solar_system_target_id: "#{solar_system_target_id}" |> String.to_integer(),
key: key_atom,
value: value
})
:telemetry.execute([:wanderer_app, :map, :connection, :update], %{count: 1}, %{
character_id: tracked_character_ids |> List.first(),
user_id: current_user.id,
map_id: map_id,
solar_system_source_id: "#{solar_system_source_id}" |> String.to_integer(),
solar_system_target_id: "#{solar_system_target_id}" |> String.to_integer(),
key: key_atom,
value: value
})
apply(WandererApp.Map.Server, method_atom, [
map_id,
%{
solar_system_source_id: "#{solar_system_source_id}" |> String.to_integer(),
solar_system_target_id: "#{solar_system_target_id}" |> String.to_integer()
}
|> Map.put_new(key_atom, value)
])
apply(WandererApp.Map.Server, method_atom, [
map_id,
%{
solar_system_source_id: "#{solar_system_source_id}" |> String.to_integer(),
solar_system_target_id: "#{solar_system_target_id}" |> String.to_integer()
}
|> Map.put_new(key_atom, value)
])
{:noreply, socket}
{:noreply, socket}
_ ->
{:noreply, socket}
end
_ ->
{:noreply, socket |> put_flash(
:error,
"You should enable tracking for at least one character to update connection."
)}
{:noreply, socket}
end
_ ->
{:noreply,
socket
|> put_flash(
:error,
"You should enable tracking for at least one character to update connection."
)}
end
end
@impl true
@@ -834,11 +889,14 @@ defmodule WandererAppWeb.MapLive do
end)
{:reply, %{signatures: _get_system_signatures(system.id)}, socket}
_ ->
{:reply, %{signatures: []}, socket |> put_flash(
:error,
"You should enable tracking for at least one character to work with signatures."
)}
{:reply, %{signatures: []},
socket
|> put_flash(
:error,
"You should enable tracking for at least one character to work with signatures."
)}
end
_ ->
@@ -973,11 +1031,14 @@ defmodule WandererAppWeb.MapLive do
_ ->
{:noreply, socket}
end
_ ->
{:noreply, socket |> put_flash(
:error,
"You should enable tracking for at least one character to update system."
)}
{:noreply,
socket
|> put_flash(
:error,
"You should enable tracking for at least one character to update system."
)}
end
end
@@ -990,21 +1051,24 @@ defmodule WandererAppWeb.MapLive do
case has_tracked_characters? do
true ->
case _check_user_permissions(socket, :update_system) do
true ->
socket
|> map_id()
|> _update_system_positions(positions)
true ->
socket
|> map_id()
|> _update_system_positions(positions)
{:noreply, socket}
{:noreply, socket}
_ ->
{:noreply, socket}
end
_ ->
{:noreply, socket}
end
_ ->
{:noreply, socket |> put_flash(
:error,
"You should enable tracking for at least one character to update systems."
)}
{:noreply,
socket
|> put_flash(
:error,
"You should enable tracking for at least one character to update systems."
)}
end
end
@@ -1012,7 +1076,13 @@ defmodule WandererAppWeb.MapLive do
def handle_event(
"delete_systems",
solar_system_ids,
%{assigns: %{current_user: current_user, tracked_character_ids: tracked_character_ids, has_tracked_characters?: has_tracked_characters?}} =
%{
assigns: %{
current_user: current_user,
tracked_character_ids: tracked_character_ids,
has_tracked_characters?: has_tracked_characters?
}
} =
socket
) do
case has_tracked_characters? do
@@ -1032,20 +1102,28 @@ defmodule WandererAppWeb.MapLive do
_ ->
{:noreply, socket}
end
_ ->
{:noreply, socket |> put_flash(
:error,
"You should enable tracking for at least one character to delete systems."
)}
end
_ ->
{:noreply,
socket
|> put_flash(
:error,
"You should enable tracking for at least one character to delete systems."
)}
end
end
@impl true
def handle_event(
"manual_delete_connection",
%{"source" => solar_system_source_id, "target" => solar_system_target_id} = _event,
%{assigns: %{current_user: current_user, tracked_character_ids: tracked_character_ids, has_tracked_characters?: has_tracked_characters?}} =
%{
assigns: %{
current_user: current_user,
tracked_character_ids: tracked_character_ids,
has_tracked_characters?: has_tracked_characters?
}
} =
socket
) do
case has_tracked_characters? do
@@ -1075,13 +1153,15 @@ defmodule WandererAppWeb.MapLive do
_ ->
{:noreply, socket}
end
_ ->
{:noreply, socket |> put_flash(
:error,
"You should enable tracking for at least one character to delete connection."
)}
end
_ ->
{:noreply,
socket
|> put_flash(
:error,
"You should enable tracking for at least one character to delete connection."
)}
end
end
@impl true
@@ -1387,14 +1467,14 @@ defmodule WandererAppWeb.MapLive do
[]
end
events =
case map_characters |> Enum.empty?() do
true ->
events ++ [:empty_tracked_characters]
events =
case map_characters |> Enum.empty?() do
true ->
events ++ [:empty_tracked_characters]
_ ->
events
end
_ ->
events
end
{:ok, characters_limit} = map_id |> WandererApp.Map.get_characters_limit()
@@ -1601,7 +1681,6 @@ defmodule WandererAppWeb.MapLive do
:character_eve_id,
:name,
:description,
:custom_info,
:kind,
:group,
:updated_at
@@ -1809,7 +1888,6 @@ defmodule WandererAppWeb.MapLive do
eve_id: eve_id,
name: name,
description: Map.get(signature, "description"),
custom_info: Map.get(signature, "custom_info"),
kind: kind,
group: group,
character_eve_id: character_eve_id

View File

@@ -2,7 +2,7 @@ defmodule WandererApp.MixProject do
use Mix.Project
@source_url "https://github.com/wanderer-industries/wanderer"
@version "1.0.15"
@version "1.0.18"
def project do
[
@@ -111,8 +111,7 @@ defmodule WandererApp.MixProject do
{:mox, "~> 1.1", only: [:test, :integration]},
{:git_ops, "~> 2.6.1"},
{:version_tasks, "~> 0.12.0"},
{:error_tracker, "~> 0.2"},
{:sourceror, "~> 1.3.0", override: true}
{:error_tracker, "~> 0.2"}
]
end

View File

@@ -105,7 +105,7 @@
"sleeplocks": {:hex, :sleeplocks, "1.1.3", "96a86460cc33b435c7310dbd27ec82ca2c1f24ae38e34f8edde97f756503441a", [:rebar3], [], "hexpm", "d3b3958552e6eb16f463921e70ae7c767519ef8f5be46d7696cc1ed649421321"},
"slugify": {:hex, :slugify, "1.3.1", "0d3b8b7e5c1eeaa960e44dce94382bee34a39b3ea239293e457a9c5b47cc6fd3", [:mix], [], "hexpm", "cb090bbeb056b312da3125e681d98933a360a70d327820e4b7f91645c4d8be76"},
"sobelow": {:hex, :sobelow, "0.13.0", "218afe9075904793f5c64b8837cc356e493d88fddde126a463839351870b8d1e", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cd6e9026b85fc35d7529da14f95e85a078d9dd1907a9097b3ba6ac7ebbe34a0d"},
"sourceror": {:hex, :sourceror, "1.3.0", "70ab9e8bf6df085a1effba4b49ad621b7153b065f69ef6cdb82e6088f2026029", [:mix], [], "hexpm", "1794c3ceeca4eb3f9437261721e4d9cbf846d7c64c7aee4f64062b18d5ce1eac"},
"sourceror": {:hex, :sourceror, "1.6.0", "9907884e1449a4bd7dbaabe95088ed4d9a09c3c791fb0103964e6316bc9448a7", [:mix], [], "hexpm", "e90aef8c82dacf32c89c8ef83d1416fc343cd3e5556773eeffd2c1e3f991f699"},
"spark": {:hex, :spark, "2.2.29", "a52733ff72b05a674e48d3ca7a4172fe7bec81e9116069da8b4db19030d581d9", [:mix], [{:igniter, ">= 0.3.36 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "111a0dadbb27537c7629bc03ac56fcab15056ab0b9ad985084b9adcdb48836c8"},
"spitfire": {:hex, :spitfire, "0.1.3", "7ea0f544005dfbe48e615ed90250c9a271bfe126914012023fd5e4b6b82b7ec7", [:mix], [], "hexpm", "d53b5107bcff526a05c5bb54c95e77b36834550affd5830c9f58760e8c543657"},
"splode": {:hex, :splode, "0.2.4", "71046334c39605095ca4bed5d008372e56454060997da14f9868534c17b84b53", [:mix], [], "hexpm", "ca3b95f0d8d4b482b5357954fec857abd0fa3ea509d623334c1328e7382044c2"},

View File

@@ -0,0 +1,54 @@
defmodule WandererApp.Repo.Migrations.InstallAshFunctionsExtension420240922090427 do
@moduledoc """
Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback
This file was autogenerated with `mix ash_postgres.generate_migrations`
"""
use Ecto.Migration
def up do
execute("""
CREATE OR REPLACE FUNCTION uuid_generate_v7()
RETURNS UUID
AS $$
DECLARE
timestamp TIMESTAMPTZ;
microseconds INT;
BEGIN
timestamp = clock_timestamp();
microseconds = (cast(extract(microseconds FROM timestamp)::INT - (floor(extract(milliseconds FROM timestamp))::INT * 1000) AS DOUBLE PRECISION) * 4.096)::INT;
RETURN encode(
set_byte(
set_byte(
overlay(uuid_send(gen_random_uuid()) placing substring(int8send(floor(extract(epoch FROM timestamp) * 1000)::BIGINT) FROM 3) FROM 1 FOR 6
),
6, (b'0111' || (microseconds >> 8)::bit(4))::bit(8)::int
),
7, microseconds::bit(8)::int
),
'hex')::UUID;
END
$$
LANGUAGE PLPGSQL
VOLATILE;
""")
execute("""
CREATE OR REPLACE FUNCTION timestamp_from_uuid_v7(_uuid uuid)
RETURNS TIMESTAMP WITHOUT TIME ZONE
AS $$
SELECT to_timestamp(('x0000' || substr(_uuid::TEXT, 1, 8) || substr(_uuid::TEXT, 10, 4))::BIT(64)::BIGINT::NUMERIC / 1000);
$$
LANGUAGE SQL
IMMUTABLE PARALLEL SAFE STRICT;
""")
end
def down do
# Uncomment this if you actually want to uninstall the extensions
# when this migration is rolled back:
execute("DROP FUNCTION IF EXISTS uuid_generate_v7(), timestamp_from_uuid_v7(uuid)")
end
end

View File

@@ -0,0 +1,100 @@
defmodule WandererApp.Repo.Migrations.AddMapAclFkCheck do
@moduledoc """
Updates resources based on their most recent snapshots.
This file was autogenerated with `mix ash_postgres.generate_migrations`
"""
use Ecto.Migration
def up do
drop constraint(:map_access_lists_v1, "map_access_lists_v1_access_list_id_fkey")
drop constraint(:map_access_lists_v1, "map_access_lists_v1_map_id_fkey")
alter table(:map_access_lists_v1) do
modify :map_id,
references(:maps_v1,
column: :id,
name: "map_access_lists_v1_map_id_fkey",
type: :uuid,
prefix: "public",
on_delete: :delete_all
)
end
drop constraint(:access_list_members_v1, "access_list_members_v1_access_list_id_fkey")
alter table(:access_list_members_v1) do
modify :access_list_id,
references(:access_lists_v1,
column: :id,
name: "access_list_members_v1_access_list_id_fkey",
type: :uuid,
prefix: "public",
on_delete: :delete_all
)
end
execute(
"ALTER TABLE access_list_members_v1 alter CONSTRAINT access_list_members_v1_access_list_id_fkey NOT DEFERRABLE"
)
execute(
"ALTER TABLE map_access_lists_v1 alter CONSTRAINT map_access_lists_v1_map_id_fkey NOT DEFERRABLE"
)
alter table(:map_access_lists_v1) do
modify :access_list_id,
references(:access_lists_v1,
column: :id,
name: "map_access_lists_v1_access_list_id_fkey",
type: :uuid,
prefix: "public",
on_delete: :delete_all
)
end
execute(
"ALTER TABLE map_access_lists_v1 alter CONSTRAINT map_access_lists_v1_access_list_id_fkey NOT DEFERRABLE"
)
end
def down do
drop constraint(:map_access_lists_v1, "map_access_lists_v1_access_list_id_fkey")
alter table(:map_access_lists_v1) do
modify :access_list_id,
references(:access_lists_v1,
column: :id,
name: "map_access_lists_v1_access_list_id_fkey",
type: :uuid,
prefix: "public"
)
end
drop constraint(:access_list_members_v1, "access_list_members_v1_access_list_id_fkey")
alter table(:access_list_members_v1) do
modify :access_list_id,
references(:access_lists_v1,
column: :id,
name: "access_list_members_v1_access_list_id_fkey",
type: :uuid,
prefix: "public"
)
end
drop constraint(:map_access_lists_v1, "map_access_lists_v1_map_id_fkey")
alter table(:map_access_lists_v1) do
modify :map_id,
references(:maps_v1,
column: :id,
name: "map_access_lists_v1_map_id_fkey",
type: :uuid,
prefix: "public"
)
end
end
end

View File

@@ -0,0 +1,183 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "fragment(\"gen_random_uuid()\")",
"generated?": false,
"primary_key?": true,
"references": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "name",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "eve_character_id",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "eve_corporation_id",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "eve_alliance_id",
"type": "text"
},
{
"allow_nil?": true,
"default": "\"viewer\"",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "role",
"type": "text"
},
{
"allow_nil?": false,
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "inserted_at",
"type": "utc_datetime_usec"
},
{
"allow_nil?": false,
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "updated_at",
"type": "utc_datetime_usec"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": {
"deferrable": false,
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"index?": false,
"match_type": null,
"match_with": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "access_list_members_v1_access_list_id_fkey",
"on_delete": "delete",
"on_update": null,
"primary_key?": true,
"schema": "public",
"table": "access_lists_v1"
},
"size": null,
"source": "access_list_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [],
"has_create_action": true,
"hash": "C513B5FDD62707C1E7491D194C5A33DB6A8F060DC7FA0BD6AECA2A8BE9EAD65E",
"identities": [
{
"all_tenants?": false,
"base_filter": null,
"index_name": "access_list_members_v1_uniq_acl_alliance_id_index",
"keys": [
{
"type": "atom",
"value": "access_list_id"
},
{
"type": "atom",
"value": "eve_alliance_id"
}
],
"name": "uniq_acl_alliance_id",
"nils_distinct?": true,
"where": null
},
{
"all_tenants?": false,
"base_filter": null,
"index_name": "access_list_members_v1_uniq_acl_character_id_index",
"keys": [
{
"type": "atom",
"value": "access_list_id"
},
{
"type": "atom",
"value": "eve_character_id"
}
],
"name": "uniq_acl_character_id",
"nils_distinct?": true,
"where": null
},
{
"all_tenants?": false,
"base_filter": null,
"index_name": "access_list_members_v1_uniq_acl_corporation_id_index",
"keys": [
{
"type": "atom",
"value": "access_list_id"
},
{
"type": "atom",
"value": "eve_corporation_id"
}
],
"name": "uniq_acl_corporation_id",
"nils_distinct?": true,
"where": null
}
],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.WandererApp.Repo",
"schema": null,
"table": "access_list_members_v1"
}

View File

@@ -1,5 +1,5 @@
{
"ash_functions_version": 3,
"ash_functions_version": 4,
"installed": [
"ash-functions"
]

View File

@@ -0,0 +1,126 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "fragment(\"gen_random_uuid()\")",
"generated?": false,
"primary_key?": true,
"references": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "inserted_at",
"type": "utc_datetime_usec"
},
{
"allow_nil?": false,
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "updated_at",
"type": "utc_datetime_usec"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": true,
"references": {
"deferrable": false,
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"index?": false,
"match_type": null,
"match_with": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "map_access_lists_v1_map_id_fkey",
"on_delete": "delete",
"on_update": null,
"primary_key?": true,
"schema": "public",
"table": "maps_v1"
},
"size": null,
"source": "map_id",
"type": "uuid"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": true,
"references": {
"deferrable": false,
"destination_attribute": "id",
"destination_attribute_default": null,
"destination_attribute_generated": null,
"index?": false,
"match_type": null,
"match_with": null,
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"name": "map_access_lists_v1_access_list_id_fkey",
"on_delete": "delete",
"on_update": null,
"primary_key?": true,
"schema": "public",
"table": "access_lists_v1"
},
"size": null,
"source": "access_list_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [],
"has_create_action": true,
"hash": "1790C0240D55A6A1F6346B22E98AED5387F62E11BB258541CC1F95679C955F42",
"identities": [
{
"all_tenants?": false,
"base_filter": null,
"index_name": "map_access_lists_v1_unique_map_acl_index",
"keys": [
{
"type": "atom",
"value": "map_id"
},
{
"type": "atom",
"value": "access_list_id"
}
],
"name": "unique_map_acl",
"nils_distinct?": true,
"where": null
}
],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.WandererApp.Repo",
"schema": null,
"table": "map_access_lists_v1"
}