Schedule graphical CCS procedures

This commit is contained in:
hz
2026-08-14 17:54:03 -05:00
parent 375b3ea62f
commit 25c2188264
7 changed files with 204 additions and 26 deletions
+104 -12
View File
@@ -88,10 +88,16 @@ var orders_status: Label
var order_search_timer: Timer
var staged_order_codes: Array[String] = []
var order_names := {}
var order_options := {}
var final_orders_mode := false
var active_order_codes: Array = []
var current_order_location := ""
var current_order_minute := 0
var known_order_result_count := -1
var known_visit_completions: Array[String] = []
var visit_completion_tracking_ready := false
var patient_update_panel: PanelContainer
var patient_update_text: Label
var experience_mode := "management"
var pending_choices: Array = []
var available_choices: Array = []
@@ -132,6 +138,7 @@ func _ready() -> void:
_style_desktop_shortcut(orders_launcher)
_build_medical_history_tabs()
_build_orders_window()
_build_patient_update()
_resize_computer_windows()
_update_clock()
_schedule_patient_blink()
@@ -315,6 +322,8 @@ func complete_response_transition() -> void:
func _input(event: InputEvent) -> void:
if patient_update_panel != null and patient_update_panel.visible:
return
if computer_overlay.visible or (physical_exam_panel != null and physical_exam_panel.visible):
return
if _event_targets_computer_launcher(event):
@@ -370,6 +379,9 @@ func is_computer_open() -> bool:
func close_transient_overlay() -> bool:
if patient_update_panel != null and patient_update_panel.visible:
patient_update_panel.visible = false
return true
if physical_exam_panel != null and physical_exam_panel.visible:
if physical_exam_result_button.visible:
_close_exam_result()
@@ -591,22 +603,29 @@ func _queue_live_order_search(query: String) -> void:
func render_order_search(rows: Array) -> void:
_clear_dynamic_children(orders_search_results)
var available_count := 0
var result_count := 0
for raw_order in rows:
var order: Dictionary = raw_order
var locations: Array = order.get("availableLocations", [])
if not locations.is_empty() and current_order_location not in locations:
continue
available_count += 1
result_count += 1
var code := str(order.get("code", ""))
order_names[code] = str(order.get("canonicalName", code.capitalize()))
var option: Dictionary = order_options.get(code, {})
var configured := not option.is_empty()
var button := Button.new()
button.text = "%s · %s" % [order_names[code], str(order.get("category", "")).capitalize()]
var detail := str(order.get("category", "")).capitalize()
if configured:
var location := _humanize_order_location(str(option.get("performanceLocation", current_order_location)))
var delay := int(option.get("turnaroundMinutes", 0))
detail += " - %s%s" % [location, " - %d min" % delay if delay > 0 else ""]
else:
detail += " - Unavailable in this case"
button.text = "%s\n%s" % [order_names[code], detail]
button.alignment = HORIZONTAL_ALIGNMENT_LEFT
button.disabled = code in staged_order_codes or code in active_order_codes
button.disabled = not configured or code in staged_order_codes or code in active_order_codes
button.tooltip_text = "This order is not configured for this case." if not configured else ""
button.pressed.connect(_stage_order.bind(code))
orders_search_results.add_child(button)
orders_status.text = "" if available_count > 0 else "No matching orders are available at this location."
orders_status.text = "" if result_count > 0 else "No matching orders found."
func _stage_order(code: String) -> void:
@@ -622,7 +641,9 @@ func _render_staged_orders() -> void:
var row := HBoxContainer.new()
orders_staged.add_child(row)
var label := Label.new()
label.text = str(order_names.get(code, code.capitalize()))
var option: Dictionary = order_options.get(code, {})
var location := _humanize_order_location(str(option.get("performanceLocation", current_order_location)))
label.text = "%s - %s" % [str(order_names.get(code, code.capitalize())), location]
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
row.add_child(label)
var remove := Button.new()
@@ -647,12 +668,18 @@ func configure_orders(attempt: Dictionary) -> void:
if orders_window == null:
return
current_order_location = str(attempt.get("location", ""))
current_order_minute = int(attempt.get("simulatedMinute", 0))
order_options.clear()
for raw_option in attempt.get("orderOptions", []):
var option: Dictionary = raw_option
order_options[str(option.get("code", ""))] = option
active_order_codes = attempt.get("activeOrderCodes", []).duplicate()
for code in attempt.get("activeOrderCodes", []):
staged_order_codes.erase(str(code))
_render_staged_orders()
_render_active_orders(attempt.get("activeOrders", []))
_render_order_results(attempt.get("chart", []))
_track_patient_visit_completions(attempt.get("chart", []))
var result_count := _order_result_count(attempt.get("chart", []))
if known_order_result_count >= 0 and result_count > known_order_result_count and not orders_window.visible:
orders_launcher.get_node("Label").text = "Orders •"
@@ -676,13 +703,13 @@ func show_order_action_complete(action: String) -> void:
match action:
"orders":
orders_tabs.current_tab = 1
orders_status.text = "Orders confirmed. Use Obtain Results for pending tests."
orders_status.text = "Orders confirmed and automatically scheduled. Use Obtain Results to advance time."
"cancel_order":
orders_tabs.current_tab = 1
orders_status.text = "Order cancelled."
"advance":
orders_tabs.current_tab = 2
orders_status.text = "The chart has been updated with all results now available."
orders_status.text = "Simulated time advanced. Newly available results are shown here."
func _render_active_orders(rows: Array) -> void:
@@ -697,7 +724,12 @@ func _render_active_orders(rows: Array) -> void:
var row := HBoxContainer.new()
orders_active.add_child(row)
var label := Label.new()
label.text = "%s — %s, %s" % [str(order.get("name", "Order")), str(order.get("route", "")), str(order.get("frequency", ""))]
var status := str(order.get("status", "active")).capitalize()
var location := _humanize_order_location(str(order.get("performanceLocation", current_order_location)))
var due_text := ""
if order.get("dueMinute", null) != null:
due_text = " - due in %d min" % maxi(0, int(order.get("dueMinute", 0)) - current_order_minute)
label.text = "%s - %s at %s%s" % [str(order.get("name", "Order")), status, location, due_text]
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
row.add_child(label)
var cancel := Button.new()
@@ -723,6 +755,66 @@ func _order_result_count(chart: Array) -> int:
return count
func _humanize_order_location(value: String) -> String:
if value.is_empty():
return "Current location"
return value.replace("_", " ").capitalize()
func _build_patient_update() -> void:
patient_update_panel = PanelContainer.new()
patient_update_panel.name = "PatientProcedureUpdate"
patient_update_panel.visible = false
patient_update_panel.z_index = 100
patient_update_panel.position = Vector2(400, 300)
patient_update_panel.custom_minimum_size = Vector2(800, 0)
add_child(patient_update_panel)
var margin := MarginContainer.new()
margin.add_theme_constant_override("margin_left", 24)
margin.add_theme_constant_override("margin_right", 24)
margin.add_theme_constant_override("margin_top", 18)
margin.add_theme_constant_override("margin_bottom", 18)
patient_update_panel.add_child(margin)
var content := VBoxContainer.new()
content.add_theme_constant_override("separation", 12)
margin.add_child(content)
var heading := Label.new()
heading.text = "Patient Update"
heading.add_theme_font_size_override("font_size", 24)
content.add_child(heading)
patient_update_text = Label.new()
patient_update_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
patient_update_text.add_theme_font_size_override("font_size", 18)
content.add_child(patient_update_text)
var dismiss := Button.new()
dismiss.text = "Continue"
dismiss.custom_minimum_size = Vector2(140, 44)
dismiss.size_flags_horizontal = Control.SIZE_SHRINK_END
dismiss.pressed.connect(func() -> void: patient_update_panel.visible = false)
content.add_child(dismiss)
func _track_patient_visit_completions(chart: Array) -> void:
var current: Array[String] = []
var new_messages: Array[String] = []
for raw_entry in chart:
var entry: Dictionary = raw_entry
var code := str(entry.get("code", ""))
if str(entry.get("category", "")) != "progress" or not code.ends_with("_completed"):
continue
var key := "%s:%d" % [code, int(entry.get("simulatedMinute", 0))]
current.append(key)
if visit_completion_tracking_ready and key not in known_visit_completions:
new_messages.append(str(entry.get("text", "The patient completed a scheduled procedure and returned.")))
known_visit_completions = current
if not visit_completion_tracking_ready:
visit_completion_tracking_ready = true
return
if not new_messages.is_empty():
patient_update_text.text = "\n".join(new_messages) + "\nNew results are available in the computer."
patient_update_panel.visible = true
func set_orders_pending(pending: bool, message: String = "") -> void:
orders_confirm_button.disabled = pending or staged_order_codes.is_empty()
orders_advance_button.disabled = pending