fix(Map): Added ability to add new system to routes via routes widget

This commit is contained in:
achichenkov
2024-12-24 11:42:46 +03:00
parent 3a69fd7786
commit a1791ba578
3 changed files with 76 additions and 7 deletions

View File

@@ -15,12 +15,20 @@ import { sortWHClasses } from '@/hooks/Mapper/helpers';
export type SearchOnSubmitCallback = (item: SearchSystemItem) => void; export type SearchOnSubmitCallback = (item: SearchSystemItem) => void;
interface AddSystemDialogProps { interface AddSystemDialogProps {
title?: string;
visible: boolean; visible: boolean;
setVisible: (visible: boolean) => void; setVisible: (visible: boolean) => void;
onSubmit?: SearchOnSubmitCallback; onSubmit?: SearchOnSubmitCallback;
excludedSystems?: number[];
} }
export const AddSystemDialog = ({ visible, setVisible, onSubmit }: AddSystemDialogProps) => { export const AddSystemDialog = ({
title = 'Add system',
visible,
setVisible,
onSubmit,
excludedSystems = [],
}: AddSystemDialogProps) => {
const { const {
outCommand, outCommand,
data: { wormholesData }, data: { wormholesData },
@@ -54,20 +62,24 @@ export const AddSystemDialog = ({ visible, setVisible, onSubmit }: AddSystemDial
}, },
}); });
const sorted = (result.systems as SearchSystemItem[]).sort((a, b) => { let prepared = (result.systems as SearchSystemItem[]).sort((a, b) => {
const amatch = a.label.indexOf(query); const amatch = a.label.indexOf(query);
const bmatch = b.label.indexOf(query); const bmatch = b.label.indexOf(query);
return amatch - bmatch; return amatch - bmatch;
}); });
setFilteredItems(sorted); if (excludedSystems) {
prepared = prepared.filter(x => !excludedSystems.includes(x.system_static_info.solar_system_id));
}
setFilteredItems(prepared);
} catch (error) { } catch (error) {
console.error('Error fetching data:', error); console.error('Error fetching data:', error);
setFilteredItems([]); setFilteredItems([]);
} }
} }
}, },
[outCommand], [excludedSystems, outCommand],
); );
const ref = useRef({ onSubmit, selectedItem }); const ref = useRef({ onSubmit, selectedItem });
@@ -89,7 +101,7 @@ export const AddSystemDialog = ({ visible, setVisible, onSubmit }: AddSystemDial
return ( return (
<Dialog <Dialog
header="Add system" header={title}
visible={visible} visible={visible}
draggable={false} draggable={false}
style={{ width: '520px' }} style={{ width: '520px' }}

View File

@@ -21,6 +21,11 @@ import { RoutesProvider, useRouteProvider } from './RoutesProvider.tsx';
import { ContextMenuSystemInfo, useContextMenuSystemInfoHandlers } from '@/hooks/Mapper/components/contexts'; import { ContextMenuSystemInfo, useContextMenuSystemInfoHandlers } from '@/hooks/Mapper/components/contexts';
import useMaxWidth from '@/hooks/Mapper/hooks/useMaxWidth.ts'; import useMaxWidth from '@/hooks/Mapper/hooks/useMaxWidth.ts';
import { WdTooltipWrapper } from '@/hooks/Mapper/components/ui-kit/WdTooltipWrapper'; import { WdTooltipWrapper } from '@/hooks/Mapper/components/ui-kit/WdTooltipWrapper';
import {
AddSystemDialog,
SearchOnSubmitCallback,
} from '@/hooks/Mapper/components/mapInterface/components/AddSystemDialog';
import { OutCommand } from '@/hooks/Mapper/types';
const sortByDist = (a: Route, b: Route) => { const sortByDist = (a: Route, b: Route) => {
const distA = a.has_connection ? a.systems?.length || 0 : Infinity; const distA = a.has_connection ? a.systems?.length || 0 : Infinity;
@@ -163,6 +168,12 @@ export const RoutesWidgetContent = () => {
export const RoutesWidgetComp = () => { export const RoutesWidgetComp = () => {
const [routeSettingsVisible, setRouteSettingsVisible] = useState(false); const [routeSettingsVisible, setRouteSettingsVisible] = useState(false);
const { data, update } = useRouteProvider(); const { data, update } = useRouteProvider();
const {
data: { hubs = [] },
outCommand,
} = useMapRootState();
const preparedHubs = useMemo(() => hubs.map(x => parseInt(x)), [hubs]);
const isSecure = data.path_type === 'secure'; const isSecure = data.path_type === 'secure';
const handleSecureChange = useCallback(() => { const handleSecureChange = useCallback(() => {
@@ -174,6 +185,23 @@ export const RoutesWidgetComp = () => {
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const compact = useMaxWidth(ref, 155); const compact = useMaxWidth(ref, 155);
const [openAddSystem, setOpenAddSystem] = useState<boolean>(false);
const onAddSystem = useCallback(() => setOpenAddSystem(true), []);
const handleSubmitAddSystem: SearchOnSubmitCallback = useCallback(
async item => {
if (preparedHubs.includes(item.value)) {
return;
}
await outCommand({
type: OutCommand.addHub,
data: { system_id: item.value },
});
},
[hubs, outCommand],
);
return ( return (
<Widget <Widget
@@ -181,6 +209,14 @@ export const RoutesWidgetComp = () => {
<div className="flex justify-between items-center text-xs w-full" ref={ref}> <div className="flex justify-between items-center text-xs w-full" ref={ref}>
<span className="select-none">Routes</span> <span className="select-none">Routes</span>
<LayoutEventBlocker className="flex items-center gap-2"> <LayoutEventBlocker className="flex items-center gap-2">
<WdImgButton
className={PrimeIcons.PLUS_CIRCLE}
onClick={onAddSystem}
tooltip={{
content: 'Click here to add new system to routes',
}}
/>
<WdTooltipWrapper content="Show shortest route"> <WdTooltipWrapper content="Show shortest route">
<WdCheckbox <WdCheckbox
size="xs" size="xs"
@@ -191,13 +227,26 @@ export const RoutesWidgetComp = () => {
classNameLabel={clsx('text-red-400')} classNameLabel={clsx('text-red-400')}
/> />
</WdTooltipWrapper> </WdTooltipWrapper>
<WdImgButton className={PrimeIcons.SLIDERS_H} onClick={() => setRouteSettingsVisible(true)} /> <WdImgButton
className={PrimeIcons.SLIDERS_H}
onClick={() => setRouteSettingsVisible(true)}
tooltip={{
content: 'Click here to open Routes settings',
}}
/>
</LayoutEventBlocker> </LayoutEventBlocker>
</div> </div>
} }
> >
<RoutesWidgetContent /> <RoutesWidgetContent />
<RoutesSettingsDialog visible={routeSettingsVisible} setVisible={setRouteSettingsVisible} /> <RoutesSettingsDialog visible={routeSettingsVisible} setVisible={setRouteSettingsVisible} />
<AddSystemDialog
title="Add system to routes"
visible={openAddSystem}
setVisible={() => setOpenAddSystem(false)}
onSubmit={handleSubmitAddSystem}
/>
</Widget> </Widget>
); );
}; };

View File

@@ -17,7 +17,7 @@ import { getSystemById } from '@/hooks/Mapper/helpers';
import { Node, XYPosition } from 'reactflow'; import { Node, XYPosition } from 'reactflow';
import { Commands } from '@/hooks/Mapper/types/mapHandlers.ts'; import { Commands } from '@/hooks/Mapper/types/mapHandlers.ts';
import { useMapEventListener } from '@/hooks/Mapper/events'; import { emitMapEvent, useMapEventListener } from '@/hooks/Mapper/events';
import { STORED_INTERFACE_DEFAULT_VALUES } from '@/hooks/Mapper/mapRootProvider/MapRootProvider'; import { STORED_INTERFACE_DEFAULT_VALUES } from '@/hooks/Mapper/mapRootProvider/MapRootProvider';
import { useDeleteSystems } from '@/hooks/Mapper/components/contexts/hooks'; import { useDeleteSystems } from '@/hooks/Mapper/components/contexts/hooks';
@@ -134,6 +134,14 @@ export const MapWrapper = () => {
const handleSubmitAddSystem: SearchOnSubmitCallback = useCallback( const handleSubmitAddSystem: SearchOnSubmitCallback = useCallback(
async item => { async item => {
if (ref.current.systems.some(x => x.system_static_info.solar_system_id === item.value)) {
emitMapEvent({
name: Commands.centerSystem,
data: item.value.toString(),
});
return;
}
await outCommand({ await outCommand({
type: OutCommand.manualAddSystem, type: OutCommand.manualAddSystem,
data: { coordinates: openAddSystem, solar_system_id: item.value }, data: { coordinates: openAddSystem, solar_system_id: item.value },