From 8e9e6749dbb02dcfddb68097a24c20fe13194e27 Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Mon, 8 Apr 2024 08:49:05 +0200 Subject: [PATCH] More tests on react components --- frontend/react/.vscode/launch.json | 16 ++++ frontend/react/.vscode/tasks.json | 13 +++ frontend/react/src/olympusapp.ts | 1 + frontend/react/src/other/utils.ts | 17 +++- frontend/react/src/ui.css | 22 ++++- frontend/react/src/ui.tsx | 4 +- .../react/src/ui/components/olaccordion.tsx | 13 +-- .../react/src/ui/components/oldropdown.tsx | 6 +- .../src/ui/components/olunitlistentry.tsx | 15 ++++ .../react/src/ui/components/olunitsummary.tsx | 27 ++++++ .../react/src/ui/panels/components/menu.tsx | 5 +- frontend/react/src/ui/panels/spawnmenu.tsx | 86 +++++++++++++++---- .../react/src/ui/panels/unitspawnmenu.tsx | 8 ++ 13 files changed, 203 insertions(+), 30 deletions(-) create mode 100644 frontend/react/.vscode/launch.json create mode 100644 frontend/react/.vscode/tasks.json create mode 100644 frontend/react/src/ui/components/olunitlistentry.tsx create mode 100644 frontend/react/src/ui/components/olunitsummary.tsx create mode 100644 frontend/react/src/ui/panels/unitspawnmenu.tsx diff --git a/frontend/react/.vscode/launch.json b/frontend/react/.vscode/launch.json new file mode 100644 index 00000000..d0e64675 --- /dev/null +++ b/frontend/react/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}", + "preLaunchTask": "npm: dev" + } + ] +} \ No newline at end of file diff --git a/frontend/react/.vscode/tasks.json b/frontend/react/.vscode/tasks.json new file mode 100644 index 00000000..f3be330a --- /dev/null +++ b/frontend/react/.vscode/tasks.json @@ -0,0 +1,13 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "dev", + "problemMatcher": [], + "label": "npm: dev", + "detail": "vite --port=8080", + "isBackground": true + } + ] +} \ No newline at end of file diff --git a/frontend/react/src/olympusapp.ts b/frontend/react/src/olympusapp.ts index 4019df51..b17010ac 100644 --- a/frontend/react/src/olympusapp.ts +++ b/frontend/react/src/olympusapp.ts @@ -35,6 +35,7 @@ import { aircraftDatabase } from "./unit/databases/aircraftdatabase"; import { helicopterDatabase } from "./unit/databases/helicopterdatabase"; import { groundUnitDatabase } from "./unit/databases/groundunitdatabase"; import { navyUnitDatabase } from "./unit/databases/navyunitdatabase"; +import { initFlowbite } from "flowbite"; //import { UnitListPanel } from "./panels/unitlistpanel"; //import { ContextManager } from "./context/contextmanager"; //import { Context } from "./context/context"; diff --git a/frontend/react/src/other/utils.ts b/frontend/react/src/other/utils.ts index ba660c1c..952c2e0e 100644 --- a/frontend/react/src/other/utils.ts +++ b/frontend/react/src/other/utils.ts @@ -473,4 +473,19 @@ export function getGroundElevation(latlng: LatLng, callback: CallableFunction) { } }; xhr.send(); -} \ No newline at end of file +} + +export function getWikipediaEntry(search: string, callback: CallableFunction) { + /* Get the ground elevation from the server endpoint */ + const xhr = new XMLHttpRequest(); + xhr.open('GET', `https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts|pageimages&exintro&explaintext&generator=search&gsrsearch=intitle:${search}&gsrlimit=1&redirects=1&origin=*`, true); + xhr.timeout = 500; // ms + xhr.responseType = 'json'; + xhr.onload = () => { + var status = xhr?.status; + if (status === 200) { + callback(xhr.response) + } + }; + xhr.send(); + } \ No newline at end of file diff --git a/frontend/react/src/ui.css b/frontend/react/src/ui.css index e50bf918..bd60d577 100644 --- a/frontend/react/src/ui.css +++ b/frontend/react/src/ui.css @@ -1,3 +1,19 @@ +/* width */ +::-webkit-scrollbar { + width: 10px; +} + +/* Track */ +::-webkit-scrollbar-track { + +} + +/* Handle */ +::-webkit-scrollbar-thumb { + background: #FFFFFFAA; + border-radius: 10px; + cursor: pointer; +} /* Hide scrollbar for Chrome, Safari and Opera */ .no-scrollbar::-webkit-scrollbar { @@ -6,6 +22,8 @@ /* Hide scrollbar for IE, Edge and Firefox */ .no-scrollbar { - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; + /* IE and Edge */ + scrollbar-width: none; + /* Firefox */ } \ No newline at end of file diff --git a/frontend/react/src/ui.tsx b/frontend/react/src/ui.tsx index f0b1da6b..813e52d1 100644 --- a/frontend/react/src/ui.tsx +++ b/frontend/react/src/ui.tsx @@ -1,5 +1,6 @@ -import React, { useState } from 'react' +import React, { useState, useEffect } from 'react' import './ui.css' +import { initFlowbite } from "flowbite"; import { Header } from './ui/panels/header' import { EventsProvider } from './eventscontext' @@ -17,6 +18,7 @@ export type OlympusState = { } export function UI(props) { + var [flowbiteInited, setFlowbiteInited] = useState(false); var [mainMenuVisible, setMainMenuVisible] = useState(false); var [spawnMenuVisible, setSpawnMenuVisible] = useState(false); var [unitControlMenuVisible, setUnitControlMenuVisible] = useState(false); diff --git a/frontend/react/src/ui/components/olaccordion.tsx b/frontend/react/src/ui/components/olaccordion.tsx index 2a976a31..0c23e185 100644 --- a/frontend/react/src/ui/components/olaccordion.tsx +++ b/frontend/react/src/ui/components/olaccordion.tsx @@ -3,6 +3,7 @@ import React, { useId, useEffect, useRef, useState } from "react" import 'flowbite'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faArrowCircleDown, faChevronDown, faChevronUp } from "@fortawesome/free-solid-svg-icons"; +import { initFlowbite } from "flowbite"; export function OlAccordion(props) { var [scrolledUp, setScrolledUp] = useState(true); @@ -21,23 +22,25 @@ export function OlAccordion(props) { setScrolledUp(e.target.scrollTop === 0); } }) + + initFlowbite(); }) - return
+ return

-
-
{!scrolledUp && }
+
+ {props.showArrows &&
{!scrolledUp && }
}
{props.children}
-
{!scrolledDown && }
+ {props.showArrows &&
{!scrolledDown && }
}
} \ No newline at end of file diff --git a/frontend/react/src/ui/components/oldropdown.tsx b/frontend/react/src/ui/components/oldropdown.tsx index bc7de864..710a1f9c 100644 --- a/frontend/react/src/ui/components/oldropdown.tsx +++ b/frontend/react/src/ui/components/oldropdown.tsx @@ -10,14 +10,14 @@ export function OlDropdown(props) { var [value, setValue] = useState(props.items[0] ?? "N/A" ) const buttonId = useId(); const dropdownId = useId() - + return
-
+
    {props.items.map((item) => { return
  • diff --git a/frontend/react/src/ui/components/olunitlistentry.tsx b/frontend/react/src/ui/components/olunitlistentry.tsx new file mode 100644 index 00000000..e6e3b81c --- /dev/null +++ b/frontend/react/src/ui/components/olunitlistentry.tsx @@ -0,0 +1,15 @@ +import React, { useId, useState, useRef } from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faQuestionCircle } from "@fortawesome/free-solid-svg-icons"; + +import 'flowbite'; + +export function OlUnitEntryList(props) { + return
    + +
    {props.blueprint.label}
    +
    {props.blueprint.era === "WW2" ? "WW2" : props.blueprint.era.split(" ").map((word) => { + return word.charAt(0).toLocaleUpperCase(); + })}
    +
    +} diff --git a/frontend/react/src/ui/components/olunitsummary.tsx b/frontend/react/src/ui/components/olunitsummary.tsx new file mode 100644 index 00000000..2bababe6 --- /dev/null +++ b/frontend/react/src/ui/components/olunitsummary.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import { UnitBlueprint } from "../../interfaces"; + +export function OlUnitSummary(props: {blueprint: UnitBlueprint}) { + console.log(props.blueprint) + return
    +
    + +
    {props.blueprint.label}
    +
    +
    +

    {props.blueprint.description}

    +
    +
    + {props.blueprint.abilities?.split(" ").map((tag) => { + return
    + {tag} +
    + })} + +
    {props.blueprint.era === "WW2" ? "WW2" : props.blueprint.era.split(" ").map((word) => { + return word.charAt(0).toLocaleUpperCase(); + })}
    +
    + +
    +} \ No newline at end of file diff --git a/frontend/react/src/ui/panels/components/menu.tsx b/frontend/react/src/ui/panels/components/menu.tsx index d383ce8c..983b1d20 100644 --- a/frontend/react/src/ui/panels/components/menu.tsx +++ b/frontend/react/src/ui/panels/components/menu.tsx @@ -1,4 +1,3 @@ -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Drawer, DrawerInterface } from "flowbite"; import React, { useEffect, useId, useRef } from "react"; @@ -11,13 +10,13 @@ export function Menu(props) { props.open ? drawer.show() : drawer.hide(); }) - return
    + return
    {props.title}
    diff --git a/frontend/react/src/ui/panels/spawnmenu.tsx b/frontend/react/src/ui/panels/spawnmenu.tsx index 7cefb56d..0dd666aa 100644 --- a/frontend/react/src/ui/panels/spawnmenu.tsx +++ b/frontend/react/src/ui/panels/spawnmenu.tsx @@ -1,25 +1,81 @@ -import React from "react"; +import React, { useState } from "react"; import { Menu } from "./components/menu"; -import { faJetFighter, faPlus } from '@fortawesome/free-solid-svg-icons'; +import { faHelicopter, faJetFighter, faPlus, faShieldAlt, faShip, faTruck } from '@fortawesome/free-solid-svg-icons'; import { library } from '@fortawesome/fontawesome-svg-core' import { OlSearchBar } from "../components/olsearchbar"; import { OlAccordion } from "../components/olaccordion"; import { getApp } from "../../olympusapp"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { OlUnitEntryList } from "../components/olunitlistentry"; +import { UnitBlueprint } from "../../interfaces"; +import { UnitSpawnMenu } from "./unitspawnmenu"; library.add(faPlus); export function SpawnMenu(props) { - return - - -
    - {getApp() && Object.keys(getApp().getAircraftDatabase().blueprints).map((key) => { - return
    {getApp().getAircraftDatabase().blueprints[key].label}
    ; - })} -
    -
    - - -
    + var [blueprint, setBlueprint] = useState(null); + + const filteredAircraft = getApp()?.getAircraftDatabase()?.blueprints ?? {}; + const filteredHelicopters = getApp()?.getHelicopterDatabase()?.blueprints ?? {}; + const filteredNavyUnits = getApp()?.getNavyUnitDatabase()?.blueprints ?? {}; + + var filteredAirDefense = {}; + var filteredGroundUnits = {}; + Object.keys(getApp()?.getGroundUnitDatabase()?.blueprints ?? {}).forEach((key) => { + var blueprint = getApp()?.getGroundUnitDatabase()?.blueprints[key]; + var type = blueprint.label; + if (/\bAAA|SAM\b/.test(type) || /\bmanpad|stinger\b/i.test(type)) { + filteredAirDefense[key] = blueprint; + } else { + filteredGroundUnits[key] = blueprint; + } + }); + + return + {!blueprint &&
    + + +
    + {Object.keys(filteredAircraft).map((key) => { + const blueprint = getApp().getAircraftDatabase().blueprints[key]; + return setBlueprint(blueprint)} /> + })} +
    +
    + +
    + {Object.keys(filteredHelicopters).map((key) => { + return + })} +
    +
    + +
    + {Object.keys(filteredAirDefense).map((key) => { + return + })} +
    +
    + +
    + {Object.keys(filteredGroundUnits).map((key) => { + const blueprint = getApp().getGroundUnitDatabase().blueprints[key]; + return setBlueprint(blueprint)} /> + })} +
    +
    + +
    + {Object.keys(filteredNavyUnits).map((key) => { + return + })} +
    +
    + + + +
    + } + + {blueprint && } +
    } \ No newline at end of file diff --git a/frontend/react/src/ui/panels/unitspawnmenu.tsx b/frontend/react/src/ui/panels/unitspawnmenu.tsx new file mode 100644 index 00000000..b3068633 --- /dev/null +++ b/frontend/react/src/ui/panels/unitspawnmenu.tsx @@ -0,0 +1,8 @@ +import React from "react"; +import { OlUnitSummary } from "../components/olunitsummary"; + +export function UnitSpawnMenu(props) { + return
    + +
    +}