Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(a380/mfd): status and switching page #9362

Merged
merged 8 commits into from
Nov 16, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
1. [A380X/EFB] Fixed doors automatically opening in flight - @saschl (saschl)
1. [A380X/FMS] Fixed layouting issue on FMS/ACTIVE/PERF/T.O page for some users - @flogross89 (floridude)
1. [A380X/TELEX] Added popup for telex consent @saschl (saschl) @Maximilian-Reuter (\_chaoz)
1. [A380X/FMS] Added SURV Status & Switching page with TCAS fault indication - @Frenkii (Moritz)

## 0.12.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { MfdDisplayInterface } from 'instruments/src/MFD/MFD';
import { MfdUiService } from 'instruments/src/MFD/pages/common/MfdUiService';
import { MfdFmsDataDebug } from 'instruments/src/MFD/pages/FMS/DATA/MfdFmsDataDebug';
import { MfdSurvControls } from 'instruments/src/MFD/pages/SURV/MfdSurvControls';
import { MfdSurvStatusSwitching } from 'instruments/src/MFD/pages/SURV/MfdSurvStatusSwitching';

export function pageForUrl(
url: string,
Expand Down Expand Up @@ -92,6 +93,8 @@ export function pageForUrl(
return <MfdFmsDataDebug pageTitle="DEBUG" bus={bus} mfd={mfd} fmcService={fmcService} />;
case 'surv/controls':
return <MfdSurvControls pageTitle="CONTROLS" bus={bus} mfd={mfd} fmcService={fmcService} />;
case 'surv/status-switching':
return <MfdSurvStatusSwitching pageTitle="STATUS & SWITCHING" bus={bus} mfd={mfd} fmcService={fmcService} />;

default:
return <MfdNotFound pageTitle="NOT FOUND" bus={bus} mfd={mfd} fmcService={fmcService} />;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@import "../../../MsfsAvionicsCommon/definitions.scss";


.sys-box {
border: 1px solid $display-light-grey;
padding: 10px;
padding-top: 50px;
width: 270px;
position: relative;
}

.sys-box.active {
border: 1px solid $display-green;
}

.sys-group {
border: 1px solid $display-light-grey;
padding: 5px;
}

.sys-group.active {
border: 1px solid $display-green;
}

.sys-group.failed {
border: 1px solid $display-amber;
}

.sys-status-item.failed {
color: $display-amber;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
import { ConsumerSubject, DisplayComponent, FSComponent, Subject, Subscription, VNode } from '@microsoft/msfs-sdk';

import './MfdSurvStatusSwitching.scss';

import { MfdSurvEvents } from 'instruments/src/MsfsAvionicsCommon/providers/MfdSurvPublisher';
import { ActivePageTitleBar } from 'instruments/src/MFD/pages/common/ActivePageTitleBar';
import { AbstractMfdPageProps } from 'instruments/src/MFD/MFD';
import { Footer } from 'instruments/src/MFD/pages/common/Footer';
import { MfdSimvars } from 'instruments/src/MFD/shared/MFDSimvarPublisher';
import { SurvStatusButton } from 'instruments/src/MFD/pages/common/SurvStatusButton';
import { SurvStatusItem } from 'instruments/src/MFD/pages/common/SurvStatusItem';

interface MfdSurvStatusSwitchingProps extends AbstractMfdPageProps {}

export enum StatusItemState {
Off = 0,
On = 1,
Failed = 2,
}

export class MfdSurvStatusSwitching extends DisplayComponent<MfdSurvStatusSwitchingProps> {
// Make sure to collect all subscriptions here, otherwise page navigation doesn't work.
private subs = [] as Subscription[];

private readonly sub = this.props.bus.getSubscriber<MfdSimvars & MfdSurvEvents>();

private readonly tcas1Failed = ConsumerSubject.create(this.sub.on('tcasFail'), true);

private readonly wxr1Failed = Subject.create<boolean>(false);

private readonly turb1Failed = Subject.create<boolean>(false);

private readonly predWs1Failed = Subject.create<boolean>(false);

private readonly xpdr1Failed = Subject.create<boolean>(false);

private readonly terr1Failed = Subject.create<boolean>(false);

private readonly gpws1Failed = Subject.create<boolean>(false);

private readonly wxr2Failed = Subject.create<boolean>(false);

private readonly turb2Failed = Subject.create<boolean>(false);

private readonly predWs2Failed = Subject.create<boolean>(false);

private readonly terr2Failed = Subject.create<boolean>(false);

private readonly gpws2Failed = Subject.create<boolean>(false);

private readonly xpdr2Failed = Subject.create<boolean>(false);

private readonly tcas2Failed = Subject.create<boolean>(false);

private readonly activeSystemGroupXpdrTcas = Subject.create<number>(1);

private readonly activeSystemGroupXpdr = Subject.create<number>(1);

private readonly activeSystemGroupTcas = Subject.create<number>(1);

public onAfterRender(node: VNode): void {
super.onAfterRender(node);
}

public destroy(): void {
// Destroy all subscriptions to remove all references to this instance.
this.subs.forEach((x) => x.destroy());

super.destroy();
}

render(): VNode {
return (
<>
<ActivePageTitleBar
activePage={Subject.create('STATUS & SWITCHING')}
offset={Subject.create('')}
eoIsActive={Subject.create(false)}
tmpyIsActive={Subject.create(false)}
/>
{/* begin page content */}
<div class="mfd-page-container">
<div style="width: 100%; display: flex; flex-direction: row; justify-content: space-between; align-items: top; padding: 50px;">
{/* upper left sys box */}
<div class="sys-box">
<SurvStatusButton
label={'SYS 1'}
active={Subject.create(true)}
onClick={() => console.log('button clicked')}
/>
<div
class={{
'sys-group': true,
active: Subject.create(true),
}}
style="margin-bottom: 10px;"
>
<SurvStatusItem
label={'WXR DISPLAY'}
sys={'1'}
active={true}
failed={this.wxr1Failed}
style={'margin-bottom: 10px;'}
/>
<SurvStatusItem
label={'TURB'}
sys={'1'}
active={true}
failed={this.turb1Failed}
style={'margin-bottom: 10px;'}
/>
<SurvStatusItem label={'PRED W/S'} sys={'1'} active={true} failed={this.predWs1Failed} />
</div>
<div class={{ 'sys-group': true, active: Subject.create(true) }}>
<SurvStatusItem
label={'TERR SYS'}
sys={'1'}
active={true}
failed={this.terr1Failed}
style={'margin-bottom: 10px;'}
/>
<SurvStatusItem label={'GPWS'} sys={'1'} active={true} failed={this.gpws1Failed} />
</div>
</div>
{/* upper middle text */}
<div style="text-align: center;">
<div class="mfd-label bigger" style="margin-top: 55px;">
WXR
</div>
<div class="mfd-label bigger" style="margin-top: 90px;">
TAWS
</div>
</div>
{/* upper right sys box */}
<div class="sys-box">
<SurvStatusButton
label={'SYS 2'}
active={Subject.create(false)}
onClick={() => console.log('button clicked')}
/>
<div
class={{
'sys-group': true,
active: Subject.create(false),
}}
style="margin-bottom: 10px;"
>
<SurvStatusItem
label={'WXR DISPLAY'}
sys={'2'}
active={false}
failed={this.wxr2Failed}
style={'margin-bottom: 10px;'}
/>
<SurvStatusItem
label={'TURB'}
sys={'2'}
active={false}
failed={this.turb2Failed}
style={'margin-bottom: 10px;'}
/>
<SurvStatusItem label={'PRED W/S'} sys={'2'} active={false} failed={this.predWs2Failed} />
</div>
<div class={{ 'sys-group': true, active: Subject.create(false) }}>
<SurvStatusItem
label={'TERR SYS'}
sys={'2'}
active={false}
failed={this.terr2Failed}
style={'margin-bottom: 10px;'}
/>
<SurvStatusItem label={'GPWS'} sys={'2'} active={false} failed={this.gpws2Failed} />
</div>
</div>
</div>
{/* lower line */}
<div style="width: 100%; display: flex; flex-direction: row; justify-content: space-between; align-items: top; padding: 50px;">
{/* lower left sys box */}
<div class="sys-box">
<SurvStatusButton label={'SYS 1'} active={Subject.create(this.activeSystemGroupXpdrTcas.get() === 1)} />
<div
class={{ 'sys-group': true, active: Subject.create(this.activeSystemGroupXpdr.get() === 1) }}
style="margin-bottom: 5px;"
>
<SurvStatusItem label={'XPDR'} sys={'1'} active={true} failed={this.xpdr1Failed} />
</div>
<div class={{ 'sys-group': true, active: Subject.create(this.activeSystemGroupTcas.get() === 1) }}>
<SurvStatusItem label={'TCAS'} sys={'1'} active={true} failed={this.tcas1Failed} />
</div>
</div>
{/* lower middle text */}
<div style="text-align: center;">
<div class="mfd-label bigger" style="margin-top: 55px;">
XPDR
</div>
<div class="mfd-label bigger" style="margin-top: 20px;">
TCAS
</div>
</div>
{/* lower right sys box */}
<div class="sys-box">
<SurvStatusButton
label={'SYS 2'}
active={Subject.create(false)}
onClick={() => console.log('button clicked')}
/>
<div
class={{ 'sys-group': true, active: Subject.create(this.activeSystemGroupXpdr.get() === 2) }}
style="margin-bottom: 5px;"
>
<SurvStatusItem label={'XPDR'} sys={'2'} active={false} failed={this.xpdr2Failed} />
</div>
<div class={{ 'sys-group': true, active: Subject.create(this.activeSystemGroupTcas.get() === 2) }}>
<SurvStatusItem label={'TCAS'} sys={'2'} active={false} failed={this.tcas2Failed} />
</div>
</div>
</div>
</div>
{/* end page content */}
<Footer bus={this.props.bus} mfd={this.props.mfd} fmcService={this.props.fmcService} />
</>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { ComponentProps, DisplayComponent, FSComponent, Subscribable, Subscription, VNode } from '@microsoft/msfs-sdk';
import './style.scss';

export interface SurvStatusButtonProps extends ComponentProps {
label: string;
active: Subscribable<boolean>;
onChanged?(val: boolean): void;
onClick?: () => void;
}

/*
* Button for MFD pages. If menuItems is set, a dropdown menu will be displayed when button is clicked
*/
export class SurvStatusButton extends DisplayComponent<SurvStatusButtonProps> {
// Make sure to collect all subscriptions here, otherwise page navigation doesn't work.
private subs = [] as Subscription[];

private buttonRef = FSComponent.createRef<HTMLSpanElement>();

private clickHandler(): void {
console.log(this.props.label + 'button clicked');
}

public onAfterRender(node: VNode): void {
super.onAfterRender(node);

this.buttonRef.instance.addEventListener('click', () => this.clickHandler());
}

public destroy(): void {
// Destroy all subscriptions to remove all references to this instance.
this.subs.forEach((x) => x.destroy());

super.destroy();
}

public render(): VNode {
return (
<div ref={this.buttonRef} class="mfd-surv-status-button">
<div style="padding-left: 7px; padding-right: 7px; height: 50%; background-color: black; display: flex; flex-direction: column; justify-content: space-evenly;">
<div class={{ 'mfd-surv-status-indicator': true, active: this.props.active }}></div>
<div class={{ 'mfd-surv-status-indicator': true, active: this.props.active }}></div>
<div class={{ 'mfd-surv-status-indicator': true, active: this.props.active }}></div>
</div>
<p class="mfd-surv-status-button-label">{this.props.label}</p>
</div>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { ComponentProps, DisplayComponent, FSComponent, Subscribable, Subscription, VNode } from '@microsoft/msfs-sdk';
import './style.scss';

export interface SurvStatusItemProps extends ComponentProps {
label: string;
active: boolean;
failed: Subscribable<boolean>;
sys: string;
style?: string;
onChanged?(val: boolean): void;
}

/*
* Button for MFD pages. If menuItems is set, a dropdown menu will be displayed when button is clicked
*/
export class SurvStatusItem extends DisplayComponent<SurvStatusItemProps> {
// Make sure to collect all subscriptions here, otherwise page navigation doesn't work.
private subs = [] as Subscription[];

public onAfterRender(node: VNode): void {
super.onAfterRender(node);
}

public destroy(): void {
// Destroy all subscriptions to remove all references to this instance.
this.subs.forEach((x) => x.destroy());

super.destroy();
}

public render(): VNode {
return (
<div
style={this.props.style}
class={{
'mfd-surv-status-item': true,
active: this.props.active,
failed: this.props.failed,
}}
>
{this.props.label} {this.props.active ? this.props.sys : 'OFF'}
</div>
);
}
}
Loading