mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-12 02:35:42 +00:00
fix: api and structure search fixes
This commit is contained in:
@@ -30,9 +30,6 @@ export const SystemStructuresDialog: React.FC<StructuresEditDialogProps> = ({
|
|||||||
|
|
||||||
const { outCommand } = useMapRootState();
|
const { outCommand } = useMapRootState();
|
||||||
|
|
||||||
const [prevQuery, setPrevQuery] = useState('');
|
|
||||||
const [prevResults, setPrevResults] = useState<{ label: string; value: string }[]>([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (structure) {
|
if (structure) {
|
||||||
setEditData(structure);
|
setEditData(structure);
|
||||||
@@ -46,34 +43,24 @@ export const SystemStructuresDialog: React.FC<StructuresEditDialogProps> = ({
|
|||||||
// Searching corporation owners via auto-complete
|
// Searching corporation owners via auto-complete
|
||||||
const searchOwners = useCallback(
|
const searchOwners = useCallback(
|
||||||
async (e: { query: string }) => {
|
async (e: { query: string }) => {
|
||||||
const newQuery = e.query.trim();
|
const query = e.query.trim();
|
||||||
if (!newQuery) {
|
if (!query) {
|
||||||
setOwnerSuggestions([]);
|
setOwnerSuggestions([]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If user typed more text but we have partial match in prevResults
|
|
||||||
if (newQuery.startsWith(prevQuery) && prevResults.length > 0) {
|
|
||||||
const filtered = prevResults.filter(item => item.label.toLowerCase().includes(newQuery.toLowerCase()));
|
|
||||||
setOwnerSuggestions(filtered);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO fix it
|
|
||||||
const { results = [] } = await outCommand({
|
const { results = [] } = await outCommand({
|
||||||
type: OutCommand.getCorporationNames,
|
type: OutCommand.getCorporationNames,
|
||||||
data: { search: newQuery },
|
data: { search: query },
|
||||||
});
|
});
|
||||||
setOwnerSuggestions(results);
|
setOwnerSuggestions(results);
|
||||||
setPrevQuery(newQuery);
|
|
||||||
setPrevResults(results);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to fetch owners:', err);
|
console.error('Failed to fetch owners:', err);
|
||||||
setOwnerSuggestions([]);
|
setOwnerSuggestions([]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[prevQuery, prevResults, outCommand],
|
[outCommand],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleChange = (field: keyof StructureItem, val: string | Date) => {
|
const handleChange = (field: keyof StructureItem, val: string | Date) => {
|
||||||
@@ -122,7 +109,6 @@ export const SystemStructuresDialog: React.FC<StructuresEditDialogProps> = ({
|
|||||||
// fetch corporation ticker if we have an ownerId
|
// fetch corporation ticker if we have an ownerId
|
||||||
if (editData.ownerId) {
|
if (editData.ownerId) {
|
||||||
try {
|
try {
|
||||||
// TODO fix it
|
|
||||||
const { ticker } = await outCommand({
|
const { ticker } = await outCommand({
|
||||||
type: OutCommand.getCorporationTicker,
|
type: OutCommand.getCorporationTicker,
|
||||||
data: { corp_id: editData.ownerId },
|
data: { corp_id: editData.ownerId },
|
||||||
|
|||||||
@@ -5,9 +5,36 @@ defmodule WandererApp.Map.Operations.Signatures do
|
|||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
alias WandererApp.Map.Operations
|
alias WandererApp.Map.Operations
|
||||||
alias WandererApp.Api.{MapSystem, MapSystemSignature}
|
alias WandererApp.Api.{Character, MapSystem, MapSystemSignature}
|
||||||
alias WandererApp.Map.Server
|
alias WandererApp.Map.Server
|
||||||
|
|
||||||
|
# Private helper to validate character_eve_id from params
|
||||||
|
# If character_eve_id is provided in params, validates it exists in the system
|
||||||
|
# If not provided, falls back to the owner's character ID
|
||||||
|
@spec validate_character_eve_id(map(), String.t()) ::
|
||||||
|
{:ok, String.t()} | {:error, :invalid_character}
|
||||||
|
defp validate_character_eve_id(params, fallback_char_id) do
|
||||||
|
case Map.get(params, "character_eve_id") do
|
||||||
|
nil ->
|
||||||
|
# No character_eve_id provided, use fallback (owner's character)
|
||||||
|
{:ok, fallback_char_id}
|
||||||
|
|
||||||
|
provided_char_id when is_binary(provided_char_id) ->
|
||||||
|
# Validate the provided character_eve_id exists
|
||||||
|
case Character.by_eve_id(provided_char_id) do
|
||||||
|
{:ok, _character} ->
|
||||||
|
{:ok, provided_char_id}
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
{:error, :invalid_character}
|
||||||
|
end
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
# Invalid format
|
||||||
|
{:error, :invalid_character}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@spec list_signatures(String.t()) :: [map()]
|
@spec list_signatures(String.t()) :: [map()]
|
||||||
def list_signatures(map_id) do
|
def list_signatures(map_id) do
|
||||||
systems = Operations.list_systems(map_id)
|
systems = Operations.list_systems(map_id)
|
||||||
@@ -42,10 +69,11 @@ defmodule WandererApp.Map.Operations.Signatures do
|
|||||||
)
|
)
|
||||||
when is_integer(solar_system_id) do
|
when is_integer(solar_system_id) do
|
||||||
# Convert solar_system_id to system_id for internal use
|
# Convert solar_system_id to system_id for internal use
|
||||||
with {:ok, system} <- MapSystem.by_map_id_and_solar_system_id(map_id, solar_system_id) do
|
with {:ok, system} <- MapSystem.by_map_id_and_solar_system_id(map_id, solar_system_id),
|
||||||
|
{:ok, validated_char_id} <- validate_character_eve_id(params, char_id) do
|
||||||
attrs =
|
attrs =
|
||||||
params
|
params
|
||||||
|> Map.put("character_eve_id", char_id)
|
|> Map.put("character_eve_id", validated_char_id)
|
||||||
|> Map.put("system_id", system.id)
|
|> Map.put("system_id", system.id)
|
||||||
|> Map.delete("solar_system_id")
|
|> Map.delete("solar_system_id")
|
||||||
|
|
||||||
@@ -54,7 +82,7 @@ defmodule WandererApp.Map.Operations.Signatures do
|
|||||||
updated_signatures: [],
|
updated_signatures: [],
|
||||||
removed_signatures: [],
|
removed_signatures: [],
|
||||||
solar_system_id: solar_system_id,
|
solar_system_id: solar_system_id,
|
||||||
character_id: char_id,
|
character_id: validated_char_id,
|
||||||
user_id: user_id,
|
user_id: user_id,
|
||||||
delete_connection_with_sigs: false
|
delete_connection_with_sigs: false
|
||||||
}) do
|
}) do
|
||||||
@@ -86,6 +114,10 @@ defmodule WandererApp.Map.Operations.Signatures do
|
|||||||
{:error, :unexpected_error}
|
{:error, :unexpected_error}
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
{:error, :invalid_character} ->
|
||||||
|
Logger.error("[create_signature] Invalid character_eve_id provided")
|
||||||
|
{:error, :invalid_character}
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
Logger.error(
|
Logger.error(
|
||||||
"[create_signature] System not found for solar_system_id: #{solar_system_id}"
|
"[create_signature] System not found for solar_system_id: #{solar_system_id}"
|
||||||
@@ -112,7 +144,8 @@ defmodule WandererApp.Map.Operations.Signatures do
|
|||||||
params
|
params
|
||||||
) do
|
) do
|
||||||
with {:ok, sig} <- MapSystemSignature.by_id(sig_id),
|
with {:ok, sig} <- MapSystemSignature.by_id(sig_id),
|
||||||
{:ok, system} <- MapSystem.by_id(sig.system_id) do
|
{:ok, system} <- MapSystem.by_id(sig.system_id),
|
||||||
|
{:ok, validated_char_id} <- validate_character_eve_id(params, char_id) do
|
||||||
base = %{
|
base = %{
|
||||||
"eve_id" => sig.eve_id,
|
"eve_id" => sig.eve_id,
|
||||||
"name" => sig.name,
|
"name" => sig.name,
|
||||||
@@ -120,7 +153,7 @@ defmodule WandererApp.Map.Operations.Signatures do
|
|||||||
"group" => sig.group,
|
"group" => sig.group,
|
||||||
"type" => sig.type,
|
"type" => sig.type,
|
||||||
"custom_info" => sig.custom_info,
|
"custom_info" => sig.custom_info,
|
||||||
"character_eve_id" => char_id,
|
"character_eve_id" => validated_char_id,
|
||||||
"description" => sig.description,
|
"description" => sig.description,
|
||||||
"linked_system_id" => sig.linked_system_id
|
"linked_system_id" => sig.linked_system_id
|
||||||
}
|
}
|
||||||
@@ -133,7 +166,7 @@ defmodule WandererApp.Map.Operations.Signatures do
|
|||||||
updated_signatures: [attrs],
|
updated_signatures: [attrs],
|
||||||
removed_signatures: [],
|
removed_signatures: [],
|
||||||
solar_system_id: system.solar_system_id,
|
solar_system_id: system.solar_system_id,
|
||||||
character_id: char_id,
|
character_id: validated_char_id,
|
||||||
user_id: user_id,
|
user_id: user_id,
|
||||||
delete_connection_with_sigs: false
|
delete_connection_with_sigs: false
|
||||||
})
|
})
|
||||||
@@ -151,6 +184,10 @@ defmodule WandererApp.Map.Operations.Signatures do
|
|||||||
_ -> {:ok, attrs}
|
_ -> {:ok, attrs}
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
{:error, :invalid_character} ->
|
||||||
|
Logger.error("[update_signature] Invalid character_eve_id provided")
|
||||||
|
{:error, :invalid_character}
|
||||||
|
|
||||||
err ->
|
err ->
|
||||||
Logger.error("[update_signature] Unexpected error: #{inspect(err)}")
|
Logger.error("[update_signature] Unexpected error: #{inspect(err)}")
|
||||||
{:error, :unexpected_error}
|
{:error, :unexpected_error}
|
||||||
|
|||||||
@@ -441,18 +441,19 @@ defmodule WandererAppWeb.MapSystemAPIController do
|
|||||||
)
|
)
|
||||||
|
|
||||||
def show(%{assigns: %{map_id: map_id}} = conn, %{"id" => id}) do
|
def show(%{assigns: %{map_id: map_id}} = conn, %{"id" => id}) do
|
||||||
with {:ok, system_uuid} <- APIUtils.validate_uuid(id),
|
# Look up by solar_system_id (EVE Online integer ID)
|
||||||
{:ok, system} <- WandererApp.Api.MapSystem.by_id(system_uuid) do
|
case APIUtils.parse_int(id) do
|
||||||
# Verify the system belongs to the requested map
|
{:ok, solar_system_id} ->
|
||||||
if system.map_id == map_id do
|
case Operations.get_system(map_id, solar_system_id) do
|
||||||
|
{:ok, system} ->
|
||||||
APIUtils.respond_data(conn, APIUtils.map_system_to_json(system))
|
APIUtils.respond_data(conn, APIUtils.map_system_to_json(system))
|
||||||
else
|
|
||||||
|
{:error, :not_found} ->
|
||||||
{:error, :not_found}
|
{:error, :not_found}
|
||||||
end
|
end
|
||||||
else
|
|
||||||
{:error, %Ash.Error.Query.NotFound{}} -> {:error, :not_found}
|
{:error, _} ->
|
||||||
{:error, _} -> {:error, :not_found}
|
{:error, :not_found}
|
||||||
error -> error
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -472,8 +473,22 @@ defmodule WandererAppWeb.MapSystemAPIController do
|
|||||||
)
|
)
|
||||||
|
|
||||||
def create(conn, params) do
|
def create(conn, params) do
|
||||||
systems = Map.get(params, "systems", [])
|
# Support both batch format {"systems": [...], "connections": [...]}
|
||||||
connections = Map.get(params, "connections", [])
|
# and single system format {"solar_system_id": ..., ...}
|
||||||
|
{systems, connections} =
|
||||||
|
cond do
|
||||||
|
Map.has_key?(params, "systems") ->
|
||||||
|
# Batch format
|
||||||
|
{Map.get(params, "systems", []), Map.get(params, "connections", [])}
|
||||||
|
|
||||||
|
Map.has_key?(params, "solar_system_id") or Map.has_key?(params, :solar_system_id) ->
|
||||||
|
# Single system format - wrap it in an array
|
||||||
|
{[params], []}
|
||||||
|
|
||||||
|
true ->
|
||||||
|
# Empty request
|
||||||
|
{[], []}
|
||||||
|
end
|
||||||
|
|
||||||
case Operations.upsert_systems_and_connections(conn, systems, connections) do
|
case Operations.upsert_systems_and_connections(conn, systems, connections) do
|
||||||
{:ok, result} ->
|
{:ok, result} ->
|
||||||
|
|||||||
@@ -595,7 +595,7 @@ defmodule WandererAppWeb.Router do
|
|||||||
# while maintaining 100% backward compatibility with existing /api/* routes
|
# while maintaining 100% backward compatibility with existing /api/* routes
|
||||||
#
|
#
|
||||||
scope "/api/v1" do
|
scope "/api/v1" do
|
||||||
pipe_through :api_v1
|
pipe_through [:api_v1, :api_map]
|
||||||
|
|
||||||
# Custom combined endpoints
|
# Custom combined endpoints
|
||||||
get "/maps/:map_id/systems_and_connections",
|
get "/maps/:map_id/systems_and_connections",
|
||||||
|
|||||||
Reference in New Issue
Block a user