fix(Map): Fixed a lot of design and architect issues after last milli… (#154)

* fix(Map): Fixed a lot of design and architect issues after last million PRs

* fix(Map): removed unnecessary hooks styles

---------

Co-authored-by: achichenkov <aleksei.chichenkov@telleqt.ai>
This commit is contained in:
Aleksei Chichenkov
2025-02-09 12:36:25 +03:00
committed by GitHub
parent 78eefcd6a7
commit cab1880fb0
32 changed files with 318 additions and 300 deletions

View File

@@ -8,6 +8,8 @@ import { LocalCharactersList } from './components/LocalCharactersList';
import { useLocalCharactersItemTemplate } from './hooks/useLocalCharacters';
import { useLocalCharacterWidgetSettings } from './hooks/useLocalWidgetSettings';
import { LocalCharactersHeader } from './components/LocalCharactersHeader';
import classes from './LocalCharacters.module.scss';
import clsx from 'clsx';
export const LocalCharacters = () => {
const {
@@ -16,11 +18,11 @@ export const LocalCharacters = () => {
const [settings, setSettings] = useLocalCharacterWidgetSettings();
const [systemId] = selectedSystems;
const restrictOfflineShowing = useMapGetOption("restrict_offline_showing");
const restrictOfflineShowing = useMapGetOption('restrict_offline_showing');
const isAdminOrManager = useMapCheckPermissions([UserPermission.MANAGE_MAP]);
const showOffline = useMemo(
() => !restrictOfflineShowing || isAdminOrManager,
[isAdminOrManager, restrictOfflineShowing]
[isAdminOrManager, restrictOfflineShowing],
);
const sorted = useMemo(() => {
@@ -81,7 +83,10 @@ export const LocalCharacters = () => {
items={sorted}
itemSize={settings.compact ? 26 : 41}
itemTemplate={itemTemplate}
containerClassName="w-full h-full overflow-x-hidden overflow-y-auto custom-scrollbar select-none"
containerClassName={clsx(
'w-full h-full overflow-x-hidden overflow-y-auto custom-scrollbar select-none',
classes.VirtualScroller,
)}
/>
)}
</Widget>

View File

@@ -1,8 +1,7 @@
import React, { useRef } from 'react';
import clsx from 'clsx';
import useMaxWidth from '@/hooks/Mapper/hooks/useMaxWidth';
import { LayoutEventBlocker, WdResponsiveCheckbox, WdDisplayMode } from '@/hooks/Mapper/components/ui-kit';
import { useElementWidth } from '@/hooks/Mapper/components/hooks';
import { LayoutEventBlocker, TooltipPosition, WdCheckbox, WdTooltipWrapper } from '@/hooks/Mapper/components/ui-kit';
interface LocalCharactersHeaderProps {
sortedCount: number;
@@ -24,68 +23,54 @@ export const LocalCharactersHeader: React.FC<LocalCharactersHeaderProps> = ({
setSettings,
}) => {
const headerRef = useRef<HTMLDivElement>(null);
const headerWidth = useElementWidth(headerRef) || 300;
const reservedWidth = 100;
const availableWidthForCheckboxes = Math.max(headerWidth - reservedWidth, 0);
let displayMode: WdDisplayMode = "full";
if (availableWidthForCheckboxes >= 150) {
displayMode = "full";
} else if (availableWidthForCheckboxes >= 100) {
displayMode = "abbr";
} else {
displayMode = "checkbox";
}
const compact = useMaxWidth(headerRef, 145);
const compactOffline = useMaxWidth(headerRef, 145);
const compactShipName = useMaxWidth(headerRef, 195);
return (
<div className="flex w-full items-center text-xs" ref={headerRef}>
<div className="flex-shrink-0 select-none mr-2">
Local{showList ? ` [${sortedCount}]` : ""}
</div>
<div className="flex-grow overflow-hidden">
<LayoutEventBlocker className="flex items-center gap-2 justify-end">
<div className="flex items-center gap-2">
{showOffline && (
<WdResponsiveCheckbox
tooltipContent="Show offline characters in system"
<div className="flex w-full items-center text-xs justify-between" ref={headerRef}>
<div className="flex-shrink-0 select-none mr-2">Local{showList ? ` [${sortedCount}]` : ''}</div>
<LayoutEventBlocker className="flex items-center gap-2 justify-end">
<div className="flex items-center gap-2">
{showOffline && (
<WdTooltipWrapper content="Show offline characters in system" position={TooltipPosition.top}>
<WdCheckbox
size="xs"
labelFull="Show offline"
labelAbbreviated="Offline"
labelSide="left"
label={compactOffline ? '' : 'Offline'}
value={settings.showOffline}
onChange={() =>
setSettings((prev: any) => ({ ...prev, showOffline: !prev.showOffline }))
}
classNameLabel={clsx("whitespace-nowrap text-stone-400 hover:text-stone-200 transition duration-300", { truncate: compact })}
displayMode={displayMode}
onChange={() => setSettings((prev: any) => ({ ...prev, showOffline: !prev.showOffline }))}
classNameLabel={clsx('whitespace-nowrap text-stone-400 hover:text-stone-200 transition duration-300', {
truncate: compactOffline,
})}
/>
)}
{settings.compact && (
<WdResponsiveCheckbox
tooltipContent="Show ship name in compact rows"
</WdTooltipWrapper>
)}
{settings.compact && (
<WdTooltipWrapper content="Show ship name in compact rows" position={TooltipPosition.top}>
<WdCheckbox
size="xs"
labelFull="Show ship name"
labelAbbreviated="Ship name"
labelSide="left"
label={compactShipName ? '' : 'Ship name'}
value={settings.showShipName}
onChange={() =>
setSettings((prev: any) => ({ ...prev, showShipName: !prev.showShipName }))
}
classNameLabel={clsx("whitespace-nowrap text-stone-400 hover:text-stone-200 transition duration-300", { truncate: compact })}
displayMode={displayMode}
onChange={() => setSettings((prev: any) => ({ ...prev, showShipName: !prev.showShipName }))}
classNameLabel={clsx('whitespace-nowrap text-stone-400 hover:text-stone-200 transition duration-300', {
truncate: compactShipName,
})}
/>
)}
</div>
</WdTooltipWrapper>
)}
</div>
<WdTooltipWrapper content="Enable compact mode" position={TooltipPosition.top}>
<span
className={clsx("w-4 h-4 cursor-pointer", {
"hero-bars-2": settings.compact,
"hero-bars-3": !settings.compact,
className={clsx('w-4 h-4 min-w-[1rem] cursor-pointer', {
'hero-bars-2': settings.compact,
'hero-bars-3': !settings.compact,
})}
onClick={() => setSettings((prev: any) => ({ ...prev, compact: !prev.compact }))}
/>
</LayoutEventBlocker>
</div>
</WdTooltipWrapper>
</LayoutEventBlocker>
</div>
);
};

View File

@@ -1,13 +1,6 @@
.VirtualScroller {
height: 100% !important;
}
.CharacterRow {
//border-left-width: 1px;
&.CardBorderLeftIsOwn {
border-left-color: rgb(251 146 60 / 1)
}
}

View File

@@ -0,0 +1,27 @@
import classes from './LocalCharactersItemTemplate.module.scss';
import clsx from 'clsx';
import { CharacterCard } from '@/hooks/Mapper/components/ui-kit';
import { CharItemProps } from '@/hooks/Mapper/components/mapInterface/widgets/LocalCharacters/components';
import { VirtualScrollerTemplateOptions } from 'primereact/virtualscroller';
export type LocalCharactersItemTemplateProps = { showShipName: boolean } & CharItemProps &
VirtualScrollerTemplateOptions;
export const LocalCharactersItemTemplate = ({ showShipName, ...options }: LocalCharactersItemTemplateProps) => {
return (
<div
className={clsx(
classes.CharacterRow,
'box-border flex items-center w-full whitespace-nowrap overflow-hidden text-ellipsis min-w-[0px]',
{
'surface-hover': options.odd,
'border-b border-gray-600 border-opacity-20': !options.last,
'bg-green-500 hover:bg-green-700 transition duration-300 bg-opacity-10 hover:bg-opacity-10': options.online,
},
)}
style={{ height: `${options.props.itemSize}px` }}
>
<CharacterCard showShipName={showShipName} {...options} />
</div>
);
};

View File

@@ -0,0 +1 @@
export * from './LocalCharactersItemTemplate.tsx';

View File

@@ -5,23 +5,24 @@ import { CharItemProps } from './types';
type LocalCharactersListProps = {
items: Array<CharItemProps>;
itemSize: number;
itemTemplate: (char: CharItemProps, options: VirtualScrollerTemplateOptions) => React.ReactNode;
containerClassName?: string;
};
export function LocalCharactersList({ items, itemSize, itemTemplate, containerClassName }: LocalCharactersListProps) {
export const LocalCharactersList = ({
items,
itemSize,
itemTemplate,
containerClassName,
}: LocalCharactersListProps) => {
return (
<VirtualScroller
items={items}
itemSize={itemSize}
orientation="vertical"
className={clsx('w-full h-full', containerClassName)}
autoSize={false}
itemTemplate={itemTemplate}
/>
);
}
};

View File

@@ -1,2 +1,3 @@
export * from './LocalCharactersItemTemplate';
export * from './LocalCharactersList';
export * from './types';

View File

@@ -1,33 +1,12 @@
import { useCallback } from 'react';
import { VirtualScrollerTemplateOptions } from 'primereact/virtualscroller';
import clsx from 'clsx';
import classes from './useLocalCharacters.module.scss';
import { CharacterCard } from '@/hooks/Mapper/components/ui-kit';
import { CharItemProps } from '../components';
import { CharItemProps, LocalCharactersItemTemplate } from '../components';
export function useLocalCharactersItemTemplate(showShipName: boolean) {
return useCallback(
(char: CharItemProps, options: VirtualScrollerTemplateOptions) => {
return (
<div
className={clsx(classes.CharacterRow, 'box-border flex items-center', {
'surface-hover': options.odd,
'border-b border-gray-600 border-opacity-20': !options.last,
'bg-green-500 hover:bg-green-700 transition duration-300 bg-opacity-10 hover:bg-opacity-10': char.online,
})}
style={{
height: `${options.props.itemSize}px`,
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
minWidth: 0,
width: '100%',
}}
>
<CharacterCard showShipName={showShipName} {...char} />
</div>
);
},
(char: CharItemProps, options: VirtualScrollerTemplateOptions) => (
<LocalCharactersItemTemplate {...char} {...options} showShipName={showShipName} />
),
[showShipName],
);
}

View File

@@ -1,7 +1,7 @@
import classes from './RoutesList.module.scss';
import { Route, SystemStaticInfoShort } from '@/hooks/Mapper/types/routes.ts';
import clsx from 'clsx';
import { SystemViewStandalone, WdTooltip, WdTooltipHandlers } from '@/hooks/Mapper/components/ui-kit';
import { SystemViewStandalone, TooltipPosition, WdTooltip, WdTooltipHandlers } from '@/hooks/Mapper/components/ui-kit';
import { getBackgroundClass, getShapeClass } from '@/hooks/Mapper/components/map/helpers';
import { MouseEvent, useCallback, useRef, useState } from 'react';
import { Commands } from '@/hooks/Mapper/types';
@@ -46,9 +46,11 @@ export const RouteSystem = ({
<>
<WdTooltip
ref={tooltipRef}
position={TooltipPosition.top}
// targetSelector={`.tooltip-route-sys_${destination}_${solar_system_id}`}
content={() => (
<SystemViewStandalone
className="mx-[4px]"
security={security}
system_class={system_class}
class_title={class_title}
@@ -63,8 +65,8 @@ export const RouteSystem = ({
tooltipRef.current?.show(e);
onMouseEnter?.(solar_system_id);
}}
onMouseLeave={e => {
tooltipRef.current?.hide(e);
onMouseLeave={() => {
tooltipRef.current?.hide();
onMouseLeave?.();
}}
onContextMenu={handleContext}

View File

@@ -184,7 +184,7 @@ export const RoutesWidgetComp = () => {
}, [data, update]);
const ref = useRef<HTMLDivElement>(null);
const compact = useMaxWidth(ref, 155);
const compact = useMaxWidth(ref, 170);
const [openAddSystem, setOpenAddSystem] = useState<boolean>(false);
const onAddSystem = useCallback(() => setOpenAddSystem(true), []);
@@ -217,14 +217,14 @@ export const RoutesWidgetComp = () => {
}}
/>
<WdTooltipWrapper content="Show shortest route">
<WdTooltipWrapper content="Show shortest route" position={TooltipPosition.top}>
<WdCheckbox
size="xs"
labelSide="left"
label={compact ? '' : 'Show shortest'}
value={!isSecure}
onChange={handleSecureChange}
classNameLabel={clsx('text-red-400')}
classNameLabel="text-red-400 whitespace-nowrap"
/>
</WdTooltipWrapper>
<WdImgButton

View File

@@ -1,15 +1,15 @@
import React, { useRef } from 'react';
import clsx from 'clsx';
import {
LayoutEventBlocker,
WdResponsiveCheckbox,
WdImgButton,
SystemView,
TooltipPosition,
WdDisplayMode,
WdCheckbox,
WdImgButton,
WdTooltipWrapper,
} from '@/hooks/Mapper/components/ui-kit';
import { useKillsWidgetSettings } from '../hooks/useKillsWidgetSettings';
import { PrimeIcons } from 'primereact/api';
import { useElementWidth } from '@/hooks/Mapper/components/hooks';
import useMaxWidth from '@/hooks/Mapper/hooks/useMaxWidth.ts';
interface KillsHeaderProps {
systemId?: string;
@@ -25,47 +25,41 @@ export const KillsHeader: React.FC<KillsHeaderProps> = ({ systemId, onOpenSettin
};
const headerRef = useRef<HTMLDivElement>(null);
const headerWidth = useElementWidth(headerRef) || 300;
const reservedWidth = 100;
const availableWidth = Math.max(headerWidth - reservedWidth, 0);
let displayMode: WdDisplayMode = "full";
if (availableWidth >= 60) {
displayMode = "full";
} else {
displayMode = "abbr";
}
const compact = useMaxWidth(headerRef, 150);
return (
<div className="flex w-full items-center text-xs" ref={headerRef}>
<div className="flex-shrink-0 select-none mr-2">
Kills{systemId && !showAll && ' in '}
<div className="flex w-full items-center justify-between text-xs" ref={headerRef}>
<div className="flex items-center gap-1">
<div className="text-stone-400">
Kills
{systemId && !showAll && ' in '}
</div>
{systemId && !showAll && <SystemView systemId={systemId} className="select-none text-center" hideRegion />}
</div>
<div className="flex-grow overflow-hidden">
<LayoutEventBlocker className="flex items-center gap-2 justify-end">
<div className="flex items-center gap-2">
<WdResponsiveCheckbox
tooltipContent="Show all systems"
<LayoutEventBlocker className="flex items-center gap-2 justify-end">
<div className="flex items-center gap-2">
<WdTooltipWrapper content="Show all systems" position={TooltipPosition.top}>
<WdCheckbox
size="xs"
labelFull="Show all systems"
labelAbbreviated="All"
labelSide="left"
label={compact ? 'All' : 'Show all systems'}
value={showAll}
onChange={onToggleShowAllVisible}
classNameLabel={clsx("whitespace-nowrap text-stone-400 hover:text-stone-200 transition duration-300")}
displayMode={displayMode}
classNameLabel="whitespace-nowrap text-stone-400 hover:text-stone-200 transition duration-300"
/>
<WdImgButton
className={PrimeIcons.SLIDERS_H}
onClick={onOpenSettings}
tooltip={{
content: 'Open Kills Settings',
position: TooltipPosition.left,
}}
/>
</div>
</LayoutEventBlocker>
</div>
</WdTooltipWrapper>
<WdImgButton
className={PrimeIcons.SLIDERS_H}
onClick={onOpenSettings}
tooltip={{
content: 'Open Kills Settings',
position: TooltipPosition.top,
}}
/>
</div>
</LayoutEventBlocker>
</div>
);
};