Compare commits

...

4 Commits

Author SHA1 Message Date
Dmitry Popov
3ce7ca928a Merge branch 'main' into show-sig-id 2025-01-12 13:15:27 +01:00
Dmitry Popov
16249950eb feat(Map): Add option to show sig ID in custom label 2025-01-12 13:15:08 +01:00
Dmitry Popov
0087bab3a2 Merge branch 'main' into show-sig-id 2025-01-11 22:18:42 +01:00
Dmitry Popov
34149799df feat(Map): Add option to show sig ID on system 2025-01-11 09:18:44 +01:00
48 changed files with 1005 additions and 235 deletions

View File

@@ -6,11 +6,7 @@ import { useMapState } from '@/hooks/Mapper/components/map/MapProvider.tsx';
import { useDoubleClick } from '@/hooks/Mapper/hooks/useDoubleClick.ts';
import { REGIONS_MAP, Spaces } from '@/hooks/Mapper/constants';
import { MapSolarSystemType } from '../../map.types';
import {
LABELS_INFO,
LABELS_ORDER,
getActivityType,
} from '@/hooks/Mapper/components/map/constants.ts';
import { LABELS_INFO, LABELS_ORDER, getActivityType } from '@/hooks/Mapper/components/map/constants.ts';
import { isWormholeSpace } from '@/hooks/Mapper/components/map/helpers/isWormholeSpace.ts';
import { getSystemClassStyles, prepareUnsplashedChunks } from '@/hooks/Mapper/components/map/helpers';
import { sortWHClasses } from '@/hooks/Mapper/helpers';
@@ -39,7 +35,8 @@ export function useSolarSystemNode({ data, selected }: UseSolarSystemNodeParams)
const { interfaceSettings } = useMapRootState();
const { isShowUnsplashedSignatures } = interfaceSettings;
const isTempSystemNameEnabled = useMapGetOption('show_temp_system_name') === 'true';
const isShowLinkedSigId = useMapGetOption('show_linked_signature_id') === 'true';
const {
data: {
characters,
@@ -71,33 +68,45 @@ export function useSolarSystemNode({ data, selected }: UseSolarSystemNodeParams)
solar_system_name,
} = data.system_static_info;
const { locked, name, tag, status, labels, id, temporary_name: temporaryName } = data || {};
const {
locked,
name,
tag,
status,
labels,
id,
temporary_name: temporaryName,
linked_sig_eve_id: linkedSigEveId = '',
} = data || {};
const signatures = data.system_signatures;
// 3) Compute derived values
const visible = useMemo(() => visibleNodes.has(id), [id, visibleNodes]);
const charactersInSystem = useMemo(() => {
return characters
.filter(c => c.location?.solar_system_id === solar_system_id)
.filter(c => c.online);
return characters.filter(c => c.location?.solar_system_id === solar_system_id).filter(c => c.online);
}, [characters, presentCharacters, solar_system_id]);
const isWormhole = isWormholeSpace(system_class);
const classTitleColor = useMemo(
() => getSystemClassStyles({ systemClass: system_class, security }),
[security, system_class],
);
const sortedStatics = useMemo(
() => sortWHClasses(wormholesData, statics),
[wormholesData, statics],
);
const sortedStatics = useMemo(() => sortWHClasses(wormholesData, statics), [wormholesData, statics]);
const linkedSigPrefix = useMemo(() => (linkedSigEveId ? linkedSigEveId.split('-')[0] : null), [linkedSigEveId]);
const labelsManager = useMemo(() => new LabelsManager(labels ?? ''), [labels]);
const labelsInfo = useMemo(() => sortedLabels(labelsManager.list), [labelsManager]);
const labelCustom = useMemo(() => labelsManager.customLabel, [labelsManager]);
const labelCustom = useMemo(
() =>
isShowLinkedSigId && linkedSigPrefix
? `${linkedSigPrefix}${labelsManager.customLabel}`
: labelsManager.customLabel,
[linkedSigPrefix, isShowLinkedSigId, labelsManager],
);
const killsCount = useMemo(() => {
const systemKills = kills[solar_system_id];
@@ -124,8 +133,7 @@ export function useSolarSystemNode({ data, selected }: UseSolarSystemNodeParams)
const regionClass = showKSpaceBG ? SpaceToClass[space] : null;
const systemName = (isTempSystemNameEnabled && temporaryName) || solar_system_name;
const customName = (isTempSystemNameEnabled && temporaryName && name)
|| (solar_system_name !== name && name);
const customName = (isTempSystemNameEnabled && temporaryName && name) || (solar_system_name !== name && name);
const [unsplashedLeft, unsplashedRight] = useMemo(() => {
if (!isShowUnsplashedSignatures) {

View File

@@ -2,7 +2,7 @@ import { memo } from 'react';
import { Handle, Position } from 'reactflow';
import clsx from 'clsx';
import classes from './SolarSystemNodeDefault.module.scss';
import classes from './SolarSystemNodeDefault.module.scss';
import { PrimeIcons } from 'primereact/api';
import { useSolarSystemNode } from '../../hooks/useSolarSystemNode';
@@ -15,47 +15,65 @@ import {
import { WormholeClassComp } from '@/hooks/Mapper/components/map/components/WormholeClassComp';
import { UnsplashedSignature } from '@/hooks/Mapper/components/map/components/UnsplashedSignature';
export const SolarSystemNodeDefault = memo((props) => {
const nodeVars = useSolarSystemNode(props);
export const SolarSystemNodeDefault = memo(props => {
const {
charactersInSystem,
classTitle,
classTitleColor,
customName,
effectName,
hasUserCharacters,
hubs,
visible,
labelCustom,
labelsInfo,
locked,
isShattered,
isThickConnections,
isWormhole,
killsCount,
killsActivityType,
regionClass,
regionName,
status,
selected,
tag,
showHandlers,
systemName,
sortedStatics,
solarSystemId,
unsplashedLeft,
unsplashedRight,
dbClick: handleDbClick,
} = useSolarSystemNode(props);
return (
<>
{nodeVars.visible && (
{visible && (
<div className={classes.Bookmarks}>
{nodeVars.labelCustom !== '' && (
{labelCustom !== '' && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES.custom)}>
<span className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] ">
{nodeVars.labelCustom}
</span>
<span className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] ">{labelCustom}</span>
</div>
)}
{nodeVars.isShattered && (
{isShattered && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES.shattered)}>
<span className={clsx('pi pi-chart-pie', classes.icon)} />
</div>
)}
{nodeVars.killsCount && (
<div
className={clsx(
classes.Bookmark,
MARKER_BOOKMARK_BG_STYLES[nodeVars.killsActivityType!]
)}
>
{killsCount && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[killsActivityType!])}>
<div className={clsx(classes.BookmarkWithIcon)}>
<span className={clsx(PrimeIcons.BOLT, classes.icon)} />
<span className={clsx(classes.text)}>{nodeVars.killsCount}</span>
<span className={clsx(classes.text)}>{killsCount}</span>
</div>
</div>
)}
{nodeVars.labelsInfo.map(x => (
<div
key={x.id}
className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[x.id])}
>
{labelsInfo.map(x => (
<div key={x.id} className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[x.id])}>
{x.shortName}
</div>
))}
@@ -63,30 +81,19 @@ export const SolarSystemNodeDefault = memo((props) => {
)}
<div
className={clsx(
classes.RootCustomNode,
nodeVars.regionClass && classes[nodeVars.regionClass],
classes[STATUS_CLASSES[nodeVars.status]],
{ [classes.selected]: nodeVars.selected },
)}
className={clsx(classes.RootCustomNode, regionClass && classes[regionClass], classes[STATUS_CLASSES[status]], {
[classes.selected]: selected,
})}
>
{nodeVars.visible && (
{visible && (
<>
<div className={classes.HeadRow}>
<div
className={clsx(
classes.classTitle,
nodeVars.classTitleColor,
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)]',
)}
>
{nodeVars.classTitle ?? '-'}
<div className={clsx(classes.classTitle, classTitleColor, '[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)]')}>
{classTitle ?? '-'}
</div>
{nodeVars.tag != null && nodeVars.tag !== '' && (
<div className={clsx(classes.TagTitle, 'text-sky-400 font-medium')}>
{nodeVars.tag}
</div>
{tag != null && tag !== '' && (
<div className={clsx(classes.TagTitle, 'text-sky-400 font-medium')}>{tag}</div>
)}
<div
@@ -95,70 +102,53 @@ export const SolarSystemNodeDefault = memo((props) => {
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] flex-grow overflow-hidden text-ellipsis whitespace-nowrap font-sans',
)}
>
{nodeVars.systemName}
{systemName}
</div>
{nodeVars.isWormhole && (
{isWormhole && (
<div className={classes.statics}>
{nodeVars.sortedStatics.map(whClass => (
{sortedStatics.map(whClass => (
<WormholeClassComp key={whClass} id={whClass} />
))}
</div>
)}
{nodeVars.effectName !== null && nodeVars.isWormhole && (
<div
className={clsx(
classes.effect,
EFFECT_BACKGROUND_STYLES[nodeVars.effectName],
)}
/>
{effectName !== null && isWormhole && (
<div className={clsx(classes.effect, EFFECT_BACKGROUND_STYLES[effectName])} />
)}
</div>
<div className={clsx(classes.BottomRow, 'flex items-center justify-between')}>
{nodeVars.customName && (
{customName && (
<div className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] text-blue-300 whitespace-nowrap overflow-hidden text-ellipsis mr-0.5">
{nodeVars.customName}
{customName}
</div>
)}
{!nodeVars.isWormhole && !nodeVars.customName && (
<div
className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] text-stone-300 whitespace-nowrap overflow-hidden text-ellipsis mr-0.5"
>
{nodeVars.regionName}
{!isWormhole && !customName && (
<div className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] text-stone-300 whitespace-nowrap overflow-hidden text-ellipsis mr-0.5">
{regionName}
</div>
)}
{nodeVars.isWormhole && !nodeVars.customName && <div />}
{isWormhole && !customName && <div />}
<div className="flex items-center justify-end">
<div className="flex gap-1 items-center">
{nodeVars.locked && (
<i
className={PrimeIcons.LOCK}
style={{ fontSize: '0.45rem', fontWeight: 'bold' }}
/>
{locked && <i className={PrimeIcons.LOCK} style={{ fontSize: '0.45rem', fontWeight: 'bold' }} />}
{hubs.includes(solarSystemId.toString()) && (
<i className={PrimeIcons.MAP_MARKER} style={{ fontSize: '0.45rem', fontWeight: 'bold' }} />
)}
{nodeVars.hubs.includes(nodeVars.solarSystemId.toString()) && (
<i
className={PrimeIcons.MAP_MARKER}
style={{ fontSize: '0.45rem', fontWeight: 'bold' }}
/>
)}
{nodeVars.charactersInSystem.length > 0 && (
{charactersInSystem.length > 0 && (
<div
className={clsx(classes.localCounter, {
['text-amber-300']: nodeVars.hasUserCharacters,
['text-amber-300']: hasUserCharacters,
})}
>
<i className="pi pi-users" style={{ fontSize: '0.50rem' }} />
<span className="font-sans">
{nodeVars.charactersInSystem.length}
</span>
<span className="font-sans">{charactersInSystem.length}</span>
</div>
)}
</div>
@@ -168,19 +158,19 @@ export const SolarSystemNodeDefault = memo((props) => {
)}
</div>
{nodeVars.visible && (
{visible && (
<>
{nodeVars.unsplashedLeft.length > 0 && (
{unsplashedLeft.length > 0 && (
<div className={classes.Unsplashed}>
{nodeVars.unsplashedLeft.map(sig => (
{unsplashedLeft.map(sig => (
<UnsplashedSignature key={sig.sig_id} signature={sig} />
))}
</div>
)}
{nodeVars.unsplashedRight.length > 0 && (
{unsplashedRight.length > 0 && (
<div className={clsx(classes.Unsplashed, classes['Unsplashed--right'])}>
{nodeVars.unsplashedRight.map(sig => (
{unsplashedRight.map(sig => (
<UnsplashedSignature key={sig.sig_id} signature={sig} />
))}
</div>
@@ -188,44 +178,44 @@ export const SolarSystemNodeDefault = memo((props) => {
</>
)}
<div onMouseDownCapture={nodeVars.dbClick} className={classes.Handlers}>
<div onMouseDownCapture={handleDbClick} className={classes.Handlers}>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleTop, {
[classes.selected]: nodeVars.selected,
[classes.Tick]: nodeVars.isThickConnections,
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: nodeVars.showHandlers ? 'visible' : 'hidden' }}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Top}
id="a"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleRight, {
[classes.selected]: nodeVars.selected,
[classes.Tick]: nodeVars.isThickConnections,
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: nodeVars.showHandlers ? 'visible' : 'hidden' }}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Right}
id="b"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleBottom, {
[classes.selected]: nodeVars.selected,
[classes.Tick]: nodeVars.isThickConnections,
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: nodeVars.showHandlers ? 'visible' : 'hidden' }}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Bottom}
id="c"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleLeft, {
[classes.selected]: nodeVars.selected,
[classes.Tick]: nodeVars.isThickConnections,
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: nodeVars.showHandlers ? 'visible' : 'hidden' }}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Left}
id="d"
/>
@@ -233,3 +223,5 @@ export const SolarSystemNodeDefault = memo((props) => {
</>
);
});
SolarSystemNodeDefault.displayName = 'SolarSystemNodeDefault';

View File

@@ -2,7 +2,7 @@ import { memo } from 'react';
import { Handle, Position } from 'reactflow';
import clsx from 'clsx';
import classes from './SolarSystemNodeTheme.module.scss';
import classes from './SolarSystemNodeTheme.module.scss';
import { PrimeIcons } from 'primereact/api';
import { useSolarSystemNode } from '../../hooks/useSolarSystemNode';
@@ -15,47 +15,65 @@ import {
import { WormholeClassComp } from '@/hooks/Mapper/components/map/components/WormholeClassComp';
import { UnsplashedSignature } from '@/hooks/Mapper/components/map/components/UnsplashedSignature';
export const SolarSystemNodeTheme = memo((props) => {
const nodeVars = useSolarSystemNode(props);
export const SolarSystemNodeTheme = memo(props => {
const {
charactersInSystem,
classTitle,
classTitleColor,
customName,
effectName,
hasUserCharacters,
hubs,
visible,
labelCustom,
labelsInfo,
locked,
isShattered,
isThickConnections,
isWormhole,
killsCount,
killsActivityType,
regionClass,
regionName,
status,
selected,
tag,
showHandlers,
systemName,
sortedStatics,
solarSystemId,
unsplashedLeft,
unsplashedRight,
dbClick: handleDbClick,
} = useSolarSystemNode(props);
return (
<>
{nodeVars.visible && (
{visible && (
<div className={classes.Bookmarks}>
{nodeVars.labelCustom !== '' && (
{labelCustom !== '' && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES.custom)}>
<span className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] ">
{nodeVars.labelCustom}
</span>
<span className="[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] ">{labelCustom}</span>
</div>
)}
{nodeVars.isShattered && (
{isShattered && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES.shattered)}>
<span className={clsx('pi pi-chart-pie', classes.icon)} />
</div>
)}
{nodeVars.killsCount && (
<div
className={clsx(
classes.Bookmark,
MARKER_BOOKMARK_BG_STYLES[nodeVars.killsActivityType!]
)}
>
{killsCount && (
<div className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[killsActivityType!])}>
<div className={clsx(classes.BookmarkWithIcon)}>
<span className={clsx(PrimeIcons.BOLT, classes.icon)} />
<span className={clsx(classes.text)}>{nodeVars.killsCount}</span>
<span className={clsx(classes.text)}>{killsCount}</span>
</div>
</div>
)}
{nodeVars.labelsInfo.map(x => (
<div
key={x.id}
className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[x.id])}
>
{labelsInfo.map(x => (
<div key={x.id} className={clsx(classes.Bookmark, MARKER_BOOKMARK_BG_STYLES[x.id])}>
{x.shortName}
</div>
))}
@@ -63,31 +81,18 @@ export const SolarSystemNodeTheme = memo((props) => {
)}
<div
className={clsx(
classes.RootCustomNode,
nodeVars.regionClass && classes[nodeVars.regionClass],
classes[STATUS_CLASSES[nodeVars.status]],
{ [classes.selected]: nodeVars.selected },
)}
className={clsx(classes.RootCustomNode, regionClass && classes[regionClass], classes[STATUS_CLASSES[status]], {
[classes.selected]: selected,
})}
>
{nodeVars.visible && (
{visible && (
<>
<div className={classes.HeadRow}>
<div
className={clsx(
classes.classTitle,
nodeVars.classTitleColor,
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)]',
)}
>
{nodeVars.classTitle ?? '-'}
<div className={clsx(classes.classTitle, classTitleColor, '[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)]')}>
{classTitle ?? '-'}
</div>
{nodeVars.tag != null && nodeVars.tag !== '' && (
<div className={clsx(classes.TagTitle)}>
{nodeVars.tag}
</div>
)}
{tag != null && tag !== '' && <div className={clsx(classes.TagTitle)}>{tag}</div>}
<div
className={clsx(
@@ -95,71 +100,63 @@ export const SolarSystemNodeTheme = memo((props) => {
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] flex-grow overflow-hidden text-ellipsis whitespace-nowrap',
)}
>
{nodeVars.systemName}
{systemName}
</div>
{nodeVars.isWormhole && (
{isWormhole && (
<div className={classes.statics}>
{nodeVars.sortedStatics.map(whClass => (
{sortedStatics.map(whClass => (
<WormholeClassComp key={whClass} id={whClass} />
))}
</div>
)}
{nodeVars.effectName !== null && nodeVars.isWormhole && (
<div className={clsx(classes.effect, EFFECT_BACKGROUND_STYLES[nodeVars.effectName])} />
{effectName !== null && isWormhole && (
<div className={clsx(classes.effect, EFFECT_BACKGROUND_STYLES[effectName])} />
)}
</div>
<div className={clsx(classes.BottomRow, 'flex items-center justify-between')}>
{nodeVars.customName && (
{customName && (
<div
className={clsx(
classes.CustomName,
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] whitespace-nowrap overflow-hidden text-ellipsis mr-0.5',
)}
>
{nodeVars.customName}
{customName}
</div>
)}
{!nodeVars.isWormhole && !nodeVars.customName && (
{!isWormhole && !customName && (
<div
className={clsx(
classes.RegionName,
'[text-shadow:_0_1px_0_rgb(0_0_0_/_40%)] whitespace-nowrap overflow-hidden text-ellipsis mr-0.5',
)}
>
{nodeVars.regionName}
{regionName}
</div>
)}
{nodeVars.isWormhole && !nodeVars.customName && <div />}
{isWormhole && !customName && <div />}
<div className="flex items-center justify-end">
<div className="flex gap-1 items-center">
{nodeVars.locked && (
<i
className={PrimeIcons.LOCK}
style={{ fontSize: '0.45rem', fontWeight: 'bold' }}
/>
{locked && <i className={PrimeIcons.LOCK} style={{ fontSize: '0.45rem', fontWeight: 'bold' }} />}
{hubs.includes(solarSystemId.toString()) && (
<i className={PrimeIcons.MAP_MARKER} style={{ fontSize: '0.45rem', fontWeight: 'bold' }} />
)}
{nodeVars.hubs.includes(nodeVars.solarSystemId.toString()) && (
<i
className={PrimeIcons.MAP_MARKER}
style={{ fontSize: '0.45rem', fontWeight: 'bold' }}
/>
)}
{nodeVars.charactersInSystem.length > 0 && (
{charactersInSystem.length > 0 && (
<div
className={clsx(classes.localCounter, {
[classes.hasUserCharacters]: nodeVars.hasUserCharacters,
[classes.hasUserCharacters]: hasUserCharacters,
})}
>
<i className="pi pi-users" style={{ fontSize: '0.50rem' }} />
<span className="font-sans">{nodeVars.charactersInSystem.length}</span>
<span className="font-sans">{charactersInSystem.length}</span>
</div>
)}
</div>
@@ -169,19 +166,19 @@ export const SolarSystemNodeTheme = memo((props) => {
)}
</div>
{nodeVars.visible && (
{visible && (
<>
{nodeVars.unsplashedLeft.length > 0 && (
{unsplashedLeft.length > 0 && (
<div className={classes.Unsplashed}>
{nodeVars.unsplashedLeft.map(sig => (
{unsplashedLeft.map(sig => (
<UnsplashedSignature key={sig.sig_id} signature={sig} />
))}
</div>
)}
{nodeVars.unsplashedRight.length > 0 && (
{unsplashedRight.length > 0 && (
<div className={clsx(classes.Unsplashed, classes['Unsplashed--right'])}>
{nodeVars.unsplashedRight.map(sig => (
{unsplashedRight.map(sig => (
<UnsplashedSignature key={sig.sig_id} signature={sig} />
))}
</div>
@@ -189,44 +186,44 @@ export const SolarSystemNodeTheme = memo((props) => {
</>
)}
<div onMouseDownCapture={nodeVars.dbClick} className={classes.Handlers}>
<div onMouseDownCapture={handleDbClick} className={classes.Handlers}>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleTop, {
[classes.selected]: nodeVars.selected,
[classes.Tick]: nodeVars.isThickConnections,
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: nodeVars.showHandlers ? 'visible' : 'hidden' }}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Top}
id="a"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleRight, {
[classes.selected]: nodeVars.selected,
[classes.Tick]: nodeVars.isThickConnections,
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: nodeVars.showHandlers ? 'visible' : 'hidden' }}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Right}
id="b"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleBottom, {
[classes.selected]: nodeVars.selected,
[classes.Tick]: nodeVars.isThickConnections,
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: nodeVars.showHandlers ? 'visible' : 'hidden' }}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Bottom}
id="c"
/>
<Handle
type="source"
className={clsx(classes.Handle, classes.HandleLeft, {
[classes.selected]: nodeVars.selected,
[classes.Tick]: nodeVars.isThickConnections,
[classes.selected]: selected,
[classes.Tick]: isThickConnections,
})}
style={{ visibility: nodeVars.showHandlers ? 'visible' : 'hidden' }}
style={{ visibility: showHandlers ? 'visible' : 'hidden' }}
position={Position.Left}
id="d"
/>
@@ -234,3 +231,5 @@ export const SolarSystemNodeTheme = memo((props) => {
</>
);
});
SolarSystemNodeTheme.displayName = 'SolarSystemNodeTheme';

View File

@@ -32,7 +32,17 @@ function sortedLabels(labels: string[]) {
export function useSolarSystemNode(props: any) {
const { data, selected, id } = props;
const { system_static_info, system_signatures, locked, name, tag, status, labels, temporary_name } = data;
const {
system_static_info,
system_signatures,
locked,
name,
tag,
status,
labels,
temporary_name,
linked_sig_eve_id: linkedSigEveId = '',
} = data;
const {
system_class,
@@ -51,6 +61,7 @@ export function useSolarSystemNode(props: any) {
const { interfaceSettings } = useMapRootState();
const { isShowUnsplashedSignatures } = interfaceSettings;
const isTempSystemNameEnabled = useMapGetOption('show_temp_system_name') === 'true';
const isShowLinkedSigId = useMapGetOption('show_linked_signature_id') === 'true';
const {
data: {
@@ -85,10 +96,18 @@ export function useSolarSystemNode(props: any) {
);
const sortedStatics = useMemo(() => sortWHClasses(wormholesData, statics), [wormholesData, statics]);
const linkedSigPrefix = useMemo(() => (linkedSigEveId ? linkedSigEveId.split('-')[0] : null), [linkedSigEveId]);
const labelsManager = useMemo(() => new LabelsManager(labels ?? ''), [labels]);
const labelsInfo = useMemo(() => sortedLabels(labelsManager.list), [labelsManager]);
const labelCustom = useMemo(() => labelsManager.customLabel, [labelsManager]);
const labelCustom = useMemo(
() =>
isShowLinkedSigId && linkedSigPrefix
? `${linkedSigPrefix}${labelsManager.customLabel}`
: labelsManager.customLabel,
[linkedSigPrefix, isShowLinkedSigId, labelsManager],
);
const killsCount = useMemo(() => kills[solar_system_id] ?? null, [kills, solar_system_id]);
const killsActivityType = killsCount ? getActivityType(killsCount) : null;
@@ -110,8 +129,7 @@ export function useSolarSystemNode(props: any) {
const regionClass = showKSpaceBG ? SpaceToClass[space] : null;
const systemName = (isTempSystemNameEnabled && temporary_name) || solar_system_name;
const customName =
(isTempSystemNameEnabled && temporary_name && name) || (solar_system_name !== name && name);
const customName = (isTempSystemNameEnabled && temporary_name && name) || (solar_system_name !== name && name);
const [unsplashedLeft, unsplashedRight] = useMemo(() => {
if (!isShowUnsplashedSignatures) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -48,6 +48,7 @@ defmodule WandererApp.Api.MapSystem do
define(:update_tag, action: :update_tag)
define(:update_temporary_name, action: :update_temporary_name)
define(:update_labels, action: :update_labels)
define(:update_linked_sig_eve_id, action: :update_linked_sig_eve_id)
define(:update_position, action: :update_position)
define(:update_visible, action: :update_visible)
end
@@ -117,6 +118,10 @@ defmodule WandererApp.Api.MapSystem do
change(set_attribute(:visible, true))
end
update :update_linked_sig_eve_id do
accept [:linked_sig_eve_id]
end
update :update_visible do
accept [:visible]
end
@@ -193,6 +198,10 @@ defmodule WandererApp.Api.MapSystem do
allow_nil? true
end
attribute :linked_sig_eve_id, :string do
allow_nil? true
end
create_timestamp(:inserted_at)
update_timestamp(:updated_at)
end

View File

@@ -105,6 +105,12 @@ defmodule WandererApp.Map.Server do
|> map_pid!
|> GenServer.cast({&Impl.update_system_position/2, [update]})
def update_system_linked_sig_eve_id(map_id, update) when is_binary(map_id),
do:
map_id
|> map_pid!
|> GenServer.cast({&Impl.update_system_linked_sig_eve_id/2, [update]})
def update_system_name(map_id, update) when is_binary(map_id),
do:
map_id
@@ -129,7 +135,7 @@ defmodule WandererApp.Map.Server do
|> map_pid!
|> GenServer.cast({&Impl.update_system_tag/2, [update]})
def update_system_temporary_name(map_id, update) when is_binary(map_id),
def update_system_temporary_name(map_id, update) when is_binary(map_id),
do:
map_id
|> map_pid!

View File

@@ -156,6 +156,8 @@ defmodule WandererApp.Map.Server.Impl do
defdelegate update_system_labels(state, update), to: SystemsImpl
defdelegate update_system_linked_sig_eve_id(state, update), to: SystemsImpl
defdelegate update_system_position(state, update), to: SystemsImpl
defdelegate add_hub(state, hub_info), to: SystemsImpl
@@ -322,6 +324,8 @@ defmodule WandererApp.Map.Server.Impl do
layout: options |> Map.get("layout", "left_to_right"),
store_custom_labels:
options |> Map.get("store_custom_labels", "false") |> String.to_existing_atom(),
show_linked_signature_id:
options |> Map.get("show_linked_signature_id", "false") |> String.to_existing_atom(),
show_temp_system_name:
options |> Map.get("show_temp_system_name", "false") |> String.to_existing_atom(),
restrict_offline_showing:
@@ -432,7 +436,7 @@ defmodule WandererApp.Map.Server.Impl do
"position" => %{"x" => x, "y" => y},
"status" => status,
"tag" => tag,
"temporary_name" => temporary_name,
"temporary_name" => temporary_name
} = _system,
acc ->
acc
@@ -451,7 +455,10 @@ defmodule WandererApp.Map.Server.Impl do
})
|> update_system_status(%{solar_system_id: id |> String.to_integer(), status: status})
|> update_system_tag(%{solar_system_id: id |> String.to_integer(), tag: tag})
|> update_system_temporary_name(%{solar_system_id: id |> String.to_integer(), temporary_name: temporary_name})
|> update_system_temporary_name(%{
solar_system_id: id |> String.to_integer(),
temporary_name: temporary_name
})
|> update_system_locked(%{solar_system_id: id |> String.to_integer(), locked: locked})
|> update_system_labels(%{solar_system_id: id |> String.to_integer(), labels: labels})
end)

View File

@@ -126,7 +126,7 @@ defmodule WandererApp.Map.Server.SystemsImpl do
state,
update
) do
state |> update_system(:update_temporary_name, [:temporary_name], update)
state |> update_system(:update_temporary_name, [:temporary_name], update)
end
def update_system_locked(
@@ -141,6 +141,12 @@ defmodule WandererApp.Map.Server.SystemsImpl do
),
do: state |> update_system(:update_labels, [:labels], update)
def update_system_linked_sig_eve_id(
state,
update
),
do: state |> update_system(:update_linked_sig_eve_id, [:linked_sig_eve_id], update)
def update_system_position(
%{rtree_name: rtree_name} = state,
update
@@ -294,6 +300,7 @@ defmodule WandererApp.Map.Server.SystemsImpl do
|> WandererApp.MapSystemRepo.update_visible!(%{visible: true})
|> WandererApp.MapSystemRepo.cleanup_tags!()
|> WandererApp.MapSystemRepo.cleanup_temporary_name!()
|> WandererApp.MapSystemRepo.cleanup_linked_sig_eve_id!()
@ddrt.insert(
{existing_system.solar_system_id,
@@ -413,6 +420,7 @@ defmodule WandererApp.Map.Server.SystemsImpl do
|> WandererApp.MapSystemRepo.cleanup_labels!(map_opts)
|> WandererApp.MapSystemRepo.cleanup_tags!()
|> WandererApp.MapSystemRepo.cleanup_temporary_name!()
|> WandererApp.MapSystemRepo.cleanup_linked_sig_eve_id!()
|> WandererApp.MapSystemRepo.update_visible(%{visible: true})
end

View File

@@ -4,6 +4,7 @@ defmodule WandererApp.MapRepo do
@default_map_options %{
"layout" => "left_to_right",
"store_custom_labels" => "false",
"show_linked_signature_id" => "false",
"show_temp_system_name" => "false",
"restrict_offline_showing" => "false"
}

View File

@@ -75,6 +75,13 @@ defmodule WandererApp.MapSystemRepo do
})
end
def cleanup_linked_sig_eve_id!(system) do
system
|> WandererApp.Api.MapSystem.update_linked_sig_eve_id!(%{
linked_sig_eve_id: nil
})
end
def get_filtered_labels(labels, true) when is_binary(labels) do
labels
|> Jason.decode!()
@@ -116,8 +123,8 @@ defmodule WandererApp.MapSystemRepo do
|> WandererApp.Api.MapSystem.update_tag(update)
def update_temporary_name(system, update) do
system
|> WandererApp.Api.MapSystem.update_temporary_name(update)
system
|> WandererApp.Api.MapSystem.update_temporary_name(update)
end
def update_labels(system, update),
@@ -130,6 +137,16 @@ defmodule WandererApp.MapSystemRepo do
system
|> WandererApp.Api.MapSystem.update_labels!(update)
def update_linked_sig_eve_id(system, update),
do:
system
|> WandererApp.Api.MapSystem.update_linked_sig_eve_id(update)
def update_linked_sig_eve_id!(system, update),
do:
system
|> WandererApp.Api.MapSystem.update_linked_sig_eve_id!(update)
def update_position(system, update),
do:
system

View File

@@ -234,6 +234,12 @@ defmodule WandererAppWeb.MapSignaturesEventHandler do
})
end)
map_id
|> WandererApp.Map.Server.update_system_linked_sig_eve_id(%{
solar_system_id: solar_system_target,
linked_sig_eve_id: signature_eve_id
})
Phoenix.PubSub.broadcast!(WandererApp.PubSub, map_id, %{
event: :signatures_updated,
payload: solar_system_source

View File

@@ -245,6 +245,7 @@ defmodule WandererAppWeb.MapEventHandler do
locked: locked,
tag: tag,
labels: labels,
linked_sig_eve_id: linked_sig_eve_id,
temporary_name: temporary_name,
status: status,
visible: visible
@@ -269,6 +270,7 @@ defmodule WandererAppWeb.MapEventHandler do
system_signatures: system_signatures,
labels: labels,
locked: locked,
linked_sig_eve_id: linked_sig_eve_id,
status: status,
tag: tag,
temporary_name: temporary_name,

View File

@@ -180,7 +180,6 @@ defmodule WandererAppWeb.MapsLive do
{:noreply, socket}
end
def handle_event("generate-map-api-key", _params, socket) do
new_api_key = UUID.uuid4()
@@ -192,7 +191,6 @@ defmodule WandererAppWeb.MapsLive do
{:noreply, assign(socket, public_api_key: new_api_key)}
end
@impl true
def handle_event(
"live_select_change",
@@ -685,6 +683,7 @@ defmodule WandererAppWeb.MapsLive do
|> Map.take([
"layout",
"store_custom_labels",
"show_linked_signature_id",
"show_temp_system_name",
"restrict_offline_showing"
])

View File

@@ -317,7 +317,9 @@
:if={not WandererApp.Env.public_api_disabled?()}
class={[
"p-unselectable-text",
classes("p-tabview-selected p-highlight": @active_settings_tab == "public_api")
classes(
"p-tabview-selected p-highlight": @active_settings_tab == "public_api"
)
]}
role="presentation"
data-pc-name=""
@@ -371,10 +373,15 @@
field={f[:store_custom_labels]}
label="Store system custom labels"
/>
<.input
type="checkbox"
field={f[:show_linked_signature_id]}
label="Show linked signature ID as custom label part"
/>
<.input
type="checkbox"
field={f[:show_temp_system_name]}
label="Allow Temporary System Names"
label="Allow temporary system names"
/>
<.input
type="checkbox"
@@ -408,7 +415,13 @@
</.button>
</div>
<div :if={@active_settings_tab == "public_api"and not WandererApp.Env.public_api_disabled?()} class="p-6">
<div
:if={
@active_settings_tab == "public_api" and
not WandererApp.Env.public_api_disabled?()
}
class="p-6"
>
<h2 class="text-lg font-semibold mb-4">Public API</h2>
<div class="flex flex-col gap-3 items-start w-full">
<div>
@@ -428,29 +441,26 @@
/>
</div>
<div class="flex items-center gap-2">
<.button
class="btn btn-primary rounded-md"
phx-click="generate-map-api-key"
>
<.button class="btn btn-primary rounded-md" phx-click="generate-map-api-key">
Generate
</.button>
<.button
phx-hook="CopyToClipboard"
id="copy-map-api-key"
data-url={@public_api_key}
disabled={is_nil(@public_api_key)}
class={
if is_nil(@public_api_key) do
"copy-link btn rounded-md transition-colors duration-300
<.button
phx-hook="CopyToClipboard"
id="copy-map-api-key"
data-url={@public_api_key}
disabled={is_nil(@public_api_key)}
class={
if is_nil(@public_api_key) do
"copy-link btn rounded-md transition-colors duration-300
bg-gray-500 hover:bg-gray-500 text-gray-300 cursor-not-allowed"
else
"copy-link btn rounded-md transition-colors duration-300
else
"copy-link btn rounded-md transition-colors duration-300
bg-blue-600 hover:bg-blue-700 text-white cursor-pointer"
end
}
>
Copy
</.button>
end
}
>
Copy
</.button>
</div>
</div>
</div>

View File

@@ -0,0 +1,88 @@
%{
title: "Map User Settings (from our community member)",
author: "Wanderer Community",
cover_image_uri: "/images/news/01-11-map-settings-guide/cover.png",
tags: ~w(map settings guide interface),
description: "",
}
---
## Map User Settings
- Click on the **Map user settings** button on the bottom-right unless you have the dock disabled in which case you could click the menu button top-right.
Map user settings depending on whether the dock is enabled or not:
![](/images/news/01-11-map-settings-guide/2024-12-05-08-38-59-image.png) or ![](/images/news/01-11-map-settings-guide/2025-01-11-16-06-36-image.png)
- Disable the minimap in the **Common** section - it may cause performance issues for some
![](/images/news/01-11-map-settings-guide/2024-12-05-08-39-19-image.png)
- In the **Systems** section, Enable Auto-Select splashed unless you want only a specific character to be followed on the map and optionally the Highlight Low/High-security systems
![](/images/news/01-11-map-settings-guide/2025-01-11-16-08-10-image.png)\*
- In the **Connections** section, enable the 'Delete connections to linked signatures' and the 'Thicker connections' options
![](/images/news/01-11-map-settings-guide/2025-01-11-16-09-07-image.png)
- In the **Signatures** section, enable the 'Link signature on splash' and 'Show unsplashed signatures'
![](/images/news/01-11-map-settings-guide/2024-12-05-08-40-20-image.png)
- Under the **User Interface** section, you can select whatever options suite you. Below are my preferences
![](/images/news/01-11-map-settings-guide/2025-01-11-16-12-53-image.png)
- For the theme, you can select what you want. I prefer the default.
![](/images/news/01-11-map-settings-guide/2025-01-11-16-14-43-image.png)
- Under the tracking menu, you can select which character the map will follow while scanning and splashing holes.
![](/images/news/01-11-map-settings-guide/2025-01-11-17-28-36-image.png)
This will ONLY work if you disable the **Auto-select splashed** option in the Map User settings menu. Otherwise, Wanderer will select the system most recently splashed by any of your tracked characters.
![](/images/news/01-11-map-settings-guide/GamYHSA5Ij.png)
---
## Signature Widget setup
- Click the signature settings button at the very top-right
![](/images/news/01-11-map-settings-guide/2025-01-11-16-15-42-image.png)
- Under **Filters** you should have at least the 'Show Cosmic Signatures' and 'Show Wormholes' checked. All of the others are optional but having too many will make the widget difficult to read.
![](/images/news/01-11-map-settings-guide/2025-01-11-16-16-21-image.png)
- Under the **User Interface** section, enable the 'Show Updated Column' and 'Show Description Column' options. The other options should be disabled.
![](/images/news/01-11-map-settings-guide/2025-01-11-16-17-45-image.png)
- Click **'Save'**
---
## Map Settings
### Admins and Corp / Alliance Leadership
The below settings are recommended for usability and security.
![](/images/news/01-11-map-settings-guide/2025-01-11-16-24-51-image.png)
- **Allow Temporary System Names**
This feature enables a new text-box when editing system data. This can be used for details that may not carry over to the next time you visit the system
The temporary name is deleted when the system is removed from the map
![](/images/news/01-11-map-settings-guide/2025-01-11-16-28-16-image.png)
- **Show offline characters to admins and managers Only**
Prevents anyone that is not a manager or admin from seeing offline users and their ships and locations when viewing the 'On the map' feature.

View File

@@ -0,0 +1,21 @@
defmodule WandererApp.Repo.Migrations.SystemLinkedSigEveId 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
alter table(:map_system_v1) do
add :linked_sig_eve_id, :text
end
end
def down do
alter table(:map_system_v1) do
remove :linked_sig_eve_id
end
end
end

View File

@@ -0,0 +1,146 @@
{
"attributes": [
{
"allow_nil?": false,
"default": "fragment(\"gen_random_uuid()\")",
"generated?": false,
"primary_key?": true,
"references": null,
"size": null,
"source": "id",
"type": "uuid"
},
{
"allow_nil?": true,
"default": "false",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "tracked",
"type": "boolean"
},
{
"allow_nil?": true,
"default": "false",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "followed",
"type": "boolean"
},
{
"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_character_settings_v1_map_id_fkey",
"on_delete": null,
"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_character_settings_v1_character_id_fkey",
"on_delete": null,
"on_update": null,
"primary_key?": true,
"schema": "public",
"table": "character_v1"
},
"size": null,
"source": "character_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [],
"has_create_action": true,
"hash": "03E6D5F913A8DB4EC1506A773B222542769B945776482E5BAE57D39CF1B79034",
"identities": [
{
"all_tenants?": false,
"base_filter": null,
"index_name": "map_character_settings_v1_uniq_map_character_index",
"keys": [
{
"type": "atom",
"value": "map_id"
},
{
"type": "atom",
"value": "character_id"
}
],
"name": "uniq_map_character",
"nils_distinct?": true,
"where": null
}
],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.WandererApp.Repo",
"schema": null,
"table": "map_character_settings_v1"
}

View File

@@ -0,0 +1,237 @@
{
"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": "solar_system_id",
"type": "bigint"
},
{
"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": "custom_name",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "description",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "tag",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "temporary_name",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "labels",
"type": "text"
},
{
"allow_nil?": true,
"default": "0",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "status",
"type": "bigint"
},
{
"allow_nil?": true,
"default": "true",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "visible",
"type": "boolean"
},
{
"allow_nil?": true,
"default": "false",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "locked",
"type": "boolean"
},
{
"allow_nil?": true,
"default": "0",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "position_x",
"type": "bigint"
},
{
"allow_nil?": true,
"default": "0",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "position_y",
"type": "bigint"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "added_at",
"type": "utc_datetime"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "linked_sig_eve_id",
"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": "map_system_v1_map_id_fkey",
"on_delete": null,
"on_update": null,
"primary_key?": true,
"schema": "public",
"table": "maps_v1"
},
"size": null,
"source": "map_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [],
"has_create_action": true,
"hash": "177B40EB60054D454E7E3D2321214CD14DD2E75B89A691D3EDEA3523F4799E85",
"identities": [
{
"all_tenants?": false,
"base_filter": null,
"index_name": "map_system_v1_map_solar_system_id_index",
"keys": [
{
"type": "atom",
"value": "map_id"
},
{
"type": "atom",
"value": "solar_system_id"
}
],
"name": "map_solar_system_id",
"nils_distinct?": true,
"where": null
}
],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.WandererApp.Repo",
"schema": null,
"table": "map_system_v1"
}

View File

@@ -0,0 +1,196 @@
{
"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?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "slug",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "description",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "personal_note",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "public_api_key",
"type": "text"
},
{
"allow_nil?": true,
"default": "[]",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "hubs",
"type": [
"array",
"text"
]
},
{
"allow_nil?": false,
"default": "\"wormholes\"",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "scope",
"type": "text"
},
{
"allow_nil?": true,
"default": "false",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "deleted",
"type": "boolean"
},
{
"allow_nil?": true,
"default": "false",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "only_tracked_characters",
"type": "boolean"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "options",
"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": "maps_v1_owner_id_fkey",
"on_delete": null,
"on_update": null,
"primary_key?": true,
"schema": "public",
"table": "character_v1"
},
"size": null,
"source": "owner_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [],
"has_create_action": true,
"hash": "5266AED79B87A21A891B42E5315E5FC2AA9406184D66A41A1069514F2CB9B16C",
"identities": [
{
"all_tenants?": false,
"base_filter": null,
"index_name": "maps_v1_unique_slug_index",
"keys": [
{
"type": "atom",
"value": "slug"
}
],
"name": "unique_slug",
"nils_distinct?": true,
"where": null
}
],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.WandererApp.Repo",
"schema": null,
"table": "maps_v1"
}