Merge pull request #1072 from Pax1601/1054-drawings-control-panel-separate-global-mission-drawings-control-from-navpoints-control

1054 drawings control panel separate global mission drawings control from navpoints control
This commit is contained in:
Pax1601
2025-03-26 16:48:39 +01:00
committed by GitHub
5 changed files with 231 additions and 143 deletions

View File

@@ -648,17 +648,17 @@ export class AWACSReferenceChangedEvent {
} }
export class DrawingsInitEvent { export class DrawingsInitEvent {
static on(callback: (drawingsData: any /*TODO*/) => void, singleShot = false) { static on(callback: (drawingsData: any, navpointData: any /*TODO*/) => void, singleShot = false) {
document.addEventListener( document.addEventListener(
this.name, this.name,
(ev: CustomEventInit) => { (ev: CustomEventInit) => {
callback(ev.detail); callback(ev.detail.drawingsData, ev.detail.navpointData);
}, },
{ once: singleShot } { once: singleShot }
); );
} }
static dispatch(drawingsData: any /*TODO*/) { static dispatch(drawingsData: any, navpointData?: any /*TODO*/) {
document.dispatchEvent(new CustomEvent(this.name, {detail: drawingsData})); document.dispatchEvent(new CustomEvent(this.name, {detail: drawingsData}));
if (DEBUG) console.log(`Event ${this.name} dispatched`); if (DEBUG) console.log(`Event ${this.name} dispatched`);
} }

View File

@@ -60,6 +60,7 @@ export interface SessionData {
hotgroups?: { [key: string]: number[] }; hotgroups?: { [key: string]: number[] };
starredSpawns?: { [key: number]: SpawnRequestTable }; starredSpawns?: { [key: number]: SpawnRequestTable };
drawings?: { [key: string]: { visibility: boolean; opacity: number; name: string; guid: string; containers: any; drawings: any } }; drawings?: { [key: string]: { visibility: boolean; opacity: number; name: string; guid: string; containers: any; drawings: any } };
navpoints?: { [key: string]: { visibility: boolean; opacity: number; name: string; guid: string; containers: any; drawings: any } };
} }
export interface ProfileOptions { export interface ProfileOptions {

View File

@@ -103,20 +103,20 @@ export class DCSPolygon extends DCSDrawing {
case "circle": case "circle":
// Example circle: // Example circle:
/* /*
colorString: 4278190335 colorString: 4278190335
fillColorString: 4278190127 fillColorString: 4278190127
lat: 27.65469131156049 lat: 27.65469131156049
layer: "Blue" layer: "Blue"
layerName: "Blue" layerName: "Blue"
lng: 54.33075915954884 lng: 54.33075915954884
name: "SA11-2 + SA6-3" name: "SA11-2 + SA6-3"
points: {0: {…}, x: 166867.07767244, y: -187576.93134045} points: {0: {…}, x: 166867.07767244, y: -187576.93134045}
polygonMode: "circle" polygonMode: "circle"
primitiveType: "Polygon" primitiveType: "Polygon"
radius: 36651.296128911 radius: 36651.296128911
style: "dash" style: "dash"
thickness: 16 thickness: 16
visible: true*/ visible: true*/
this.#polygon = new Circle([drawingData.lat, drawingData.lng], { this.#polygon = new Circle([drawingData.lat, drawingData.lng], {
radius: Math.round(drawingData.radius), radius: Math.round(drawingData.radius),
@@ -131,7 +131,7 @@ export class DCSPolygon extends DCSDrawing {
case "arrow": case "arrow":
let weight = this.getWeight(); let weight = this.getWeight();
if (!weight || weight < 1) { if (!weight || weight < 1) {
weight = 1; weight = 1;
} }
@@ -160,44 +160,44 @@ export class DCSPolygon extends DCSDrawing {
case "rect": case "rect":
/** Rectangle Example: /** Rectangle Example:
* { * {
"angle": 68.579040048342, "angle": 68.579040048342,
"colorString": 255, "colorString": 255,
"fillColorString": 4294901888, "fillColorString": 4294901888,
"height": 11100, "height": 11100,
"lat": 27.5547706075188, "lat": 27.5547706075188,
"layer": "Author", "layer": "Author",
"layerName": "Author", "layerName": "Author",
"lng": 57.22438242806247, "lng": 57.22438242806247,
"mapX": 152970.68262179, "mapX": 152970.68262179,
"mapY": 97907.892121675, "mapY": 97907.892121675,
"name": "FLOT BUFFER EAST", "name": "FLOT BUFFER EAST",
"points": { "points": {
"1": { "1": {
"lat": 27.417344649833286, "lat": 27.417344649833286,
"lng": 57.34472624501578 "lng": 57.34472624501578
}, },
"2": { "2": {
"lat": 27.38096510320196, "lat": 27.38096510320196,
"lng": 57.24010993680159 "lng": 57.24010993680159
}, },
"3": { "3": {
"lat": 27.69209116201148, "lat": 27.69209116201148,
"lng": 57.1037392116416 "lng": 57.1037392116416
}, },
"4": { "4": {
"lat": 27.728570135811577, "lat": 27.728570135811577,
"lng": 57.20860735951096 "lng": 57.20860735951096
} }
}, },
"polygonMode": "rect", "polygonMode": "rect",
"primitiveType": "Polygon", "primitiveType": "Polygon",
"style": "dot", "style": "dot",
"thickness": 16, "thickness": 16,
"visible": true, "visible": true,
"width": 37000 "width": 37000
} }
*/ */
const bounds = [ const bounds = [
[drawingData.points["1"].lat, drawingData.points["1"].lng], [drawingData.points["1"].lat, drawingData.points["1"].lng],
[drawingData.points["2"].lat, drawingData.points["2"].lng], [drawingData.points["2"].lat, drawingData.points["2"].lng],
@@ -217,42 +217,42 @@ export class DCSPolygon extends DCSDrawing {
case "oval": case "oval":
/** /**
* Example: * Example:
* { * {
"angle": 270, "angle": 270,
"colorString": 255, "colorString": 255,
"fillColorString": 4278190080, "fillColorString": 4278190080,
"lat": 25.032272009407105, "lat": 25.032272009407105,
"layer": "Blue", "layer": "Blue",
"layerName": "Blue", "layerName": "Blue",
"lng": 55.36597899137401, "lng": 55.36597899137401,
"mapX": -125416.92956726, "mapX": -125416.92956726,
"mapY": -89103.936896595, "mapY": -89103.936896595,
"name": "AM OTP", "name": "AM OTP",
"points": { "points": {
"1": { "1": {
"lat": 25.03332743167039, "lat": 25.03332743167039,
"lng": 55.34689257576858 "lng": 55.34689257576858
}, },
"2": { "2": {
"lat": 25.034529398092356, "lat": 25.034529398092356,
"lng": 55.348849087588164 "lng": 55.348849087588164
}, },
... ...
"24": { "24": {
"lat": 25.032053589358366, "lat": 25.032053589358366,
"lng": 55.34623694782629 "lng": 55.34623694782629
} }
}, },
"polygonMode": "oval", "polygonMode": "oval",
"primitiveType": "Polygon", "primitiveType": "Polygon",
"r1": 1992.4714734497, "r1": 1992.4714734497,
"r2": 541.99904672895, "r2": 541.99904672895,
"style": "dot", "style": "dot",
"thickness": 10, "thickness": 10,
"visible": true "visible": true
} }
*/ */
const points: [number, number][] = Object.values(drawingData.points as Record<string, { lat: number; lng: number }>).map((p) => [p.lat, p.lng]); const points: [number, number][] = Object.values(drawingData.points as Record<string, { lat: number; lng: number }>).map((p) => [p.lat, p.lng]);
this.#polygon = new Polygon(points, { this.#polygon = new Polygon(points, {
@@ -276,8 +276,8 @@ export class DCSPolygon extends DCSDrawing {
dashArray: dashArray, dashArray: dashArray,
}); });
break; break;
default: default:
break; break;
} }
@@ -374,21 +374,21 @@ export class DCSTextBox extends DCSDrawing {
super(drawingData, parent); super(drawingData, parent);
/* Example textbox "ABC625": /* Example textbox "ABC625":
angle: 0 angle: 0
borderThickness: 1 borderThickness: 1
colorString: 4294967295 colorString: 4294967295
fillColorString: 8421504 fillColorString: 8421504
font: "DejaVuLGCSansCondensed.ttf" font: "DejaVuLGCSansCondensed.ttf"
fontSize: 10 fontSize: 10
layer: "Common" layer: "Common"
layerName: "Common" layerName: "Common"
mapX: -261708.68309463 mapX: -261708.68309463
mapY: -217863.03743212 mapY: -217863.03743212
name: "ABC625" name: "ABC625"
primitiveType: "TextBox" primitiveType: "TextBox"
text: "ABC625" text: "ABC625"
visible: true visible: true
*/ */
const customIcon = new DivIcon({ const customIcon = new DivIcon({
html: ` html: `
<div style=" <div style="
@@ -527,9 +527,6 @@ export class DCSDrawingsContainer {
initFromData(drawingsData) { initFromData(drawingsData) {
let hasContainers = false; let hasContainers = false;
Object.keys(drawingsData).forEach((layerName: string) => { Object.keys(drawingsData).forEach((layerName: string) => {
if (layerName === 'navpoints') {
return;
}
if (drawingsData[layerName]["name"] === undefined && drawingsData[layerName]["callsignStr"] === undefined) { if (drawingsData[layerName]["name"] === undefined && drawingsData[layerName]["callsignStr"] === undefined) {
const newContainer = new DCSDrawingsContainer(layerName, this); const newContainer = new DCSDrawingsContainer(layerName, this);
this.addSubContainer(newContainer); this.addSubContainer(newContainer);
@@ -585,11 +582,11 @@ export class DCSDrawingsContainer {
if (othersContainer.getDrawings().length === 0) this.removeSubContainer(othersContainer); // Remove empty container if (othersContainer.getDrawings().length === 0) this.removeSubContainer(othersContainer); // Remove empty container
} }
initNavpoints(drawingsData) { // initNavpoints(drawingsData) {
const newContainer = new DCSDrawingsContainer('Navpoints', this); // const newContainer = new DCSDrawingsContainer('Navpoints', this);
this.addSubContainer(newContainer); // this.addSubContainer(newContainer);
newContainer.initFromData(drawingsData); // newContainer.initFromData(drawingsData);
} // }
getLayerGroup() { getLayerGroup() {
return this.#layerGroup; return this.#layerGroup;
@@ -703,14 +700,17 @@ export class DCSDrawingsContainer {
export class DrawingsManager { export class DrawingsManager {
#drawingsContainer: DCSDrawingsContainer; #drawingsContainer: DCSDrawingsContainer;
#navpointsContainer: DCSDrawingsContainer;
#updateEventRequested: boolean = false; #updateEventRequested: boolean = false;
#sessionDataDrawings = {}; #sessionDataDrawings = {};
#sessionDataNavpoints = {};
#initialized: boolean = false; #initialized: boolean = false;
constructor() { constructor() {
const drawingsLayerGroup = new LayerGroup(); const drawingsLayerGroup = new LayerGroup();
drawingsLayerGroup.addTo(getApp().getMap()); drawingsLayerGroup.addTo(getApp().getMap());
this.#drawingsContainer = new DCSDrawingsContainer("Mission drawings", drawingsLayerGroup); this.#drawingsContainer = new DCSDrawingsContainer("Mission drawings", drawingsLayerGroup);
this.#navpointsContainer = new DCSDrawingsContainer("Navpoints", drawingsLayerGroup);
MapOptionsChangedEvent.on((mapOptions: MapOptions) => { MapOptionsChangedEvent.on((mapOptions: MapOptions) => {
this.#drawingsContainer.setVisibility(mapOptions.showMissionDrawings); this.#drawingsContainer.setVisibility(mapOptions.showMissionDrawings);
@@ -718,18 +718,25 @@ export class DrawingsManager {
SessionDataLoadedEvent.on((sessionData) => { SessionDataLoadedEvent.on((sessionData) => {
this.#sessionDataDrawings = sessionData.drawings ?? {}; this.#sessionDataDrawings = sessionData.drawings ?? {};
if (this.#initialized) if (this.#sessionDataDrawings["Mission drawings"]) this.#drawingsContainer.fromJSON(this.#sessionDataDrawings["Mission drawings"]); this.#sessionDataNavpoints = sessionData.navpoints ?? {};
if (this.#initialized) {
if (this.#sessionDataDrawings["Mission drawings"]) this.#drawingsContainer.fromJSON(this.#sessionDataDrawings["Mission drawings"]);
if (this.#sessionDataNavpoints["Navpoints"]) this.#navpointsContainer.fromJSON(this.#sessionDataNavpoints["Navpoints"]);
}
this.#drawingsContainer.setVisibility(getApp().getMap().getOptions().showMissionDrawings); this.#drawingsContainer.setVisibility(getApp().getMap().getOptions().showMissionDrawings);
}); });
} }
initDrawings(data: { drawings: Record<string, Record<string, any>> }): boolean { initDrawings(data: { drawings: Record<string, Record<string, any>> }): boolean {
if (data && data.drawings) { if (data && data.drawings) {
if (data.drawings.navpoints) {
this.#navpointsContainer.initFromData(data.drawings.navpoints);
delete data.drawings.navpoints;
}
this.#drawingsContainer.initFromData(data.drawings); this.#drawingsContainer.initFromData(data.drawings);
if (data.drawings.navpoints) this.#drawingsContainer.initNavpoints(data.drawings.navpoints);
if (this.#sessionDataDrawings["Mission drawings"]) this.#drawingsContainer.fromJSON(this.#sessionDataDrawings["Mission drawings"]); if (this.#sessionDataDrawings["Mission drawings"]) this.#drawingsContainer.fromJSON(this.#sessionDataDrawings["Mission drawings"]);
this.#drawingsContainer.setVisibility(getApp().getMap().getOptions().showMissionDrawings); this.#drawingsContainer.setVisibility(getApp().getMap().getOptions().showMissionDrawings);
DrawingsInitEvent.dispatch(this.#drawingsContainer); DrawingsInitEvent.dispatch(this.#drawingsContainer, this.#navpointsContainer);
this.#initialized = true; this.#initialized = true;
return true; return true;
} else { } else {
@@ -742,6 +749,10 @@ export class DrawingsManager {
return this.#drawingsContainer; return this.#drawingsContainer;
} }
getNavpointsContainer() {
return this.#navpointsContainer;
}
requestUpdateEventDispatch() { requestUpdateEventDispatch() {
if (this.#updateEventRequested) return; if (this.#updateEventRequested) return;
this.#updateEventRequested = true; this.#updateEventRequested = true;

View File

@@ -134,8 +134,10 @@ export class SessionDataManager {
}); });
DrawingsUpdatedEvent.on(() => { DrawingsUpdatedEvent.on(() => {
let container = getApp().getDrawingsManager().getDrawingsContainer(); let mainDrawingsContainer = getApp().getDrawingsManager().getDrawingsContainer();
this.#sessionData.drawings = {"Mission drawings": container.toJSON()}; let navpointsContainer = getApp().getDrawingsManager().getNavpointsContainer();
this.#sessionData.drawings = {"Mission drawings": mainDrawingsContainer.toJSON()};
this.#sessionData.navpoints = {"Navpoints": navpointsContainer.toJSON()};
this.#saveSessionData(); this.#saveSessionData();
}); });
}, 200); }, 200);

View File

@@ -3,7 +3,7 @@ import { Menu } from "./components/menu";
import { FaArrowDown, FaArrowUp, FaChevronRight, FaTrash } from "react-icons/fa"; import { FaArrowDown, FaArrowUp, FaChevronRight, FaTrash } from "react-icons/fa";
import { getApp } from "../../olympusapp"; import { getApp } from "../../olympusapp";
import { OlStateButton } from "../components/olstatebutton"; import { OlStateButton } from "../components/olstatebutton";
import { faDrawPolygon, faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons"; import { faDrawPolygon, faEye, faEyeSlash, faMapLocation } from "@fortawesome/free-solid-svg-icons";
import { faCircle } from "@fortawesome/free-regular-svg-icons"; import { faCircle } from "@fortawesome/free-regular-svg-icons";
import { CoalitionPolygon } from "../../map/coalitionarea/coalitionpolygon"; import { CoalitionPolygon } from "../../map/coalitionarea/coalitionpolygon";
import { OlCoalitionToggle } from "../components/olcoalitiontoggle"; import { OlCoalitionToggle } from "../components/olcoalitiontoggle";
@@ -14,7 +14,7 @@ import { OlRangeSlider } from "../components/olrangeslider";
import { CoalitionCircle } from "../../map/coalitionarea/coalitioncircle"; import { CoalitionCircle } from "../../map/coalitionarea/coalitioncircle";
import { DrawSubState, ERAS_ORDER, IADSTypes, NO_SUBSTATE, OlympusState, OlympusSubState } from "../../constants/constants"; import { DrawSubState, ERAS_ORDER, IADSTypes, NO_SUBSTATE, OlympusState, OlympusSubState } from "../../constants/constants";
import { AppStateChangedEvent, CoalitionAreasChangedEvent, CoalitionAreaSelectedEvent, DrawingsInitEvent, DrawingsUpdatedEvent } from "../../events"; import { AppStateChangedEvent, CoalitionAreasChangedEvent, CoalitionAreaSelectedEvent, DrawingsInitEvent, DrawingsUpdatedEvent } from "../../events";
import { FaXmark } from "react-icons/fa6"; import { FaCopy, FaPencil, FaRegCompass, FaXmark } from "react-icons/fa6";
import { deepCopyTable } from "../../other/utils"; import { deepCopyTable } from "../../other/utils";
import { DCSDrawing, DCSDrawingsContainer, DCSEmptyLayer } from "../../map/drawings/drawingsmanager"; import { DCSDrawing, DCSDrawingsContainer, DCSEmptyLayer } from "../../map/drawings/drawingsmanager";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -35,18 +35,22 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
const [openContainers, setOpenContainers] = useState([] as DCSDrawingsContainer[]); const [openContainers, setOpenContainers] = useState([] as DCSDrawingsContainer[]);
const [mainDrawingsContainer, setDrawingsContainer] = useState({ container: null } as { container: null | DCSDrawingsContainer }); const [mainDrawingsContainer, setDrawingsContainer] = useState({ container: null } as { container: null | DCSDrawingsContainer });
const [navpointsContainer, setNavpointsContainer] = useState({ container: null } as { container: null | DCSDrawingsContainer });
const [searchString, setSearchString] = useState(""); const [searchString, setSearchString] = useState("");
const [navpointSearchString, setNavpointSearchString] = useState("");
useEffect(() => { useEffect(() => {
AppStateChangedEvent.on((state, subState) => { AppStateChangedEvent.on((state, subState) => {
setAppState(state); setAppState(state);
setAppSubState(subState); setAppSubState(subState);
}); });
DrawingsInitEvent.on((drawingContainer) => { DrawingsInitEvent.on((drawingContainer, navpointsContainer) => {
setDrawingsContainer({ container: drawingContainer }); setDrawingsContainer({ container: drawingContainer });
setNavpointsContainer({ container: navpointsContainer });
}); });
DrawingsUpdatedEvent.on(() => { DrawingsUpdatedEvent.on(() => {
setDrawingsContainer({ container: getApp().getDrawingsManager().getDrawingsContainer() }); setDrawingsContainer({ container: getApp().getDrawingsManager().getDrawingsContainer() });
setNavpointsContainer({ container: getApp().getDrawingsManager().getNavpointsContainer() });
}); });
}, []); }, []);
@@ -67,8 +71,14 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
return drawing.getVisibility() ? `text-gray-200` : `text-gray-600`; return drawing.getVisibility() ? `text-gray-200` : `text-gray-600`;
} }
function renderDrawingsContainerControls(container: DCSDrawingsContainer) { function renderDrawingsContainerControls(container: DCSDrawingsContainer, containerSearchString: string) {
if (container.hasSearchString(searchString)) { if (container.hasSearchString(containerSearchString)) {
/* The following snippet automatically open containers that contains searched drawings */
if (!openContainers.includes(container) && containerSearchString != "") {
openContainers.push(container);
setOpenContainers([...openContainers]);
}
return ( return (
<div className="ml-2 flex flex-col gap-2" key={container.getGuid()}> <div className="ml-2 flex flex-col gap-2" key={container.getGuid()}>
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
@@ -126,10 +136,12 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
></OlRangeSlider> ></OlRangeSlider>
</div> </div>
</div> </div>
{openContainers.includes(container) && container.getSubContainers().map((container) => renderDrawingsContainerControls(container))} {openContainers.includes(container) &&
container.getSubContainers().map((container) => renderDrawingsContainerControls(container, containerSearchString))}
{openContainers.includes(container) && {openContainers.includes(container) &&
container.getDrawings().map((drawing, index) => { container.getDrawings().map((drawing, index) => {
if (drawing instanceof DCSEmptyLayer) return <></>; if (drawing instanceof DCSEmptyLayer) return <></>;
if (!drawing.getName().toLowerCase().includes(containerSearchString.toLowerCase())) return <></>;
return ( return (
<div className="ml-4 flex justify-start gap-2" key={index}> <div className="ml-4 flex justify-start gap-2" key={index}>
<FontAwesomeIcon <FontAwesomeIcon
@@ -149,6 +161,19 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
${getDrawingLabelColor(drawing)} ${getDrawingLabelColor(drawing)}
text-ellipsis text-nowrap text-ellipsis text-nowrap
`}>{drawing.getName()}</div> `}>{drawing.getName()}</div>
<FontAwesomeIcon
icon={faMapLocation}
className={`
ml-auto cusor-pointer transition-transform
hover:scale-125
`}
onClick={() => {
const latLng = drawing.getLayer()["getLatLng"] && drawing.getLayer()["getLatLng"]();
const bounds = drawing.getLayer()["getBounds"] && drawing.getLayer()["getBounds"]();
latLng && getApp().getMap().setView(latLng, 14);
bounds && getApp().getMap().fitBounds(bounds);
}}
/>
</div> </div>
); );
})} })}
@@ -192,12 +217,9 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
You can change the name and the coalition of the area. You can also generate an IADS area by selecting the types, eras, and ranges of units you You can change the name and the coalition of the area. You can also generate an IADS area by selecting the types, eras, and ranges of units you
want to include in the area. You can also set the density and distribution of the IADS. If you check the 'Force coalition appropriate units' box, want to include in the area. You can also set the density and distribution of the IADS. If you check the 'Force coalition appropriate units' box,
the IADS will only include units that are appropriate for the coalition of the area (e.g. Hawk SAMs for {""} the IADS will only include units that are appropriate for the coalition of the area (e.g. Hawk SAMs for {""}
<span className="text-blue-500">blue</span> and SA-6 SAMs for{" "} <span className="text-blue-500">blue</span> and SA-6 SAMs for <span className={`
<span text-red-500
className={`text-red-500`} `}>red</span>
>
red
</span>
). ).
</div> </div>
<div> <div>
@@ -212,9 +234,7 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
<div> <div>
You can search for a specific drawing by typing in the search bar. The search is case-insensitive and will match any part of the drawing name. You can search for a specific drawing by typing in the search bar. The search is case-insensitive and will match any part of the drawing name.
</div> </div>
<div> <div>Any change you make is persistent and will be saved for the next time you reload Olympus, as long as the DCS mission was not restarted.</div>
Any change you make is persistent and will be saved for the next time you reload Olympus, as long as the DCS mission was not restarted.
</div>
</div> </div>
); );
}} }}
@@ -292,9 +312,61 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
<div> <div>
<div className="flex flex-col gap-2 p-6"> <div className="flex flex-col gap-2 p-6">
<div className="text-sm text-gray-400">Mission drawings</div> <div
<OlSearchBar onChange={(search) => setSearchString(search)} text={searchString || ""}></OlSearchBar> className={`flex flex-row items-center text-sm text-gray-400`}
<div className="flex flex-col gap-2">{mainDrawingsContainer.container && renderDrawingsContainerControls(mainDrawingsContainer.container)}</div> >
<span
className={`
mr-2 px-1 py-1 text-center font-bold text-olympus-700
text-white
`}
>
<FaPencil />
</span>
Mission drawings
</div>
<OlSearchBar
key="main-search"
onChange={(search) => {
setSearchString(search);
if (search === "") {
setOpenContainers([]);
}
}}
text={searchString || ""}
></OlSearchBar>
<div className="flex flex-col gap-2">
{mainDrawingsContainer.container && renderDrawingsContainerControls(mainDrawingsContainer.container, searchString)}
</div>
</div>
<div className="flex flex-col gap-2 p-6">
<div
className={`flex flex-row items-center text-sm text-gray-400`}
>
<span
className={`
mr-2 px-1 py-1 text-center font-bold text-olympus-700
text-white
`}
>
<FaRegCompass />
</span>
Navpoints
</div>
<OlSearchBar
key="navpoint-search"
onChange={(search) => {
setNavpointSearchString(search);
if (search === "") {
setOpenContainers([]);
}
}}
text={navpointSearchString || ""}
></OlSearchBar>
<div className="flex flex-col gap-2">
{navpointsContainer.container && renderDrawingsContainerControls(navpointsContainer.container, navpointSearchString)}
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -362,9 +434,11 @@ export function DrawingMenu(props: { open: boolean; onClose: () => void }) {
bg-olympus-600 p-5 bg-olympus-600 p-5
`} `}
> >
<div className={` <div
border-b-2 border-b-olympus-100 pb-4 text-gray-300 className={`border-b-2 border-b-olympus-100 pb-4 text-gray-300`}
`}>Automatic IADS generation</div> >
Automatic IADS generation
</div>
<OlDropdown className="" label="Units types" disableAutoClose={true}> <OlDropdown className="" label="Units types" disableAutoClose={true}>
{types.map((type, idx) => { {types.map((type, idx) => {
if (!(type in typesSelection)) { if (!(type in typesSelection)) {