Compare commits

...

35 Commits

Author SHA1 Message Date
CI
78dbea6267 chore: release version v1.76.1 2025-08-13 16:15:29 +00:00
Dmitry Popov
6a9e53141d Merge pull request #498 from wanderer-industries/reselect-systems-after-init
fix(Map): Fix problem when systems was deselected after change tab
2025-08-13 20:15:05 +04:00
DanSylvest
05e6994520 fix(Map): Fix problem when systems was deselected after change tab 2025-08-13 18:58:24 +03:00
CI
1a4dc67eb9 chore: [skip ci] 2025-08-12 11:39:44 +00:00
CI
31d87a116b chore: release version v1.76.0 2025-08-12 11:39:44 +00:00
Dmitry Popov
c47796d590 Merge pull request #497 from wanderer-industries/sig-temp-names
Sig temp names
2025-08-12 15:39:07 +04:00
Dmitry Popov
c7138a41ee feat(Signatures): Sync signature temporary name with system on link signature to system 2025-08-12 13:20:03 +02:00
Dmitry Popov
96f04c70a9 Merge branch 'main' into sig-temp-names 2025-08-11 19:20:46 +02:00
Dmitry Popov
87a8bc09ab chore: [skip ci] 2025-08-11 19:20:37 +02:00
Dmitry Popov
5f5661d559 chore: [skip ci] 2025-08-11 19:20:13 +02:00
CI
35ca87790e chore: [skip ci] 2025-08-11 15:57:51 +00:00
CI
ae43e4a57c chore: release version v1.75.23 2025-08-11 15:57:51 +00:00
Dmitry Popov
b91712a01a chore: updated deps 2025-08-11 17:54:23 +02:00
CI
b20007b341 chore: [skip ci] 2025-08-11 14:47:44 +00:00
CI
6a24e1188b chore: release version v1.75.22 2025-08-11 14:47:44 +00:00
Dmitry Popov
5894efc1aa chore: release version v1.75.21 2025-08-11 16:47:11 +02:00
CI
a05612d243 chore: [skip ci] 2025-08-11 12:02:06 +00:00
CI
48de874d6b chore: release version v1.75.21 2025-08-11 12:02:06 +00:00
Dmitry Popov
91e6da316f Merge branch 'main' of github.com:wanderer-industries/wanderer 2025-08-11 14:01:41 +02:00
Dmitry Popov
fa60bd81a1 chore: release version v1.75.19 2025-08-11 14:01:33 +02:00
CI
a08a69c5be chore: [skip ci] 2025-08-11 11:55:22 +00:00
CI
18d450a41a chore: release version v1.75.20 2025-08-11 11:55:22 +00:00
Dmitry Popov
36cdee61c0 chore: release version v1.75.19 2025-08-11 13:54:51 +02:00
Dmitry Popov
797e188259 fix: Fixed docs 2025-08-11 13:49:22 +02:00
Dmitry Popov
91b581668a Merge branch 'main' of github.com:wanderer-industries/wanderer 2025-08-11 13:44:17 +02:00
Dmitry Popov
ad01fec28f Merge branch 'main' of github.com:wanderer-industries/wanderer 2025-08-11 13:44:13 +02:00
CI
357d3a0df6 chore: release version v1.75.19 2025-08-11 11:25:52 +00:00
CI
5ce6022761 chore: release version v1.75.18 2025-08-11 11:25:17 +00:00
CI
235a0c5aea chore: release version v1.75.17 2025-08-11 11:24:44 +00:00
CI
9b81fa6ebb chore: release version v1.75.16 2025-08-11 11:24:16 +00:00
Dmitry Popov
8792d5ab0e Merge branch 'main' of github.com:wanderer-industries/wanderer 2025-08-11 13:23:40 +02:00
Dmitry Popov
d46ed0c078 Merge branch 'main' of github.com:wanderer-industries/wanderer 2025-08-11 13:23:36 +02:00
Dmitry Popov
74f7ad155d Merge branch 'develop' into sig-temp-names 2025-07-18 13:52:07 +02:00
DanSylvest
f58ebad0ec fix(Map): Add Temp name field 2025-07-08 18:43:49 +03:00
Dmitry Popov
7ca4eb3b8f feat(Signatures): add support for signature temp names 2025-07-08 14:03:22 +02:00
45 changed files with 4653 additions and 3233 deletions

View File

@@ -96,6 +96,7 @@ jobs:
git config --global user.name 'CI'
git config --global user.email 'ci@users.noreply.github.com'
mix git_ops.release --force-patch --yes
git commit --allow-empty -m 'chore: [skip ci]'
git push --follow-tags
echo "commit_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT

View File

@@ -43,6 +43,11 @@ jobs:
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: ⬇️ Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get Release Tag
id: get-latest-tag
uses: "WyriHaximus/github-action-get-previous-tag@v1"
@@ -118,9 +123,7 @@ jobs:
id: get-content
with:
stringToTruncate: |
📣 Wanderer **ARM** release available 🎉
[wandererltd/community-edition-arm:${{ steps.get-latest-tag.outputs.tag }}](https://hub.docker.com/r/wandererltd/community-edition-arm/tags)
📣 Wanderer **ARM** (https://hub.docker.com/repository/docker/wandererltd/community-edition-arm/general) release available 🎉
**Version**: ${{ steps.get-latest-tag.outputs.tag }}
@@ -181,4 +184,4 @@ jobs:
uses: tsickert/discord-webhook@v5.3.0
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
content: ${{ needs.docker.outputs.release-notes }}
content: Release notes ${{ needs.docker.outputs.release-notes }}

View File

@@ -43,6 +43,11 @@ jobs:
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: ⬇️ Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Get Release Tag
id: get-latest-tag
uses: "WyriHaximus/github-action-get-previous-tag@v1"
@@ -120,8 +125,6 @@ jobs:
stringToTruncate: |
📣 Wanderer new release available 🎉
[wandererltd/community-edition:${{ steps.get-latest-tag.outputs.tag }}](https://hub.docker.com/r/wandererltd/community-edition/tags)
**Version**: ${{ steps.get-latest-tag.outputs.tag }}
${{ steps.extract-changelog.outputs.body }}
@@ -181,4 +184,4 @@ jobs:
uses: tsickert/discord-webhook@v5.3.0
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
content: ${{ needs.docker.outputs.release-notes }}
content: Release notes ${{ needs.docker.outputs.release-notes }}

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,13 @@
// import './tailwind.css';
//@import 'primereact/resources/themes/bootstrap4-dark-blue/theme.css';
//@import 'primereact/resources/themes/lara-dark-purple/theme.css';
//@import "prime-fixes";
@import 'primereact/resources/primereact.min.css';
//@import 'primeflex/primeflex.css';
@import 'primeicons/primeicons.css';
//@import 'primereact/resources/primereact.css';
@use 'primereact/resources/primereact.min.css';
@use 'primeicons/primeicons.css';
@import "fixes";
@import "prime-fixes";
@import "custom-scrollbar";
@import "tooltip";
@import "context-menu";
@use "fixes";
@use "prime-fixes";
@use "custom-scrollbar";
@use "tooltip";
@use "context-menu";
.fixedImportant {

View File

@@ -1,6 +1,3 @@
@import "fix-dialog";
@import "fix-popup";
@import "fix-tabs";
//@import "fix-input";
//@import "theme";
@use "fix-dialog";
@use "fix-popup";
@use "fix-tabs";

View File

@@ -1,4 +1,4 @@
@import '@/hooks/Mapper/components/map/styles/eve-common-variables';
@use '@/hooks/Mapper/components/map/styles/eve-common-variables';
.ConnectionTimeEOL {
background-image: linear-gradient(207deg, transparent, var(--conn-time-eol));

View File

@@ -1,4 +1,4 @@
@import '@/hooks/Mapper/components/map/styles/eve-common-variables';
@use '@/hooks/Mapper/components/map/styles/eve-common-variables';
.EdgePathBack {
fill: none;

View File

@@ -1,4 +1,5 @@
@import '@/hooks/Mapper/components/map/styles/eve-common-variables';
@use "sass:color";
@use '@/hooks/Mapper/components/map/styles/eve-common-variables';
$pastel-blue: #5a7d9a;
$pastel-pink: rgb(30, 161, 255);
@@ -34,7 +35,7 @@ $neon-color-3: rgba(27, 132, 236, 0.40);
color: var(--rf-text-color, #ffffff);
box-shadow: 0 0 5px rgba($dark-bg, 0.5);
border: 1px solid darken($pastel-blue, 10%);
border: 1px solid color.adjust($pastel-blue, $lightness: -10%);
border-radius: 5px;
position: relative;
z-index: 3;

View File

@@ -1,4 +1,4 @@
@import './SolarSystemNodeDefault.module.scss';
@use './SolarSystemNodeDefault.module.scss';
/* ---------------------------------------------
Only override what's different from the base

View File

@@ -1,4 +1,4 @@
@import '@/hooks/Mapper/components/map/styles/eve-common-variables';
@use '@/hooks/Mapper/components/map/styles/eve-common-variables';
.Signature {
position: relative;

View File

@@ -6,5 +6,5 @@ export * from './useCommandsCharacters';
export * from './useCommandsConnections';
export * from './useCommandsConnections';
export * from './useCenterSystem';
export * from './useSelectSystem';
export * from './useSelectSystems';
export * from './useMapCommands';

View File

@@ -1,21 +0,0 @@
import { useReactFlow } from 'reactflow';
import { useCallback, useRef } from 'react';
import { CommandSelectSystem } from '@/hooks/Mapper/types';
export const useSelectSystem = () => {
const rf = useReactFlow();
const ref = useRef({ rf });
ref.current = { rf };
return useCallback((systemId: CommandSelectSystem) => {
ref.current.rf.setNodes(nds =>
nds.map(node => {
return {
...node,
selected: node.id === systemId,
};
}),
);
}, []);
};

View File

@@ -0,0 +1,31 @@
import { useReactFlow } from 'reactflow';
import { useCallback, useRef } from 'react';
import { CommandSelectSystems } from '@/hooks/Mapper/types';
import { OnMapSelectionChange } from '@/hooks/Mapper/components/map/map.types.ts';
export const useSelectSystems = (onSelectionChange: OnMapSelectionChange) => {
const rf = useReactFlow();
const ref = useRef({ rf, onSelectionChange });
ref.current = { rf, onSelectionChange };
return useCallback(({ systems, delay }: CommandSelectSystems) => {
const run = () => {
ref.current.rf.setNodes(nds =>
nds.map(node => {
return {
...node,
selected: systems.includes(node.id),
};
}),
);
};
if (delay == null || delay === 0) {
run();
return;
}
setTimeout(run, delay);
}, []);
};

View File

@@ -14,6 +14,7 @@ import {
CommandRemoveSystems,
Commands,
CommandSelectSystem,
CommandSelectSystems,
CommandUpdateConnection,
CommandUpdateSystems,
MapHandlers,
@@ -28,7 +29,7 @@ import {
useMapRemoveSystems,
useMapUpdateSystems,
useCenterSystem,
useSelectSystem,
useSelectSystems,
} from './api';
import { OnMapSelectionChange } from '@/hooks/Mapper/components/map/map.types.ts';
@@ -38,7 +39,7 @@ export const useMapHandlers = (ref: ForwardedRef<MapHandlers>, onSelectionChange
const mapUpdateSystems = useMapUpdateSystems();
const removeSystems = useMapRemoveSystems(onSelectionChange);
const centerSystem = useCenterSystem();
const selectSystem = useSelectSystem();
const selectSystems = useSelectSystems(onSelectionChange);
const selectRef = useRef({ onSelectionChange });
selectRef.current = { onSelectionChange };
@@ -105,14 +106,11 @@ export const useMapHandlers = (ref: ForwardedRef<MapHandlers>, onSelectionChange
break;
case Commands.selectSystem:
setTimeout(() => {
const systemId = `${data}`;
selectRef.current.onSelectionChange({
systems: [systemId],
connections: [],
});
selectSystem(systemId as CommandSelectSystem);
}, 500);
selectSystems({ systems: [data as string], delay: 500 });
break;
case Commands.selectSystems:
selectSystems(data as CommandSelectSystems);
break;
case Commands.pingAdded:

View File

@@ -1,5 +1,5 @@
@import './eve-common-variables';
@import './eve-common';
@use './eve-common-variables';
@use './eve-common';
.default-theme {
--rf-bg-color: #0C0A09;

View File

@@ -1,18 +1,19 @@
@use "sass:color";
$friendlyBase: #3bbd39;
$friendlyAlpha: #3bbd3952;
$friendlyDark20: darken($friendlyBase, 20%);
$friendlyDark30: darken($friendlyBase, 30%);
$friendlyDark5: darken($friendlyBase, 5%);
$friendlyDark20: color.adjust($friendlyBase, $lightness: -20%);
$friendlyDark30: color.adjust($friendlyBase, $lightness: -30%);
$friendlyDark5: color.adjust($friendlyBase, $lightness: -5%);
$lookingForBase: #43c2fd;
$lookingForAlpha: rgba(67, 176, 253, 0.48);
$lookingForDark15: darken($lookingForBase, 15%);
$lookingForDark15: color.adjust($lookingForBase, $lightness: -15%);
$homeBase: rgb(179, 253, 67);
$homeAlpha: rgba(186, 248, 48, 0.32);
$homeBackground: #a0fa5636;
$homeDark30: darken($homeBase, 30%);
$homeDark30: color.adjust($homeBase, $lightness: -30%);
:root {
--pastel-blue: #5a7d9a;

View File

@@ -1,4 +1,4 @@
@import './eve-common-variables';
@use './eve-common-variables';
.eve-wh-effect-color-pulsar {

View File

@@ -1,2 +1,2 @@
@import './default-theme.scss';
@import './pathfinder-theme.scss';
@use './default-theme.scss';
@use './pathfinder-theme.scss';

View File

@@ -1,10 +1,11 @@
@import './eve-common-variables';
@import './eve-common';
@use "sass:color";
@use './eve-common-variables';
@use './eve-common';
@import url('https://fonts.googleapis.com/css2?family=Oxygen:wght@300;400;700&display=swap');
$homeBase: rgb(197, 253, 67);
$homeAlpha: rgba(197, 253, 67, 0.32);
$homeDark30: darken($homeBase, 30%);
$homeDark30: color.adjust($homeBase, $lightness: -30%);
.pathfinder-theme {
/* -- Override values from the default theme -- */

View File

@@ -28,12 +28,12 @@ import {
renderInfoColumn,
renderUpdatedTimeLeft,
} from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/renders';
import { SETTINGS_KEYS, SIGNATURE_WINDOW_ID, SignatureSettingsType } from '@/hooks/Mapper/constants/signatures.ts';
import { useClipboard, useHotkey } from '@/hooks/Mapper/hooks';
import useMaxWidth from '@/hooks/Mapper/hooks/useMaxWidth';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { getSignatureRowClass } from '../helpers/rowStyles';
import { useSystemSignaturesData } from '../hooks/useSystemSignaturesData';
import { SETTINGS_KEYS, SIGNATURE_WINDOW_ID, SignatureSettingsType } from '@/hooks/Mapper/constants/signatures.ts';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
const renderColIcon = (sig: SystemSignature) => renderIcon(sig);
@@ -157,9 +157,18 @@ export const SystemSignaturesContent = ({
[onSelect, selectable, setSelectedSignatures, deletedSignatures],
);
const { showDescriptionColumn, showUpdatedColumn, showCharacterColumn, showCharacterPortrait } = useMemo(
const {
showGroupColumn,
showDescriptionColumn,
showAddedColumn,
showUpdatedColumn,
showCharacterColumn,
showCharacterPortrait,
} = useMemo(
() => ({
showGroupColumn: settings[SETTINGS_KEYS.SHOW_GROUP_COLUMN] as boolean,
showDescriptionColumn: settings[SETTINGS_KEYS.SHOW_DESCRIPTION_COLUMN] as boolean,
showAddedColumn: settings[SETTINGS_KEYS.SHOW_ADDED_COLUMN] as boolean,
showUpdatedColumn: settings[SETTINGS_KEYS.SHOW_UPDATED_COLUMN] as boolean,
showCharacterColumn: settings[SETTINGS_KEYS.SHOW_CHARACTER_COLUMN] as boolean,
showCharacterPortrait: settings[SETTINGS_KEYS.SHOW_CHARACTER_PORTRAIT] as boolean,
@@ -309,15 +318,17 @@ export const SystemSignaturesContent = ({
style={{ maxWidth: 72, minWidth: 72, width: 72 }}
sortable
/>
<Column
field="group"
header="Group"
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
style={{ maxWidth: 110, minWidth: 110, width: 110 }}
body={sig => sig.group ?? ''}
hidden={isCompact}
sortable
/>
{showGroupColumn && (
<Column
field="group"
header="Group"
bodyClassName="text-ellipsis overflow-hidden whitespace-nowrap"
style={{ maxWidth: 110, minWidth: 110, width: 110 }}
body={sig => sig.group ?? ''}
hidden={isCompact}
sortable
/>
)}
<Column
field="info"
header="Info"
@@ -336,15 +347,17 @@ export const SystemSignaturesContent = ({
sortable
/>
)}
<Column
field="inserted_at"
header="Added"
dataType="date"
body={renderAddedTimeLeft}
style={{ minWidth: 70, maxWidth: 80 }}
bodyClassName="ssc-header text-ellipsis overflow-hidden whitespace-nowrap"
sortable
/>
{showAddedColumn && (
<Column
field="inserted_at"
header="Added"
dataType="date"
body={renderAddedTimeLeft}
style={{ minWidth: 70, maxWidth: 80 }}
bodyClassName="ssc-header text-ellipsis overflow-hidden whitespace-nowrap"
sortable
/>
)}
{showUpdatedColumn && (
<Column
field="updated_at"

View File

@@ -1,3 +1,4 @@
import { SETTINGS_KEYS, SIGNATURES_DELETION_TIMING, SignatureSettingsType } from '@/hooks/Mapper/constants/signatures';
import {
GroupType,
SignatureGroup,
@@ -11,7 +12,6 @@ import {
SignatureKindFR,
SignatureKindRU,
} from '@/hooks/Mapper/types';
import { SETTINGS_KEYS, SIGNATURES_DELETION_TIMING, SignatureSettingsType } from '@/hooks/Mapper/constants/signatures';
export const TIME_ONE_MINUTE = 1000 * 60;
export const TIME_TEN_MINUTES = TIME_ONE_MINUTE * 10;
@@ -130,6 +130,8 @@ export const SIGNATURE_SETTINGS = {
{ type: SettingsTypes.flag, key: SETTINGS_KEYS.COMBAT_SITE, name: 'Show Combat Sites' },
],
uiFlags: [
{ type: SettingsTypes.flag, key: SETTINGS_KEYS.SHOW_GROUP_COLUMN, name: 'Show Group Column' },
{ type: SettingsTypes.flag, key: SETTINGS_KEYS.SHOW_ADDED_COLUMN, name: 'Show Added Column' },
{ type: SettingsTypes.flag, key: SETTINGS_KEYS.SHOW_UPDATED_COLUMN, name: 'Show Updated Column' },
{ type: SettingsTypes.flag, key: SETTINGS_KEYS.SHOW_DESCRIPTION_COLUMN, name: 'Show Description Column' },
{ type: SettingsTypes.flag, key: SETTINGS_KEYS.SHOW_CHARACTER_COLUMN, name: 'Show Character Column' },

View File

@@ -1,8 +1,6 @@
import { Dialog } from 'primereact/dialog';
import { Button } from 'primereact/button';
import { ConfirmPopup } from 'primereact/confirmpopup';
import { useCallback, useRef } from 'react';
import { MapUserSettings } from '@/hooks/Mapper/mapRootProvider/types.ts';
import { DEFAULT_SIGNATURE_SETTINGS } from '@/hooks/Mapper/constants/signatures.ts';
import { useConfirmPopup } from '@/hooks/Mapper/hooks';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import {
DEFAULT_KILLS_WIDGET_SETTINGS,
DEFAULT_ON_THE_MAP_SETTINGS,
@@ -11,11 +9,13 @@ import {
getDefaultWidgetProps,
STORED_INTERFACE_DEFAULT_VALUES,
} from '@/hooks/Mapper/mapRootProvider/constants.ts';
import { DEFAULT_SIGNATURE_SETTINGS } from '@/hooks/Mapper/constants/signatures.ts';
import { Toast } from 'primereact/toast';
import { useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { MapUserSettings } from '@/hooks/Mapper/mapRootProvider/types.ts';
import { saveTextFile } from '@/hooks/Mapper/utils';
import { useConfirmPopup } from '@/hooks/Mapper/hooks';
import { Button } from 'primereact/button';
import { ConfirmPopup } from 'primereact/confirmpopup';
import { Dialog } from 'primereact/dialog';
import { Toast } from 'primereact/toast';
import { useCallback, useRef } from 'react';
const createSettings = function <T>(lsSettings: string | null, defaultValues: T) {
return {
@@ -41,7 +41,7 @@ export const OldSettingsDialog = () => {
const widgetKills = localStorage.getItem('kills:widget:settings');
const onTheMapOld = localStorage.getItem('window:onTheMap:settings');
const widgetsOld = localStorage.getItem('windows:settings:v2');
const signatures = localStorage.getItem('wanderer_system_signature_settings_v6_5');
const signatures = localStorage.getItem('wanderer_system_signature_settings_v6_6');
const out: MapUserSettings = {
killsWidget: createSettings(widgetKills, DEFAULT_KILLS_WIDGET_SETTINGS),
@@ -118,7 +118,7 @@ export const OldSettingsDialog = () => {
localStorage.removeItem('kills:widget:settings');
localStorage.removeItem('window:onTheMap:settings');
localStorage.removeItem('windows:settings:v2');
localStorage.removeItem('wanderer_system_signature_settings_v6_5');
localStorage.removeItem('wanderer_system_signature_settings_v6_6');
checkOldSettings();
}, [checkOldSettings]);

View File

@@ -94,6 +94,10 @@ export const SignatureSettings = ({ systemId, show, onHide, signatureData }: Map
out = { ...out, type: values.type };
}
if (values.temporary_name != null) {
out = { ...out, temporary_name: values.temporary_name };
}
if (signatureData.group !== SignatureGroup.Wormhole) {
out = { ...out, name: '' };
}

View File

@@ -4,6 +4,7 @@ import { SignatureWormholeTypeSelect } from '@/hooks/Mapper/components/mapRootCo
import { SignatureK162TypeSelect } from '@/hooks/Mapper/components/mapRootContent/components/SignatureSettings/components/SignatureK162TypeSelect';
import { SignatureLeadsToSelect } from '@/hooks/Mapper/components/mapRootContent/components/SignatureSettings/components/SignatureLeadsToSelect';
import { SignatureEOLCheckbox } from '@/hooks/Mapper/components/mapRootContent/components/SignatureSettings/components/SignatureEOLCheckbox';
import { SignatureTempName } from '@/hooks/Mapper/components/mapRootContent/components/SignatureSettings/components/SignatureTempName.tsx';
export const SignatureGroupContentWormholes = () => {
const { watch } = useFormContext<SystemSignature>();
@@ -32,6 +33,11 @@ export const SignatureGroupContentWormholes = () => {
<span>EOL:</span>
<SignatureEOLCheckbox name="isEOL" />
</label>
<label className="grid grid-cols-[100px_250px_1fr] gap-2 items-center text-[14px]">
<span>Temp. Name:</span>
<SignatureTempName />
</label>
</>
);
};

View File

@@ -0,0 +1,15 @@
import { Controller, useFormContext } from 'react-hook-form';
import { InputText } from 'primereact/inputtext';
import { SystemSignature } from '@/hooks/Mapper/types';
export const SignatureTempName = () => {
const { control } = useFormContext<SystemSignature>();
return (
<Controller
name="temporary_name"
control={control}
render={({ field }) => <InputText placeholder="Temporary Name" value={field.value} onChange={field.onChange} />}
/>
);
};

View File

@@ -1,6 +1,6 @@
import { Map, MAP_ROOT_ID } from '@/hooks/Mapper/components/map/Map.tsx';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { OutCommand, OutCommandHandler, SolarSystemConnection } from '@/hooks/Mapper/types';
import { CommandSelectSystems, OutCommand, OutCommandHandler, SolarSystemConnection } from '@/hooks/Mapper/types';
import { MapRootData, useMapRootState } from '@/hooks/Mapper/mapRootProvider';
import { OnMapAddSystemCallback, OnMapSelectionChange } from '@/hooks/Mapper/components/map/map.types.ts';
import isEqual from 'lodash.isequal';
@@ -88,6 +88,18 @@ export const MapWrapper = () => {
useMapEventListener(event => {
runCommand(event);
if (event.name === Commands.init) {
const { selectedSystems } = ref.current;
if (selectedSystems.length === 0) {
return;
}
runCommand({
name: Commands.selectSystems,
data: { systems: selectedSystems } as CommandSelectSystems,
});
}
});
const onSelectionChange: OnMapSelectionChange = useCallback(

View File

@@ -12,14 +12,16 @@ export enum SETTINGS_KEYS {
SORT_FIELD = 'sortField',
SORT_ORDER = 'sortOrder',
SHOW_DESCRIPTION_COLUMN = 'show_description_column',
SHOW_UPDATED_COLUMN = 'show_updated_column',
SHOW_ADDED_COLUMN = 'show_added_column',
SHOW_CHARACTER_COLUMN = 'show_character_column',
SHOW_CHARACTER_PORTRAIT = 'show_character_portrait',
SHOW_DESCRIPTION_COLUMN = 'show_description_column',
SHOW_GROUP_COLUMN = 'show_group_column',
SHOW_UPDATED_COLUMN = 'show_updated_column',
LAZY_DELETE_SIGNATURES = 'lazy_delete_signatures',
KEEP_LAZY_DELETE = 'keep_lazy_delete_enabled',
DELETION_TIMING = 'deletion_timing',
COLOR_BY_TYPE = 'color_by_type',
SHOW_CHARACTER_PORTRAIT = 'show_character_portrait',
// From SignatureKind
COSMIC_ANOMALY = SignatureKind.CosmicAnomaly,
@@ -45,6 +47,8 @@ export const DEFAULT_SIGNATURE_SETTINGS: SignatureSettingsType = {
[SETTINGS_KEYS.SORT_FIELD]: 'inserted_at',
[SETTINGS_KEYS.SORT_ORDER]: -1,
[SETTINGS_KEYS.SHOW_GROUP_COLUMN]: true,
[SETTINGS_KEYS.SHOW_ADDED_COLUMN]: true,
[SETTINGS_KEYS.SHOW_UPDATED_COLUMN]: true,
[SETTINGS_KEYS.SHOW_DESCRIPTION_COLUMN]: true,
[SETTINGS_KEYS.SHOW_CHARACTER_COLUMN]: true,

View File

@@ -27,6 +27,7 @@ export enum Commands {
userRoutes = 'user_routes',
centerSystem = 'center_system',
selectSystem = 'select_system',
selectSystems = 'select_systems',
linkSignatureToSystem = 'link_signature_to_system',
signaturesUpdated = 'signatures_updated',
systemCommentAdded = 'system_comment_added',
@@ -60,6 +61,7 @@ export type Command =
| Commands.routes
| Commands.userRoutes
| Commands.selectSystem
| Commands.selectSystems
| Commands.centerSystem
| Commands.linkSignatureToSystem
| Commands.signaturesUpdated
@@ -118,6 +120,10 @@ export type CommandUserRoutes = RoutesList;
export type CommandKillsUpdated = Kill[];
export type CommandDetailedKillsUpdated = Record<string, DetailedKill[]>;
export type CommandSelectSystem = string | undefined;
export type CommandSelectSystems = {
systems: string[];
delay?: number;
};
export type CommandCenterSystem = string | undefined;
export type CommandLinkSignatureToSystem = {
solar_system_source: number;
@@ -187,6 +193,7 @@ export interface CommandData {
[Commands.killsUpdated]: CommandKillsUpdated;
[Commands.detailedKillsUpdated]: CommandDetailedKillsUpdated;
[Commands.selectSystem]: CommandSelectSystem;
[Commands.selectSystems]: CommandSelectSystems;
[Commands.centerSystem]: CommandCenterSystem;
[Commands.linkSignatureToSystem]: CommandLinkSignatureToSystem;
[Commands.signaturesUpdated]: CommandLinkSignaturesUpdated;

View File

@@ -48,6 +48,7 @@ export type SystemSignature = {
inserted_at?: string;
updated_at?: string;
deleted?: boolean;
temporary_name?: string;
};
export interface ExtendedSystemSignature extends SystemSignature {

View File

@@ -79,7 +79,7 @@
"sass-loader": "^14.2.1",
"ts-jest": "^29.1.2",
"typescript": "^5.2.2",
"vite": "^5.0.5",
"vite": "^6.3.5",
"vite-plugin-cdn-import": "^1.0.1"
},
"peerDependencies": {

File diff suppressed because it is too large Load Diff

82
clean_changelog.py Normal file
View File

@@ -0,0 +1,82 @@
#!/usr/bin/env python3
"""
Script to clean up CHANGELOG.md by removing empty version entries.
An empty version entry has only a version header followed by empty lines,
without any actual content (### Bug Fixes: or ### Features: sections).
"""
import re
def clean_changelog():
with open('./CHANGELOG.md', 'r') as f:
content = f.read()
# Split content into sections based on version headers
version_pattern = r'^## \[v\d+\.\d+\.\d+\].*?\([^)]+\)$'
# Find all version headers with their positions
matches = list(re.finditer(version_pattern, content, re.MULTILINE))
# Build new content by keeping only non-empty versions
new_content = ""
# Keep the header (everything before first version)
if matches:
new_content += content[:matches[0].start()]
else:
# No versions found, keep original
return content
for i, match in enumerate(matches):
version_start = match.start()
# Find the end of this version section (start of next version or end of file)
if i + 1 < len(matches):
version_end = matches[i + 1].start()
else:
version_end = len(content)
version_section = content[version_start:version_end]
# Check if this version has actual content
# Look for ### Bug Fixes: or ### Features: followed by actual content
has_content = False
# Split the section into lines
lines = version_section.split('\n')
# Look for content sections
in_content_section = False
for line in lines:
line_stripped = line.strip()
# Check if we're entering a content section
if line_stripped.startswith('### Bug Fixes:') or line_stripped.startswith('### Features:'):
in_content_section = True
continue
# If we're in a content section and find non-empty content
if in_content_section:
if line_stripped and not line_stripped.startswith('###') and not line_stripped.startswith('##'):
# This is actual content (not just another header)
if line_stripped.startswith('*') or len(line_stripped) > 0:
has_content = True
break
elif line_stripped.startswith('##'):
# We've reached the next version, stop looking
break
# Only keep versions with actual content
if has_content:
new_content += version_section
return new_content
if __name__ == "__main__":
cleaned_content = clean_changelog()
# Write the cleaned content back to the file
with open('./CHANGELOG.md', 'w') as f:
f.write(cleaned_content)
print("CHANGELOG.md has been cleaned up successfully!")

View File

@@ -30,6 +30,7 @@ defmodule WandererApp.Api.MapSystemSignature do
code_interface do
define(:all_active, action: :all_active)
define(:create, action: :create)
define(:destroy, action: :destroy)
define(:update, action: :update)
define(:update_linked_system, action: :update_linked_system)
define(:update_type, action: :update_type)
@@ -62,6 +63,7 @@ defmodule WandererApp.Api.MapSystemSignature do
:eve_id,
:character_eve_id,
:name,
:temporary_name,
:description,
:kind,
:group,
@@ -101,6 +103,7 @@ defmodule WandererApp.Api.MapSystemSignature do
:eve_id,
:character_eve_id,
:name,
:temporary_name,
:description,
:kind,
:group,
@@ -120,6 +123,7 @@ defmodule WandererApp.Api.MapSystemSignature do
:eve_id,
:character_eve_id,
:name,
:temporary_name,
:description,
:kind,
:group,
@@ -195,6 +199,10 @@ defmodule WandererApp.Api.MapSystemSignature do
allow_nil? true
end
attribute :temporary_name, :string do
allow_nil? true
end
attribute :type, :string do
allow_nil? true
end
@@ -241,6 +249,7 @@ defmodule WandererApp.Api.MapSystemSignature do
:eve_id,
:character_eve_id,
:name,
:temporary_name,
:description,
:type,
:linked_system_id,

View File

@@ -97,7 +97,7 @@ defmodule WandererApp.ExternalEvents.Event do
:locked,
# ADD
:temporary_name,
# ADD
# ADD
:labels,
# ADD
:description,

View File

@@ -9,8 +9,6 @@ defmodule WandererApp.Map.Audit do
require Ash.Query
require Logger
alias WandererApp.SecurityAudit
@week_seconds :timer.hours(24 * 7)
@month_seconds @week_seconds * 4
@audit_expired_seconds @month_seconds * 3
@@ -38,17 +36,14 @@ defmodule WandererApp.Map.Audit do
:ok
end
def get_activity_query(map_id, period, activity) do
SecurityAudit.get_map_activity_query(map_id, period, activity)
end
defdelegate get_map_activity_query(map_id, period, activity),
to: WandererApp.SecurityAudit
def track_acl_event(event_type, metadata) do
SecurityAudit.track_acl_event(event_type, metadata)
end
defdelegate track_acl_event(event_type, metadata),
to: WandererApp.SecurityAudit
def track_map_event(event_type, metadata) do
SecurityAudit.track_map_event(event_type, metadata)
end
defdelegate track_map_event(event_type, metadata),
to: WandererApp.SecurityAudit
defp get_expired_at(), do: DateTime.utc_now() |> DateTime.add(-@audit_expired_seconds, :second)
end

View File

@@ -114,6 +114,7 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
deleted_sig,
Map.take(sig, [
:name,
:temporary_name,
:description,
:kind,
:group,
@@ -239,6 +240,7 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
system_id: system_id,
eve_id: sig["eve_id"],
name: sig["name"],
temporary_name: sig["temporary_name"],
description: Map.get(sig, "description"),
kind: sig["kind"],
group: sig["group"],

View File

@@ -113,7 +113,7 @@ defmodule WandererAppWeb.MapAuditAPIController do
def index(conn, params) do
with {:ok, map_id} <- APIUtils.fetch_map_id(params),
{:ok, period} <- APIUtils.require_param(params, "period"),
query <- WandererApp.Map.Audit.get_activity_query(map_id, period, "all"),
query <- WandererApp.Map.Audit.get_map_activity_query(map_id, period, "all"),
{:ok, data} <-
Ash.read(query) do
data = Enum.map(data, &map_audit_event_to_json/1)

View File

@@ -80,25 +80,73 @@ defmodule WandererAppWeb.MapConnectionsEventHandler do
current_user: %{id: current_user_id},
main_character_id: main_character_id,
has_tracked_characters?: true,
map_user_settings: map_user_settings,
user_permissions: %{delete_connection: true}
}
} =
socket
)
when not is_nil(main_character_id) do
solar_system_source_id = solar_system_source_id |> String.to_integer()
solar_system_target_id = solar_system_target_id |> String.to_integer()
map_id
|> WandererApp.Map.Server.delete_connection(%{
solar_system_source_id: solar_system_source_id |> String.to_integer(),
solar_system_target_id: solar_system_target_id |> String.to_integer()
solar_system_source_id: solar_system_source_id,
solar_system_target_id: solar_system_target_id
})
delete_connection_with_sigs =
map_user_settings
|> WandererApp.MapUserSettingsRepo.to_form_data!()
|> WandererApp.MapUserSettingsRepo.get_boolean_setting("delete_connection_with_sigs")
if delete_connection_with_sigs do
target_system =
WandererApp.Map.find_system_by_location(
map_id,
%{solar_system_id: solar_system_target_id}
)
if not is_nil(target_system.linked_sig_eve_id) do
{:ok, signatures} =
WandererApp.Api.MapSystemSignature.by_linked_system_id(solar_system_target_id)
signatures
|> Enum.each(fn s ->
if not is_nil(s.temporary_name) && s.temporary_name == target_system.temporary_name do
map_id
|> WandererApp.Map.Server.update_system_temporary_name(%{
solar_system_id: solar_system_target_id,
temporary_name: nil
})
end
map_id
|> WandererApp.Map.Server.update_system_linked_sig_eve_id(%{
solar_system_id: solar_system_target_id,
linked_sig_eve_id: nil
})
s
|> WandererApp.Api.MapSystemSignature.destroy!()
end)
WandererApp.Map.Server.Impl.broadcast!(
map_id,
:signatures_updated,
solar_system_source_id
)
end
end
{:ok, _} =
WandererApp.User.ActivityTracker.track_map_event(:map_connection_removed, %{
character_id: main_character_id,
user_id: current_user_id,
map_id: map_id,
solar_system_source_id: "#{solar_system_source_id}" |> String.to_integer(),
solar_system_target_id: "#{solar_system_target_id}" |> String.to_integer()
solar_system_source_id: solar_system_source_id,
solar_system_target_id: solar_system_target_id
})
{:noreply, socket}

View File

@@ -179,42 +179,50 @@ defmodule WandererAppWeb.MapSignaturesEventHandler do
} = socket
)
when not is_nil(main_character_id) do
solar_system_source = get_integer(solar_system_source)
solar_system_target = get_integer(solar_system_target)
with solar_system_source <- get_integer(solar_system_source),
solar_system_target <- get_integer(solar_system_target),
{:ok, source_system} <-
WandererApp.Api.MapSystem.read_by_map_and_solar_system(%{
map_id: map_id,
solar_system_id: solar_system_source
}),
signature <-
WandererApp.Api.MapSystemSignature.by_system_id!(source_system.id)
|> Enum.find(fn s -> s.eve_id == signature_eve_id end),
target_system <-
WandererApp.Map.find_system_by_location(
map_id,
%{solar_system_id: solar_system_target}
) do
if not is_nil(signature) do
signature
|> WandererApp.Api.MapSystemSignature.update_group!(%{group: "Wormhole"})
|> WandererApp.Api.MapSystemSignature.update_linked_system(%{
linked_system_id: solar_system_target
})
case WandererApp.Api.MapSystem.read_by_map_and_solar_system(%{
map_id: map_id,
solar_system_id: solar_system_source
}) do
{:ok, system} ->
WandererApp.Api.MapSystemSignature.by_system_id!(system.id)
|> Enum.filter(fn s -> s.eve_id == signature_eve_id end)
|> Enum.each(fn s ->
s
|> WandererApp.Api.MapSystemSignature.update_group!(%{group: "Wormhole"})
|> WandererApp.Api.MapSystemSignature.update_linked_system(%{
linked_system_id: solar_system_target
})
end)
map_system =
WandererApp.Map.find_system_by_location(
map_id,
%{solar_system_id: solar_system_target}
)
if not is_nil(map_system) && is_nil(map_system.linked_sig_eve_id) do
if not is_nil(target_system) &&
is_nil(target_system.linked_sig_eve_id) do
map_id
|> WandererApp.Map.Server.update_system_linked_sig_eve_id(%{
solar_system_id: solar_system_target,
linked_sig_eve_id: signature_eve_id
})
if not is_nil(signature.temporary_name) do
map_id
|> WandererApp.Map.Server.update_system_temporary_name(%{
solar_system_id: solar_system_target,
temporary_name: signature.temporary_name
})
end
end
end
WandererApp.Map.Server.Impl.broadcast!(map_id, :signatures_updated, solar_system_source)
{:noreply, socket}
WandererApp.Map.Server.Impl.broadcast!(map_id, :signatures_updated, solar_system_source)
{:noreply, socket}
else
_ ->
{:noreply, socket}
end
@@ -320,6 +328,7 @@ defmodule WandererAppWeb.MapSignaturesEventHandler do
:eve_id,
:character_eve_id,
:name,
:temporary_name,
:description,
:kind,
:group,

View File

@@ -153,7 +153,7 @@ defmodule WandererAppWeb.MapAuditLive do
} =
socket.assigns
query = WandererApp.Map.Audit.get_activity_query(map_id, period, activity)
query = WandererApp.Map.Audit.get_map_activity_query(map_id, period, activity)
AshPagify.validate_and_run(query, params, opts)
|> case do

View File

@@ -3,7 +3,7 @@ defmodule WandererApp.MixProject do
@source_url "https://github.com/wanderer-industries/wanderer"
@version "1.75.15"
@version "1.76.1"
def project do
[

View File

@@ -21,8 +21,9 @@ As part of the Wanderer platform, a public API has been introduced to help users
## Authentication
Each request to the Wanderer APIs that being with /api/map must include a valid API key in the `Authorization` header. The format is:
Authorization: Bearer <YOUR_MAP_API_KEY>
```
Authorization: Bearer <YOUR_MAP_API_KEY>
```
If the API key is missing or incorrect, you'll receive a `401 Unauthorized` response.

View File

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

View File

@@ -0,0 +1,217 @@
{
"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": "eve_id",
"type": "text"
},
{
"allow_nil?": false,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "character_eve_id",
"type": "text"
},
{
"allow_nil?": true,
"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": "description",
"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": "type",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "linked_system_id",
"type": "bigint"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "kind",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "group",
"type": "text"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "custom_info",
"type": "text"
},
{
"allow_nil?": false,
"default": "false",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "deleted",
"type": "boolean"
},
{
"allow_nil?": true,
"default": "nil",
"generated?": false,
"primary_key?": false,
"references": null,
"size": null,
"source": "update_forced_at",
"type": "utc_datetime"
},
{
"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_signatures_v1_system_id_fkey",
"on_delete": null,
"on_update": null,
"primary_key?": true,
"schema": "public",
"table": "map_system_v1"
},
"size": null,
"source": "system_id",
"type": "uuid"
}
],
"base_filter": null,
"check_constraints": [],
"custom_indexes": [],
"custom_statements": [],
"has_create_action": true,
"hash": "D1885311D35F70BB9117EB170BD2E07D0CFEEB9E6AE4D971C7DE8DBF9CCDED10",
"identities": [
{
"all_tenants?": false,
"base_filter": null,
"index_name": "map_system_signatures_v1_uniq_system_eve_id_index",
"keys": [
{
"type": "atom",
"value": "system_id"
},
{
"type": "atom",
"value": "eve_id"
}
],
"name": "uniq_system_eve_id",
"nils_distinct?": true,
"where": null
}
],
"multitenancy": {
"attribute": null,
"global": null,
"strategy": null
},
"repo": "Elixir.WandererApp.Repo",
"schema": null,
"table": "map_system_signatures_v1"
}