-
Notifications
You must be signed in to change notification settings - Fork 11
Feature/interface signaller UI #1076
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
base: dev
Are you sure you want to change the base?
Feature/interface signaller UI #1076
Conversation
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, my review as far as I've gotten today.
// ESLint seems to be wrong here. Without the type assertion, we receive an ExerciseSimulationBehaviorState | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion | ||
const reportBehavior = selectStateSnapshot( | ||
createSelectBehaviorState( | ||
this.simulatedRegionId, | ||
this.reportBehaviorId | ||
), | ||
this.store | ||
) as ReportBehaviorState; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use this instead:
// ESLint seems to be wrong here. Without the type assertion, we receive an ExerciseSimulationBehaviorState | |
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion | |
const reportBehavior = selectStateSnapshot( | |
createSelectBehaviorState( | |
this.simulatedRegionId, | |
this.reportBehaviorId | |
), | |
this.store | |
) as ReportBehaviorState; | |
const reportBehavior = selectStateSnapshot( | |
createSelectBehaviorState<ReportBehaviorState>( | |
this.simulatedRegionId, | |
this.reportBehaviorId | |
), | |
this.store | |
); |
This should in theory be done to all calls to createSelectBehaviorState
as its B
generic parameter can never be inferred from usage. But this should not be something for this PR, I think.
By the way, createSelectBehaviorState
has a weird contract: It allows you to pass in any B extends ExerciseSimulationBehaviorState
but filters for a condition unrelated (at the surface at least) to B
, simply assuming the resulting element is a B
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggested fix! I've added it in 255fcd5
I understand why you think the contract is weird, but I claim that it makes sense given how I expect the selector to be used: If I got a UUID and know from the context what type of behavior to expect, I wouldn't check the type again, but just assume it (i.e., perform a type cast). So I'd rather keep this shorthand way of doing it
@@ -0,0 +1,5 @@ | |||
# EOC Information | |||
|
|||
TODO: It would be better if the EOC could sent radiograms for requested information, too. However, radiograms must have a SimulatedRegion they're sent by and refactoring this would have been too much work at least for now. Therefore, information requested from the EOC will be shown in the details modal instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider opening an issue for this and link it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved to #1093
<app-hotkey-indicator keys="Leertaste" />: Aktuelles Steuerelement | ||
an-/ausschalten | ||
<br /> | ||
<app-hotkey-indicator keys="Tab" />: Nächstes Steuerelement auswählen | ||
<br /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are also shown when there are no elements to select or toggle, e.g. in the sent alarm groups dialog. Maybe there is a way to check whether there is anything meaningful to tab through.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice suggestion, implemented in 9b8e6cd
} | ||
} | ||
|
||
public updateInterval(newInterval: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please document which unit is expected here, e.g. by renaming the parameter to newIntervalMinutes
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in 24d684f
requiredBehaviors: ['transferBehavior'], | ||
errorMessage: 'Dieser Bereich kann keine Fahrzeuge bereitstellen', | ||
}, | ||
// TODO: Radio channels |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO for this PR?
hotkey: new Hotkey('2', true, () => | ||
this.editTransferPatientTrays() | ||
), | ||
requiredBehaviors: ['managePatientTransportToHospitalBehavior'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a little weird that these requiredBehaviors
are defined twice: Once here, and again in the *ngIf
of the respective ng-template
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, but I don't know how to resolve this. In the HTML template, I need the *ngIf
to resolve the observable to a specific value to pass it as input into the component and in the TypeScript code, I need the array of required behaviors to en-/disable the button and hotkey to show some user feedback before the user actually clicked on the button.
What I could do:
- Change
*ngIf
to*appLet
so that it does not look like a condition (however, it basically does the same in the end) - Remove the templates showing an error message for the
else
branch, as it should never be visible due to the checks in the code behind.
But the general issue of duplication remains. Even if I only pass the ID of the region into the subcomponents, the required behaviors would still be checked twice (once in the current commands component and once in each of the subcomponents).
Do you have a suggestion how to handle this?
hotkey: new Hotkey('A', false, () => this.requestPatientCount()), | ||
secondaryHotkey: new Hotkey('⇧ + A', true, () => | ||
this.openRecurringReportModal('patientCount') | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like some kind of unification would be good here. Currently, the modal type is declared twice, once in the secondary hotkey and once in the function called by the hotkey. Also, these calls are more or less identical between the different interactions. However, I'm also not sure how this could be unified in a reasonable way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the only way to simplify/deduplicate this would be to define an additional, reduced data model and then build the full data model from this definition. However, this feels like overall adding more overhead and complexity due to the additional indirection…
errorMessage: 'Dieser Bereich behandelt keine Patienten', | ||
loading$: new BehaviorSubject<boolean>(false), | ||
}, | ||
// TODO: Location |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO for this PR? Also for the two TODO
s below.
get filteredInteractions() { | ||
const lowerFilter = this.filter.toLowerCase(); | ||
|
||
return this.interactions.filter( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a little weird in the sense that you cannot filter by multiple phrases by entering multiple words. Maybe you could split the lowerFilter
in whitespace and then require that all parts match, each using the existing filter logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice idea, added in 9b6fa4d
Co-authored-by: Clemens <[email protected]> Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
Signed-off-by: Lukas Radermacher <[email protected]>
This PR adds a new modal that allows interface signallers to interact with the software
PR Checklist
Please make sure to fulfil the following conditions before marking this PR ready for review:
own code or code licensed under a license compatible to AGPL v3.0 or later, for exceptions look into LICENSE-README.md) and
hereby license the code in this Pull Request under it.
I certify that by signing off my commits (see In case of using third party code, I have given appropriate credit.
We are using DCO for that, see here for more information.