mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Slightly nicer PoC.
This commit is contained in:
parent
6f64bd1622
commit
071942b632
@ -12,7 +12,7 @@
|
||||
column-gap: 4px;
|
||||
display:flex;
|
||||
flex-flow: row nowrap;
|
||||
padding:4px;
|
||||
row-gap:4px;
|
||||
}
|
||||
|
||||
.ol-strip-board-strip[data-flight-status="checkedin"] {
|
||||
@ -20,7 +20,7 @@
|
||||
}
|
||||
|
||||
.ol-strip-board-strip[data-flight-status="readytotaxi"] {
|
||||
background-color: #ffff002A;
|
||||
background-color: #ffff0063;
|
||||
}
|
||||
|
||||
.ol-strip-board-strip[data-flight-status="clearedtotaxi"] {
|
||||
@ -46,7 +46,7 @@
|
||||
padding: 4px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width:70px;
|
||||
width:80px;
|
||||
}
|
||||
|
||||
.ol-strip-board-strip input[type="text"] {
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
}
|
||||
|
||||
#primary-toolbar {
|
||||
align-items: center;
|
||||
display:flex;
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 10px;
|
||||
|
||||
@ -346,6 +346,11 @@ nav.ol-panel> :last-child {
|
||||
row-gap: 4px;
|
||||
}
|
||||
|
||||
.ol-group-header {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ol-panel .ol-group.wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
@ -545,30 +550,6 @@ nav.ol-panel> :last-child {
|
||||
width: 28px;
|
||||
}
|
||||
|
||||
#unit-selection #unit-identification [data-object|="unit"] .unit-short-label {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#unit-selection #unit-identification #unit-name {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
font-weight: var(--font-weight-bolder);
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
#edit-unit-name {
|
||||
background-image: url("/images/buttons/edit.svg");
|
||||
background-repeat: no-repeat;
|
||||
height: 14px;
|
||||
margin-left: 10px;
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
#unit-visibility-control {
|
||||
align-items: center;
|
||||
}
|
||||
@ -619,6 +600,18 @@ body[data-hide-navyunit] #unit-visibility-control-navyunit {
|
||||
background-image: var(--visibility-control-navyunit-hidden-url);
|
||||
}
|
||||
|
||||
#atc-navbar-control {
|
||||
align-items: center;
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#atc-navbar-control button {
|
||||
background:#ffffff20;
|
||||
border-radius: var( --border-radius-sm );
|
||||
padding:4px;
|
||||
}
|
||||
|
||||
|
||||
.toggle {
|
||||
--width: 40px;
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
import { Draggable } from "leaflet";
|
||||
import { Dropdown } from "../controls/dropdown";
|
||||
import { zeroAppend } from "../other/utils";
|
||||
import { ATC } from "./atc";
|
||||
|
||||
export interface ATCTemplateInterface {
|
||||
"template": string
|
||||
export interface StripBoardStripInterface {
|
||||
"id": string,
|
||||
"element": HTMLElement,
|
||||
"dropdowns": {[key:string]: Dropdown}
|
||||
}
|
||||
|
||||
export abstract class ATCBoard {
|
||||
@ -14,6 +18,9 @@ export abstract class ATCBoard {
|
||||
#boardElement:HTMLElement;
|
||||
#clockElement:HTMLElement;
|
||||
#stripBoardElement:HTMLElement;
|
||||
|
||||
// Content
|
||||
#strips:{[key:string]: StripBoardStripInterface} = {};
|
||||
|
||||
// Update timing
|
||||
#updateInterval:number|undefined = undefined;
|
||||
@ -27,6 +34,18 @@ export abstract class ATCBoard {
|
||||
this.#stripBoardElement = <HTMLElement>this.getBoardElement().querySelector( ".ol-strip-board-strips" );
|
||||
this.#clockElement = <HTMLElement>this.getBoardElement().querySelector( ".ol-strip-board-clock" );
|
||||
|
||||
if ( this.#boardElement.classList.contains( "ol-draggable" ) ) {
|
||||
|
||||
let options:any = {};
|
||||
|
||||
let handle = this.#boardElement.querySelector( ".handle" );
|
||||
|
||||
if ( handle instanceof HTMLElement ) {
|
||||
options.handle = handle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
setInterval( () => {
|
||||
this.updateClock();
|
||||
@ -35,17 +54,30 @@ export abstract class ATCBoard {
|
||||
}
|
||||
|
||||
|
||||
addStrip( strip:StripBoardStripInterface ) {
|
||||
this.#strips[ strip.id ] = strip;
|
||||
}
|
||||
|
||||
|
||||
calculateTimeToGo( fromTimestamp:number, toTimestamp:number ) {
|
||||
|
||||
let timestamp = ( toTimestamp - fromTimestamp ) / 1000;
|
||||
|
||||
const hours = zeroAppend( Math.floor( timestamp / 3600 ), 2 );
|
||||
const hasElapsed = ( timestamp < 0 ) ? true : false;
|
||||
|
||||
if ( hasElapsed ) {
|
||||
timestamp = -( timestamp );
|
||||
}
|
||||
|
||||
const hours = ( timestamp < 3600 ) ? "00" : zeroAppend( Math.floor( timestamp / 3600 ), 2 );
|
||||
const rMinutes = timestamp % 3600;
|
||||
|
||||
const minutes = zeroAppend( Math.floor( rMinutes / 60 ), 2 );
|
||||
const minutes = ( timestamp < 60 ) ? "00" : zeroAppend( Math.floor( rMinutes / 60 ), 2 );
|
||||
const seconds = zeroAppend( Math.floor( rMinutes % 60 ), 2 );
|
||||
|
||||
return {
|
||||
"elapsedMarker": ( hasElapsed ) ? "+" : "-",
|
||||
"hasElapsed": hasElapsed,
|
||||
"hours": hours,
|
||||
"minutes": minutes,
|
||||
"seconds": seconds,
|
||||
@ -56,6 +88,16 @@ export abstract class ATCBoard {
|
||||
}
|
||||
|
||||
|
||||
deleteStrip( id:string ) {
|
||||
|
||||
if ( this.#strips.hasOwnProperty( id ) ) {
|
||||
this.#strips[ id ].element.remove();
|
||||
delete this.#strips[ id ];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
getATC() {
|
||||
return this.#atc;
|
||||
}
|
||||
@ -71,6 +113,16 @@ export abstract class ATCBoard {
|
||||
}
|
||||
|
||||
|
||||
getStrips() {
|
||||
return this.#strips;
|
||||
}
|
||||
|
||||
|
||||
getStrip( id:string ) {
|
||||
return this.#strips[ id ] || false;
|
||||
}
|
||||
|
||||
|
||||
getTemplate( key:string ) {
|
||||
|
||||
return this.#templates[ key ] || false;
|
||||
@ -115,7 +167,9 @@ export abstract class ATCBoard {
|
||||
|
||||
timeToGo( timestamp:number ) {
|
||||
|
||||
return ( timestamp === -1 ) ? "-" : this.calculateTimeToGo( this.getATC().getMissionDateTime().getTime(), timestamp ).time;
|
||||
const timeData = this.calculateTimeToGo( this.getATC().getMissionDateTime().getTime(), timestamp );
|
||||
|
||||
return ( timestamp === -1 ) ? "-" : timeData.elapsedMarker + timeData.time;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { getMissionData } from "../..";
|
||||
import { Dropdown } from "../../controls/dropdown";
|
||||
import { ATC } from "../atc";
|
||||
import { ATCBoard } from "../atcboard";
|
||||
import { ATCBoard, StripBoardStripInterface } from "../atcboard";
|
||||
|
||||
|
||||
export class ATCBoardFlight extends ATCBoard {
|
||||
@ -83,7 +83,7 @@ export class ATCBoardFlight extends ATCBoard {
|
||||
|
||||
flights.forEach( flight => {
|
||||
|
||||
let strip = stripBoard.querySelector( `[data-flight-id="${flight.id}"]`);
|
||||
let strip = this.getStrip( flight.id );
|
||||
|
||||
if ( !strip ) {
|
||||
|
||||
@ -104,15 +104,20 @@ export class ATCBoardFlight extends ATCBoard {
|
||||
|
||||
stripBoard.insertAdjacentHTML( "beforeend", template );
|
||||
|
||||
strip = <HTMLElement>stripBoard.lastElementChild;
|
||||
|
||||
strip.querySelectorAll( ".ol-select" ).forEach( select => {
|
||||
strip = {
|
||||
"id": flight.id,
|
||||
"element": <HTMLElement>stripBoard.lastElementChild,
|
||||
"dropdowns": {}
|
||||
};
|
||||
|
||||
strip.element.querySelectorAll( ".ol-select" ).forEach( select => {
|
||||
|
||||
switch( select.getAttribute( "data-point" ) ) {
|
||||
|
||||
case "status":
|
||||
|
||||
new Dropdown( select.id, ( value:string, ev:MouseEvent ) => {
|
||||
strip.dropdowns.status = new Dropdown( select.id, ( value:string, ev:MouseEvent ) => {
|
||||
|
||||
fetch( '/api/atc/flight/' + flight.id, {
|
||||
method: 'PATCH',
|
||||
@ -135,10 +140,7 @@ export class ATCBoardFlight extends ATCBoard {
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
strip.querySelectorAll( `input[type="text"]` ).forEach( input => {
|
||||
strip.element.querySelectorAll( `input[type="text"]` ).forEach( input => {
|
||||
|
||||
if ( input instanceof HTMLInputElement ) {
|
||||
|
||||
@ -190,22 +192,26 @@ export class ATCBoardFlight extends ATCBoard {
|
||||
|
||||
});
|
||||
|
||||
this.addStrip( strip );
|
||||
|
||||
} else {
|
||||
|
||||
// TODO: change status dropdown if status is different
|
||||
strip.setAttribute( "data-flight-status", flight.status );
|
||||
if ( flight.status !== strip.element.getAttribute( "data-flight-status" ) ) {
|
||||
strip.element.setAttribute( "data-flight-status", flight.status );
|
||||
strip.dropdowns.status.selectText( flight.status );
|
||||
}
|
||||
|
||||
strip.querySelectorAll( `input[name="takeoffTime"]:not(:focus)` ).forEach( el => {
|
||||
strip.element.querySelectorAll( `input[name="takeoffTime"]:not(:focus)` ).forEach( el => {
|
||||
if ( el instanceof HTMLInputElement ) {
|
||||
el.value = this.timestampToLocaleTime( flight.takeoffTime );
|
||||
el.dataset.previousValue = el.value;
|
||||
}
|
||||
});
|
||||
|
||||
strip.querySelectorAll( `[data-point="timeToGo"]` ).forEach( el => {
|
||||
strip.element.querySelectorAll( `[data-point="timeToGo"]` ).forEach( el => {
|
||||
|
||||
if ( flight.takeoffTime > 0 && this.calculateTimeToGo( missionTime, flight.takeoffTime ).totalSeconds <= 120 ) {
|
||||
strip?.setAttribute( "data-time-warning", "level-1" );
|
||||
strip.element.setAttribute( "data-time-warning", "level-1" );
|
||||
}
|
||||
|
||||
if ( el instanceof HTMLElement ) {
|
||||
@ -217,12 +223,12 @@ export class ATCBoardFlight extends ATCBoard {
|
||||
|
||||
}
|
||||
|
||||
strip.toggleAttribute( "data-updating", false );
|
||||
strip.element.toggleAttribute( "data-updating", false );
|
||||
|
||||
});
|
||||
|
||||
stripBoard.querySelectorAll( `[data-updating]` ).forEach( strip => {
|
||||
strip.remove();
|
||||
this.deleteStrip( strip.getAttribute( "data-flight-id" ) || "" );
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -54,6 +54,15 @@ export class Dropdown {
|
||||
}));
|
||||
}
|
||||
|
||||
selectText( text:string ) {
|
||||
|
||||
const index = [].slice.call( this.#options.children ).findIndex( ( opt:Element ) => opt.querySelector( "button" )?.innerText === text );
|
||||
if ( index > -1 ) {
|
||||
this.selectValue( index );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
selectValue(idx: number)
|
||||
{
|
||||
if (idx < this.#optionsList.length)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div class="ol-panel ol-dialog ol-strip-board" data-feature-switch="atc">
|
||||
<div id="strip-board-ground" class="ol-panel ol-dialog ol-strip-board ol-draggable" data-feature-switch="atc">
|
||||
|
||||
<div class="ol-dialog-close" data-on-click="closeDialog"></div>
|
||||
|
||||
|
||||
@ -50,4 +50,13 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="atc-navbar-control" class="ol-group-container" data-feature-switch="atc">
|
||||
<div class="ol-group-header">ATC</div>
|
||||
<div class="ol-group">
|
||||
<button data-on-click="toggleElements" data-on-click-params='{"selector": "#strip-board-ground"}'>GND</button>
|
||||
<button>TWR</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
Loading…
x
Reference in New Issue
Block a user