More work on database manager

This commit is contained in:
Pax1601
2023-09-27 17:08:15 +02:00
parent e9100504a0
commit 7a24e5d39d
11 changed files with 294 additions and 92 deletions

View File

@@ -1526,9 +1526,12 @@ declare module "toolbars/commandmodetoolbar" {
}
}
declare module "toolbars/primarytoolbar" {
import { Dropdown } from "controls/dropdown";
import { Toolbar } from "toolbars/toolbar";
export class PrimaryToolbar extends Toolbar {
#private;
constructor(ID: string);
getMainDropdown(): Dropdown;
}
}
declare module "unit/citiesDatabase" {

View File

@@ -40,15 +40,15 @@ class DatabaseManagerPlugin {
_DatabaseManagerPlugin_contentDiv.set(this, void 0);
_DatabaseManagerPlugin_aircraftEditor.set(this, void 0);
__classPrivateFieldSet(this, _DatabaseManagerPlugin_element, document.createElement("div"), "f");
__classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").id = "database-control-panel";
__classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").id = "database-manager-panel";
__classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").oncontextmenu = () => { return false; };
__classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").classList.add("ol-dialog");
document.body.appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f"));
__classPrivateFieldSet(this, _DatabaseManagerPlugin_scrollDiv, document.createElement("div"), "f");
__classPrivateFieldGet(this, _DatabaseManagerPlugin_scrollDiv, "f").classList.add("dc-scroll-container");
__classPrivateFieldGet(this, _DatabaseManagerPlugin_scrollDiv, "f").classList.add("dm-scroll-container");
__classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_scrollDiv, "f"));
__classPrivateFieldSet(this, _DatabaseManagerPlugin_contentDiv, document.createElement("div"), "f");
__classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv, "f").classList.add("dc-content-container");
__classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv, "f").classList.add("dm-content-container");
__classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv, "f"));
__classPrivateFieldSet(this, _DatabaseManagerPlugin_aircraftEditor, new airuniteditor_1.AirUnitEditor(__classPrivateFieldGet(this, _DatabaseManagerPlugin_scrollDiv, "f"), __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv, "f")), "f");
}

View File

@@ -11,14 +11,19 @@ export class AirUnitEditor extends UnitEditor {
super(contentDiv1, contentDiv2, contentDiv3);
this.#loadoutEditor = new LoadoutEditor(this.contentDiv3);
this.contentDiv2.addEventListener("refresh", () => {
if (this.#blueprint !== null)
this.setBlueprint(this.#blueprint);
if (this.visible) {
if (this.#blueprint !== null)
this.setBlueprint(this.#blueprint);
}
});
this.contentDiv3.addEventListener("refresh", () => {
if (this.#blueprint !== null)
this.setBlueprint(this.#blueprint);
this.#loadoutEditor?.show();
if (this.visible) {
console.log("refresh")
if (this.#blueprint !== null)
this.setBlueprint(this.#blueprint);
this.#loadoutEditor?.show();
}
});
}
@@ -72,4 +77,9 @@ export class AirUnitEditor extends UnitEditor {
this.setBlueprint(this.#blueprint);
}
}
hide() {
super.hide();
this.#loadoutEditor?.hide();
}
}

View File

@@ -1,6 +1,8 @@
import { OlympusPlugin } from "interfaces";
import { AirUnitEditor } from "./airuniteditor";
import { OlympusApp } from "olympusapp";
import { GroundUnitEditor } from "./grounduniteditor";
import { PrimaryToolbar } from "toolbars/primarytoolbar";
export class DatabaseManagerPlugin implements OlympusPlugin {
#app: OlympusApp | null = null;
@@ -11,56 +13,102 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
#contentDiv2: HTMLElement;
#contentDiv3: HTMLElement;
#button1: HTMLButtonElement;
#button2: HTMLButtonElement;
#button3: HTMLButtonElement;
#button4: HTMLButtonElement;
#button5: HTMLButtonElement;
#button6: HTMLButtonElement;
#button7: HTMLButtonElement;
#button8: HTMLButtonElement;
#aircraftEditor: AirUnitEditor;
#helicopterEditor: AirUnitEditor;
#groundUnitEditor: GroundUnitEditor;
constructor() {
this.#element = document.createElement("div");
this.#element.id = "database-control-panel";
this.#element.id = "database-manager-panel";
this.#element.oncontextmenu = () => { return false; }
this.#element.classList.add("ol-dialog");
document.body.appendChild(this.#element);
let buttonContainer = document.createElement("div");
this.toggle(false);
let button1 = document.createElement("button");
button1.textContent = "Aircraft";
button1.onclick = () => this.#aircraftEditor.show();
buttonContainer.appendChild(button1);
let topButtonContainer = document.createElement("div");
let button2 = document.createElement("button");
button2.textContent = "Helicopter";
button2.onclick = () => this.#helicopterEditor.show();
buttonContainer.appendChild(button2);
this.#button1 = document.createElement("button");
this.#button1.classList.add("tab-button");
this.#button1.textContent = "Aircraft database";
this.#button1.onclick = () => { this.hideAll(); this.#aircraftEditor.show(); this.#button1.classList.add("selected"); };
topButtonContainer.appendChild(this.#button1);
let button3 = document.createElement("button");
button3.textContent = "Ground Unit";
buttonContainer.appendChild(button3);
this.#button2 = document.createElement("button");
this.#button2.classList.add("tab-button");
this.#button2.textContent = "Helicopter database";
this.#button2.onclick = () => { this.hideAll(); this.#helicopterEditor.show(); this.#button2.classList.add("selected"); };
topButtonContainer.appendChild(this.#button2);
let button4 = document.createElement("button");
button4.textContent = "Navy Unit";
buttonContainer.appendChild(button4);
this.#button3 = document.createElement("button");
this.#button3.classList.add("tab-button");
this.#button3.textContent = "Ground Unit database";
this.#button3.onclick = () => { this.hideAll(); this.#groundUnitEditor.show(); this.#button3.classList.add("selected"); };
topButtonContainer.appendChild(this.#button3);
this.#element.appendChild(buttonContainer);
this.#button4 = document.createElement("button");
this.#button4.classList.add("tab-button");
this.#button4.textContent = "Navy Unit database";
topButtonContainer.appendChild(this.#button4);
this.#element.appendChild(topButtonContainer);
this.#container = document.createElement("div");
this.#container.classList.add("dc-container");
this.#container.classList.add("dm-container");
this.#element.appendChild(this.#container)
this.#contentDiv1 = document.createElement("div");
this.#contentDiv1.classList.add("dc-content-container");
this.#contentDiv1.classList.add("dm-content-container");
this.#container.appendChild(this.#contentDiv1);
this.#contentDiv2 = document.createElement("div");
this.#contentDiv2.classList.add("dc-content-container");
this.#contentDiv2.classList.add("dm-content-container");
this.#container.appendChild(this.#contentDiv2);
this.#contentDiv3 = document.createElement("div");
this.#contentDiv3.classList.add("dc-content-container");
this.#contentDiv3.classList.add("dm-content-container");
this.#container.appendChild(this.#contentDiv3);
this.#aircraftEditor = new AirUnitEditor(this.#contentDiv1, this.#contentDiv2, this.#contentDiv3);
this.#helicopterEditor = new AirUnitEditor(this.#contentDiv1, this.#contentDiv2, this.#contentDiv3);
this.#groundUnitEditor = new GroundUnitEditor(this.#contentDiv1, this.#contentDiv2, this.#contentDiv3);
let bottomButtonContainer = document.createElement("div");
this.#button5 = document.createElement("button");
this.#button5.textContent = "Save";
this.#button5.title = "Save the changes on the server"
this.#button5.onclick = () => { };
bottomButtonContainer.appendChild(this.#button5);
this.#button6 = document.createElement("button");
this.#button6.textContent = "Discard";
this.#button6.title = "Discard all changes and reload the database from the server"
this.#button6.onclick = () => { this.loadDatabases(); };
bottomButtonContainer.appendChild(this.#button6);
this.#button7 = document.createElement("button");
this.#button7.textContent = "Reload";
this.#button7.onclick = () => { };
//bottomButtonContainer.appendChild(this.#button7);
this.#button8 = document.createElement("button");
this.#button8.textContent = "Close";
this.#button8.title = "Close the Database Manager"
this.#button8.onclick = () => { this.toggle(false); };
bottomButtonContainer.appendChild(this.#button8);
this.#element.appendChild(bottomButtonContainer);
}
getName() {
@@ -69,25 +117,59 @@ export class DatabaseManagerPlugin implements OlympusPlugin {
initialize(app: any) {
this.#app = app;
var aircraftDatabase = this.#app?.getAircraftDatabase();
if (aircraftDatabase != null) {
this.#aircraftEditor.setDatabase(aircraftDatabase);
}
this.loadDatabases();
var helicopterDatabase = this.#app?.getHelicopterDatabase();
if (helicopterDatabase != null) {
this.#helicopterEditor.setDatabase(helicopterDatabase);
}
var mainButtonDiv = document.createElement("div");
var mainButton = document.createElement("button");
mainButton.textContent = "Database Manager";
mainButtonDiv.appendChild(mainButton);
var toolbar: PrimaryToolbar = this.#app?.getToolbarsManager().get("primaryToolbar") as PrimaryToolbar;
var elements = toolbar.getMainDropdown().getOptionElements();
var arr = Array.prototype.slice.call(elements);
arr.splice(arr.length - 1, 0, mainButtonDiv);
toolbar.getMainDropdown().setOptionsElements(arr);
mainButton.onclick = () => { this.toggle(); }
return true;
}
loadDatabases() {
var aircraftDatabase = this.#app?.getAircraftDatabase();
if (aircraftDatabase != null)
this.#aircraftEditor.setDatabase(aircraftDatabase);
var helicopterDatabase = this.#app?.getHelicopterDatabase();
if (helicopterDatabase != null)
this.#helicopterEditor.setDatabase(helicopterDatabase);
var groundUnitDatabase = this.#app?.getGroundUnitDatabase();
if (groundUnitDatabase != null)
this.#groundUnitEditor.setDatabase(groundUnitDatabase);
this.hideAll();
this.#aircraftEditor.show();
this.#button1.classList.add("selected");
}
getElement() {
return this.#element;
}
toggle(bool?: boolean) {
this.getElement().classList.toggle("hide", bool);
if (bool)
this.getElement().classList.toggle("hide", !bool);
else
this.getElement().classList.toggle("hide");
}
hideAll() {
this.#aircraftEditor.hide();
this.#helicopterEditor.hide();
this.#groundUnitEditor.hide();
this.#button1.classList.remove("selected");
this.#button2.classList.remove("selected");
this.#button3.classList.remove("selected");
this.#button4.classList.remove("selected");
}
}

View File

@@ -0,0 +1,55 @@
import { UnitBlueprint } from "interfaces";
import { UnitEditor } from "./uniteditor";
import { addDropdownInput, addStringInput } from "./utils";
export class GroundUnitEditor extends UnitEditor {
#blueprint: UnitBlueprint | null = null;
constructor(contentDiv1: HTMLElement, contentDiv2: HTMLElement, contentDiv3: HTMLElement) {
super(contentDiv1, contentDiv2, contentDiv3);
this.contentDiv2.addEventListener("refresh", () => {
if (this.visible) {
if (this.#blueprint !== null)
this.setBlueprint(this.#blueprint);
}
});
this.contentDiv3.addEventListener("refresh", () => {
if (this.visible) {
if (this.#blueprint !== null)
this.setBlueprint(this.#blueprint);
}
});
}
setBlueprint(blueprint: UnitBlueprint) {
this.#blueprint = blueprint;
if (this.#blueprint !== null) {
this.contentDiv2.replaceChildren();
addStringInput(this.contentDiv2, "Name", blueprint.name, "text", (value: string) => {blueprint.name = value; }, true);
addStringInput(this.contentDiv2, "Label", blueprint.label, "text", (value: string) => {blueprint.label = value; });
addStringInput(this.contentDiv2, "Short label", blueprint.shortLabel, "text", (value: string) => {blueprint.shortLabel = value; });
addStringInput(this.contentDiv2, "Type", blueprint.type?? "", "text", (value: string) => {blueprint.type = value; });
addDropdownInput(this.contentDiv2, "Coalition", blueprint.coalition, ["", "blue", "red"],);
addDropdownInput(this.contentDiv2, "Era", blueprint.era, ["WW2", "Early Cold War", "Mid Cold War", "Late Cold War", "Modern"]);
addStringInput(this.contentDiv2, "Filename", blueprint.filename?? "", "text", (value: string) => {blueprint.filename = value; });
addStringInput(this.contentDiv2, "Cost", String(blueprint.cost)?? "", "number", (value: string) => {blueprint.cost = parseFloat(value); });
}
}
addBlueprint(key: string) {
if (this.database != null) {
this.database.blueprints[key] = {
name: key,
coalition: "",
label: "",
shortLabel: "",
era: ""
}
this.show();
this.setBlueprint(this.database.blueprints[key]);
}
}
}

View File

@@ -4,10 +4,15 @@ import { addLoadoutItemsEditor, addStringInput } from "./utils";
export class LoadoutEditor {
#contentDiv: HTMLElement;
#loadout: LoadoutBlueprint | null = null;
#visible: boolean = false;
constructor(contentDiv: HTMLElement) {
this.#contentDiv = contentDiv;
this.#contentDiv.addEventListener("refresh", () => { this.show(); })
this.#contentDiv.addEventListener("refresh", () => {
if (this.#visible)
this.show();
})
}
setLoadout(loadout: LoadoutBlueprint) {
@@ -15,6 +20,7 @@ export class LoadoutEditor {
}
show() {
this.#visible = true;
this.#contentDiv.replaceChildren();
if (this.#loadout) {
@@ -26,6 +32,7 @@ export class LoadoutEditor {
}
hide() {
this.#visible = false;
this.#contentDiv.replaceChildren();
}
}

View File

@@ -4,6 +4,7 @@ import { addBlueprintsScroll, addNewElementInput } from "./utils";
export abstract class UnitEditor {
database: {blueprints: {[key: string]: UnitBlueprint}} | null = null;
visible: boolean = false;
contentDiv1: HTMLElement;
contentDiv2: HTMLElement;
contentDiv3: HTMLElement;
@@ -12,7 +13,10 @@ export abstract class UnitEditor {
this.contentDiv1 = contentDiv1;
this.contentDiv2 = contentDiv2;
this.contentDiv3 = contentDiv3;
this.contentDiv1.addEventListener("refresh", () => { this.show(); })
this.contentDiv1.addEventListener("refresh", () => {
if (this.visible)
this.show();
})
}
setDatabase(database: UnitDatabase) {
@@ -20,6 +24,7 @@ export abstract class UnitEditor {
}
show() {
this.visible = true;
this.contentDiv1.replaceChildren();
this.contentDiv2.replaceChildren();
this.contentDiv3.replaceChildren();
@@ -37,6 +42,7 @@ export abstract class UnitEditor {
}
hide() {
this.visible = false;
this.contentDiv1.replaceChildren();
this.contentDiv2.replaceChildren();
this.contentDiv3.replaceChildren();

View File

@@ -40,7 +40,7 @@ export function addDropdownInput(div: HTMLElement, key: string, value: string, o
export function addLoadoutItemsEditor(div: HTMLElement, loadout: LoadoutBlueprint) {
var itemsEl = document.createElement("div");
itemsEl.classList.add("dc-scroll-container", "dc-items-container");
itemsEl.classList.add("dm-scroll-container", "dm-items-container");
loadout.items.forEach((item: LoadoutItemBlueprint, index: number) => {
var rowDiv = document.createElement("div");
@@ -79,7 +79,7 @@ export function addLoadoutItemsEditor(div: HTMLElement, loadout: LoadoutBlueprin
div.appendChild(itemsEl);
var inputDiv = document.createElement("div");
inputDiv.classList.add("dc-new-item-input");
inputDiv.classList.add("dm-new-item-input");
var button = document.createElement("button");
button.innerText = "Add";
inputDiv.appendChild(button);
@@ -96,7 +96,7 @@ export function addLoadoutItemsEditor(div: HTMLElement, loadout: LoadoutBlueprin
export function addNewElementInput(div: HTMLElement, callback: CallableFunction) {
var inputDiv = document.createElement("div");
inputDiv.classList.add("dc-new-element-input");
inputDiv.classList.add("dm-new-element-input");
var input = document.createElement("input");
inputDiv.appendChild(input);
var button = document.createElement("button");
@@ -108,7 +108,7 @@ export function addNewElementInput(div: HTMLElement, callback: CallableFunction)
export function addBlueprintsScroll(div: HTMLElement, database: {blueprints: {[key: string]: UnitBlueprint}}, callback: CallableFunction) {
var scrollDiv = document.createElement("div");
scrollDiv.classList.add("dc-scroll-container");
scrollDiv.classList.add("dm-scroll-container");
if (database !== null) {
var blueprints: {[key: string]: UnitBlueprint} = database.blueprints;
@@ -135,7 +135,7 @@ export function addBlueprintsScroll(div: HTMLElement, database: {blueprints: {[k
export function addLoadoutsScroll(div: HTMLElement, loadouts: LoadoutBlueprint[], callback: CallableFunction) {
var loadoutsEl = document.createElement("div");
loadoutsEl.classList.add("dc-scroll-container", "dc-loadout-container")
loadoutsEl.classList.add("dm-scroll-container", "dm-loadout-container")
loadouts.forEach((loadout: LoadoutBlueprint, index: number) => {
var rowDiv = document.createElement("div");

View File

@@ -1,91 +1,102 @@
#database-control-panel {
#database-manager-panel {
display: flex;
flex-direction: column;
width: 80%;
height: 80%;
padding: 10px;
border-radius: 5px;
}
#database-control-panel * {
#database-manager-panel * {
font-size: 13;
font-weight: bold;
}
#database-control-panel>div:first-child {
#database-manager-panel>div:first-child {
display: flex;
column-gap: 2px;
align-items: center;
}
.dc-container {
#database-manager-panel>div:last-child {
display: flex;
column-gap: 5px;
align-items: center;
justify-content: end;
justify-items: end;
margin-top: 5px;
}
.dm-container {
background-color: #555555;
border: 2px solid #777777;
position: relative;
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
padding: 10px;
padding: 5px;
height: calc(100% - 64px - 5px);
border-radius: 0px 5px 5px 5px;
}
.dc-container>div {
min-width: 200px;
width: fit-content;
margin: 10px;
}
.dc-container>div:nth-child(3) {
.dm-container>div:nth-child(3) {
flex: 1;
}
.dc-scroll-container {
.dm-content-container {
position: relative;
margin: 10px;
display: flex;
flex-direction: column;
row-gap: 5px;
height: calc(100% - 20px);
min-width: 200px;
width: fit-content;
}
.dm-scroll-container {
display: flex;
flex-direction: column;
overflow-y: auto;
max-height: 600px;
max-height: 100%;
color: black;
font-weight: bold;
}
.dc-scroll-container>* {
.dm-scroll-container>* {
padding: 2px;
}
.dc-scroll-container>div:nth-child(even) {
.dm-scroll-container>div:nth-child(even) {
background-color: gainsboro;
}
.dc-scroll-container>div:nth-child(odd) {
.dm-scroll-container>div:nth-child(odd) {
background-color: white;
}
.dc-scroll-container>div *:nth-child(1) {
.dm-scroll-container>div *:nth-child(1) {
height: 100%;
width: 100%;
}
.dc-scroll-container>div *:nth-child(1):hover{
.dm-scroll-container>div *:nth-child(1):hover{
background-color: var(--secondary-blue-text);
color: white;
cursor: pointer;
}
.dc-scroll-container>div {
.dm-scroll-container>div {
display: flex;
align-items: center;
justify-content: space-between;
}
.dc-scroll-container>div>button {
.dm-scroll-container>div>button {
height: 20px;
width: 20px;
padding: 0px;
}
.dc-content-container {
margin: 10px;
display: flex;
flex-direction: column;
row-gap: 5px;
}
.input-row {
width: 100%;
display: flex;
@@ -104,35 +115,35 @@
width: 100%;
}
.dc-loadout-container {
.dm-loadout-container {
max-height: 100%;
width: 400px;
}
.dc-items-container {
.dm-items-container {
max-height: 100%;
height: fit-content;
}
.dc-items-container>div {
.dm-items-container>div {
display: flex;
align-items: center;
column-gap: 2px;
}
.dc-items-container>div>label {
.dm-items-container>div>label {
width: 80px !important;
}
.dc-items-container div>input:nth-of-type(1) {
.dm-items-container div>input:nth-of-type(1) {
width: 100%;
}
.dc-items-container div>input:nth-of-type(2) {
.dm-items-container div>input:nth-of-type(2) {
width: 40px;
}
.dc-new-element-input {
.dm-new-element-input {
display: flex;
flex-direction: row;
column-gap: 2px;
@@ -140,19 +151,43 @@
align-items: center;
}
.dc-new-element-input>input {
.dm-new-element-input>input {
width: 100%;
}
.dc-new-element-input>button {
.dm-new-element-input>button {
width: 60px;
}
.dc-new-item-input {
.dm-new-item-input {
display: flex;
justify-content: end;
}
.dc-new-item-input>button {
.dm-new-item-input>button {
width: 60px;
}
.tab-button {
transform: translateY(+3px);
background-color: #333333;
border-radius: 0;
border-bottom: 2px solid transparent;
border-top: 2px solid #777777;
border-left: 2px solid #777777;
border-right: 0px solid #777777;
}
.tab-button.selected {
background-color: #555555;
z-index: 10;
}
.tab-button:first-of-type {
border-top-left-radius: 5px;
}
.tab-button:last-of-type {
border-top-right-radius: 5px;
border-right: 2px solid #777777;
}

View File

@@ -191,7 +191,7 @@ export class OlympusApp {
// Toolbars
this.getToolbarsManager().add("primaryToolbar", new PrimaryToolbar("primary-toolbar"))
.add("commandModeToolbar", new PrimaryToolbar("command-mode-toolbar"));
.add("commandModeToolbar", new CommandModeToolbar("command-mode-toolbar"));
this.#pluginsManager = new PluginsManager();

View File

@@ -2,12 +2,16 @@ import { Dropdown } from "../controls/dropdown";
import { Toolbar } from "./toolbar";
export class PrimaryToolbar extends Toolbar {
#mainDropdown: Dropdown;
constructor(ID: string) {
super(ID);
// TODO move here all code about primary toolbar
/* The content of the dropdown is entirely defined in the .ejs file */
new Dropdown("app-icon", () => { });
this.#mainDropdown = new Dropdown("app-icon", () => { });
}
getMainDropdown() {
return this.#mainDropdown;
}
}