diff --git a/assets/js/hooks/Mapper/components/mapRootContent/MapRootContent.tsx b/assets/js/hooks/Mapper/components/mapRootContent/MapRootContent.tsx index 5d97d126..88edbc1e 100644 --- a/assets/js/hooks/Mapper/components/mapRootContent/MapRootContent.tsx +++ b/assets/js/hooks/Mapper/components/mapRootContent/MapRootContent.tsx @@ -9,6 +9,7 @@ import { MapContextMenu } from '@/hooks/Mapper/components/mapRootContent/compone import { useSkipContextMenu } from '@/hooks/Mapper/hooks/useSkipContextMenu'; import { MapSettings } from '@/hooks/Mapper/components/mapRootContent/components/MapSettings'; import { CharacterActivity } from '@/hooks/Mapper/components/mapRootContent/components/CharacterActivity'; +import { WormholeSignaturesDialog } from '@/hooks/Mapper/components/mapRootContent/components/WormholeSignaturesDialog'; import { useCharacterActivityHandlers } from './hooks/useCharacterActivityHandlers'; import { TrackingDialog } from '@/hooks/Mapper/components/mapRootContent/components/TrackingDialog'; import { useMapEventListener } from '@/hooks/Mapper/events'; @@ -34,6 +35,7 @@ export const MapRootContent = ({}: MapRootContentProps) => { const [showOnTheMap, setShowOnTheMap] = useState(false); const [showMapSettings, setShowMapSettings] = useState(false); const [showTrackingDialog, setShowTrackingDialog] = useState(false); + const [showWormholeSignatures, setShowWormholeSignatures] = useState(false); /* Important Notice - this solution needs for use one instance of MapInterface */ const mapInterface = isReady ? : null; @@ -47,6 +49,10 @@ export const MapRootContent = ({}: MapRootContentProps) => { setShowTrackingDialog(true); return true; } + if (event.name === Commands.showWormholeSignatures) { + setShowWormholeSignatures(true); + return true; + } }); useSkipContextMenu(); @@ -93,6 +99,12 @@ export const MapRootContent = ({}: MapRootContentProps) => { {showTrackingDialog && ( setShowTrackingDialog(false)} /> )} + {showWormholeSignatures && ( + setShowWormholeSignatures(false)} + /> + )} {hasOldSettings && } diff --git a/assets/js/hooks/Mapper/components/mapRootContent/components/WormholeSignaturesDialog/WormholeSignaturesDialog.tsx b/assets/js/hooks/Mapper/components/mapRootContent/components/WormholeSignaturesDialog/WormholeSignaturesDialog.tsx new file mode 100644 index 00000000..18f8cbd6 --- /dev/null +++ b/assets/js/hooks/Mapper/components/mapRootContent/components/WormholeSignaturesDialog/WormholeSignaturesDialog.tsx @@ -0,0 +1,175 @@ +import { useMemo, useState } from 'react'; +import { Dialog } from 'primereact/dialog'; +import { DataTable } from 'primereact/datatable'; +import { Column } from 'primereact/column'; +import { useMapRootState } from '@/hooks/Mapper/mapRootProvider'; +import { WormholeDataRaw } from '@/hooks/Mapper/types'; +import { WHClassView } from '@/hooks/Mapper/components/ui-kit'; +import { kgToTons } from '@/hooks/Mapper/utils/kgToTons.ts'; +import { WORMHOLE_CLASS_STYLES, WORMHOLES_ADDITIONAL_INFO } from '@/hooks/Mapper/components/map/constants.ts'; +import clsx from 'clsx'; +import { InputText } from 'primereact/inputtext'; +import { IconField } from 'primereact/iconfield'; +import { InputIcon } from 'primereact/inputicon'; + +export interface WormholeSignaturesDialogProps { + visible: boolean; + onHide: () => void; +} + +const RespawnTag = ({ value }: { value: string }) => ( + {value} +); + +export const WormholeSignaturesDialog = ({ visible, onHide }: WormholeSignaturesDialogProps) => { + const { + data: { wormholes }, + } = useMapRootState(); + + const [filter, setFilter] = useState(''); + + const filtered = useMemo(() => { + const q = filter.trim().toLowerCase(); + + if (!q) return wormholes; + + return wormholes.filter(w => { + const destInfo = WORMHOLES_ADDITIONAL_INFO[w.dest]; + const spawnsLabels = w.src + .map(s => { + const group = s.split('-')[0]; + const info = WORMHOLES_ADDITIONAL_INFO[group]; + if (!info) return s; + return `${info.title} ${info.shortName}`.trim(); + }) + .join(' '); + + return [ + w.name, + destInfo?.title, + destInfo?.shortName, + spawnsLabels, + String(w.total_mass), + String(w.max_mass_per_jump), + w.lifetime, + w.respawn.join(','), + ] + .filter(Boolean) + .join(' ') + .toLowerCase() + .includes(q); + }); + }, [wormholes, filter]); + + const renderName = (w: WormholeDataRaw) => ( +
+ +
+ ); + + const renderRespawn = (w: WormholeDataRaw) => ( +
+ {w.respawn.map(r => ( + + ))} +
+ ); + + const renderSpawns = (w: WormholeDataRaw) => ( +
+ {w.src.map(s => { + const group = s.split('-')[0]; + const info = WORMHOLES_ADDITIONAL_INFO[group]; + if (!info) + return ( + + {s} + + ); + const cls = WORMHOLE_CLASS_STYLES[String(info.wormholeClassID)] || ''; + const label = `${info.shortName}`; + return ( + + {label} + + ); + })} +
+ ); + + return ( + +
+
Reference list of all wormhole types
+ + filter && setFilter('')} + role="button" + aria-label="Clear search" + aria-disabled={!filter} + title={filter ? 'Clear' : 'Nothing to clear'} + /> + setFilter(e.target.value)} /> + +
+ +
+ + + + + kgToTons(w.total_mass)} + bodyClassName="whitespace-normal break-words" + /> + kgToTons(w.max_mass_per_jump)} + bodyClassName="whitespace-normal break-words" + /> + + +
+
+ ); +}; diff --git a/assets/js/hooks/Mapper/components/mapRootContent/components/WormholeSignaturesDialog/index.ts b/assets/js/hooks/Mapper/components/mapRootContent/components/WormholeSignaturesDialog/index.ts new file mode 100644 index 00000000..6c970e1c --- /dev/null +++ b/assets/js/hooks/Mapper/components/mapRootContent/components/WormholeSignaturesDialog/index.ts @@ -0,0 +1 @@ +export * from './WormholeSignaturesDialog'; diff --git a/assets/js/hooks/Mapper/mapRootProvider/hooks/useMapRootHandlers.ts b/assets/js/hooks/Mapper/mapRootProvider/hooks/useMapRootHandlers.ts index 7571d1ae..d1e5b405 100644 --- a/assets/js/hooks/Mapper/mapRootProvider/hooks/useMapRootHandlers.ts +++ b/assets/js/hooks/Mapper/mapRootProvider/hooks/useMapRootHandlers.ts @@ -63,127 +63,126 @@ export const useMapRootHandlers = (ref: ForwardedRef) => { const { pingAdded, pingCancelled } = useCommandPings(); const { characterActivityData, trackingCharactersData, userSettingsUpdated } = useCommandsActivity(); - useImperativeHandle( - ref, - () => { - return { - command(type, data) { - switch (type) { - case Commands.init: // USED - mapInit(data as CommandInit); - break; - case Commands.addSystems: // USED - addSystems(data as CommandAddSystems); - break; - case Commands.updateSystems: // USED - updateSystems(data as CommandUpdateSystems); - break; - case Commands.removeSystems: // USED - removeSystems(data as CommandRemoveSystems); - break; - case Commands.addConnections: // USED - addConnections(data as CommandAddConnections); - break; - case Commands.removeConnections: // USED - removeConnections(data as CommandRemoveConnections); - break; - case Commands.updateConnection: // USED - updateConnection(data as CommandUpdateConnection); - break; - case Commands.charactersUpdated: // USED - charactersUpdated(data as CommandCharactersUpdated); - break; - case Commands.characterAdded: // USED - characterAdded(data as CommandCharacterAdded); - break; - case Commands.characterRemoved: // USED - characterRemoved(data as CommandCharacterRemoved); - break; - case Commands.characterUpdated: // USED - characterUpdated(data as CommandCharacterUpdated); - break; - case Commands.presentCharacters: // USED - presentCharacters(data as CommandPresentCharacters); - break; - case Commands.mapUpdated: // USED - mapUpdated(data as CommandMapUpdated); - break; - case Commands.routes: - mapRoutes(data as CommandRoutes); - break; - case Commands.userRoutes: - mapUserRoutes(data as CommandRoutes); - break; + useImperativeHandle(ref, () => { + return { + command(type, data) { + switch (type) { + case Commands.init: // USED + mapInit(data as CommandInit); + break; + case Commands.addSystems: // USED + addSystems(data as CommandAddSystems); + break; + case Commands.updateSystems: // USED + updateSystems(data as CommandUpdateSystems); + break; + case Commands.removeSystems: // USED + removeSystems(data as CommandRemoveSystems); + break; + case Commands.addConnections: // USED + addConnections(data as CommandAddConnections); + break; + case Commands.removeConnections: // USED + removeConnections(data as CommandRemoveConnections); + break; + case Commands.updateConnection: // USED + updateConnection(data as CommandUpdateConnection); + break; + case Commands.charactersUpdated: // USED + charactersUpdated(data as CommandCharactersUpdated); + break; + case Commands.characterAdded: // USED + characterAdded(data as CommandCharacterAdded); + break; + case Commands.characterRemoved: // USED + characterRemoved(data as CommandCharacterRemoved); + break; + case Commands.characterUpdated: // USED + characterUpdated(data as CommandCharacterUpdated); + break; + case Commands.presentCharacters: // USED + presentCharacters(data as CommandPresentCharacters); + break; + case Commands.mapUpdated: // USED + mapUpdated(data as CommandMapUpdated); + break; + case Commands.routes: + mapRoutes(data as CommandRoutes); + break; + case Commands.userRoutes: + mapUserRoutes(data as CommandRoutes); + break; - case Commands.signaturesUpdated: // USED - updateSystemSignatures(data as CommandSignaturesUpdated); - break; + case Commands.signaturesUpdated: // USED + updateSystemSignatures(data as CommandSignaturesUpdated); + break; - case Commands.linkSignatureToSystem: // USED - setTimeout(() => { - updateLinkSignatureToSystem(data as CommandLinkSignatureToSystem); - }, 200); - break; + case Commands.linkSignatureToSystem: // USED + setTimeout(() => { + updateLinkSignatureToSystem(data as CommandLinkSignatureToSystem); + }, 200); + break; - case Commands.centerSystem: // USED - // do nothing here - break; + case Commands.centerSystem: // USED + // do nothing here + break; - case Commands.selectSystem: // USED - // do nothing here - break; + case Commands.selectSystem: // USED + // do nothing here + break; - case Commands.killsUpdated: - // do nothing here - break; + case Commands.killsUpdated: + // do nothing here + break; - case Commands.detailedKillsUpdated: - updateDetailedKills(data as Record); - break; + case Commands.detailedKillsUpdated: + updateDetailedKills(data as Record); + break; - case Commands.characterActivityData: - characterActivityData(data as CommandCharacterActivityData); - break; + case Commands.characterActivityData: + characterActivityData(data as CommandCharacterActivityData); + break; - case Commands.trackingCharactersData: - trackingCharactersData(data as CommandTrackingCharactersData); - break; + case Commands.trackingCharactersData: + trackingCharactersData(data as CommandTrackingCharactersData); + break; - case Commands.updateActivity: - break; + case Commands.updateActivity: + break; - case Commands.updateTracking: - break; + case Commands.updateTracking: + break; - case Commands.userSettingsUpdated: - userSettingsUpdated(data as CommandUserSettingsUpdated); - break; + case Commands.userSettingsUpdated: + userSettingsUpdated(data as CommandUserSettingsUpdated); + break; - case Commands.systemCommentAdded: - addComment(data as CommandCommentAdd); - break; + case Commands.systemCommentAdded: + addComment(data as CommandCommentAdd); + break; - case Commands.systemCommentRemoved: - removeComment(data as CommandCommentRemoved); - break; + case Commands.systemCommentRemoved: + removeComment(data as CommandCommentRemoved); + break; - case Commands.pingAdded: - pingAdded(data as CommandPingAdded); - break; + case Commands.pingAdded: + pingAdded(data as CommandPingAdded); + break; - case Commands.pingCancelled: - pingCancelled(data as CommandPingCancelled); - break; + case Commands.pingCancelled: + pingCancelled(data as CommandPingCancelled); + break; - default: - console.warn(`JOipP Interface handlers: Unknown command: ${type}`, data); - break; - } + case Commands.showWormholeSignatures: + break; - emitMapEvent({ name: type, data }); - }, - }; - }, - [], - ); + default: + console.warn(`JOipP Interface handlers: Unknown command: ${type}`, data); + break; + } + + emitMapEvent({ name: type, data }); + }, + }; + }, []); }; diff --git a/assets/js/hooks/Mapper/types/mapHandlers.ts b/assets/js/hooks/Mapper/types/mapHandlers.ts index aaae0ff5..d12c3149 100644 --- a/assets/js/hooks/Mapper/types/mapHandlers.ts +++ b/assets/js/hooks/Mapper/types/mapHandlers.ts @@ -40,6 +40,7 @@ export enum Commands { showTracking = 'show_tracking', pingAdded = 'ping_added', pingCancelled = 'ping_cancelled', + showWormholeSignatures = 'show_wormhole_signatures', } export type Command = @@ -75,7 +76,8 @@ export type Command = | Commands.updateTracking | Commands.showTracking | Commands.pingAdded - | Commands.pingCancelled; + | Commands.pingCancelled + | Commands.showWormholeSignatures; export type CommandInit = { systems: SolarSystemRawType[]; @@ -158,6 +160,7 @@ export type CommandUpdateTracking = { }; export type CommandPingAdded = PingData[]; export type CommandPingCancelled = Pick; +export type CommandShowWormholeSignatures = null; export interface UserSettings { primaryCharacterId?: string; @@ -208,6 +211,7 @@ export interface CommandData { [Commands.showTracking]: CommandShowTracking; [Commands.pingAdded]: CommandPingAdded; [Commands.pingCancelled]: CommandPingCancelled; + [Commands.showWormholeSignatures]: CommandShowWormholeSignatures; } export interface MapHandlers { diff --git a/lib/wanderer_app_web/live/map/event_handlers/map_core_event_handler.ex b/lib/wanderer_app_web/live/map/event_handlers/map_core_event_handler.ex index c7f7c47f..f6a9f759 100644 --- a/lib/wanderer_app_web/live/map/event_handlers/map_core_event_handler.ex +++ b/lib/wanderer_app_web/live/map/event_handlers/map_core_event_handler.ex @@ -219,6 +219,15 @@ defmodule WandererAppWeb.MapCoreEventHandler do {:reply, %{user_settings: user_settings}, socket} end + def handle_ui_event("show_wormhole_signatures", _event, socket) do + {:noreply, + socket + |> MapEventHandler.push_map_event( + "show_wormhole_signatures", + %{} + )} + end + def handle_ui_event( "update_user_settings", user_settings_form, diff --git a/lib/wanderer_app_web/live/map/map_live.html.heex b/lib/wanderer_app_web/live/map/map_live.html.heex index c83f1d9f..3ef8c0e9 100644 --- a/lib/wanderer_app_web/live/map/map_live.html.heex +++ b/lib/wanderer_app_web/live/map/map_live.html.heex @@ -32,6 +32,15 @@ <.icon name="hero-chart-bar-solid" class="w-6 h-6" /> + + <.link :if={(@user_permissions || %{}) |> Map.get(:delete_map, false)} id={"map-audit-#{@map_slug}"}