Repository: mbta/screens
Pull request #2471: Added support for Pre-fare Solo layout to the Screenplay simulation
Author: login: deanshi
Created: 2025-03-06T22:02:10Z | Merged: 2025-03-07T19:21:53Z

**Asana task**: [Screenplay renaming / support for layout](https://app.asana.com/0/1185117109217413/1209255549956022)

<img width="185" alt="Screenshot 2025-03-06 at 4 59 54 PM" src="https://github.com/user-attachments/assets/e79eb2e1-99fc-44b6-8c76-ab6f8a3f415e" />
<img width="365" alt="Screenshot 2025-03-06 at 5 00 15 PM" src="https://github.com/user-attachments/assets/7304213c-8bdc-4fe2-8770-f8324ffe7591" />

Description
- These changes fix the cut off duo layout too
- [ ] Tests added?



Diff:
diff --git a/assets/css/pre_fare_v2.scss b/assets/css/pre_fare_v2.scss
index 5bc732d3f..03b437c8e 100644
--- a/assets/css/pre_fare_v2.scss
+++ b/assets/css/pre_fare_v2.scss
@@ -60,6 +60,7 @@
 
 @import "v2/simulation_common";
 @import "v2/pre_fare/simulation";
+@import "v2/pre_fare/viewport";
 
 @import "v2/pre_fare/disruption_diagram/disruption_diagram";
 
diff --git a/assets/css/v2/pre_fare/screen_container.scss b/assets/css/v2/pre_fare/screen_container.scss
index 034fdc41b..e560d623a 100644
--- a/assets/css/v2/pre_fare/screen_container.scss
+++ b/assets/css/v2/pre_fare/screen_container.scss
@@ -1,26 +1,6 @@
 .screen-container {
   position: relative;
-  height: 1920px;
   margin: 0 auto;
-  overflow: hidden;
-  // width of a single Pre-Fare display unit; "duo" installations are two of
-  // these side-by-side
-  --panel-width: 1080px;
-
-  &--duo {
-    width: calc(var(--panel-width) * 2);
-  }
-
-  &--left,
-  &--right,
-  &--solo {
-    width: var(--panel-width);
-  }
-
-  &--right > *,
-  &--solo > * {
-    margin-left: calc(var(--panel-width) * -1);
-  }
 }
 
 .screen-container-blink {
diff --git a/assets/css/v2/pre_fare/viewport.scss b/assets/css/v2/pre_fare/viewport.scss
new file mode 100644
index 000000000..e7feecb23
--- /dev/null
+++ b/assets/css/v2/pre_fare/viewport.scss
@@ -0,0 +1,23 @@
+.screen-container,
+.simulation {
+  height: 1920px;
+  overflow: hidden;
+  // width of a single Pre-Fare display unit; "duo" installations are two of
+  // these side-by-side
+  --panel-width: 1080px;
+
+  &--duo {
+    width: calc(var(--panel-width) * 2);
+  }
+
+  &--left,
+  &--right,
+  &--solo {
+    width: var(--panel-width);
+  }
+
+  &--right > *,
+  &--solo > * {
+    margin-left: calc(var(--panel-width) * -1);
+  }
+}
diff --git a/assets/src/components/v2/pre_fare/simulation_screen_container.tsx b/assets/src/components/v2/pre_fare/simulation_screen_container.tsx
index c353f24ed..6bb7e2c07 100644
--- a/assets/src/components/v2/pre_fare/simulation_screen_container.tsx
+++ b/assets/src/components/v2/pre_fare/simulation_screen_container.tsx
@@ -9,6 +9,7 @@ import {
   useSimulationApiResponse,
 } from "Hooks/v2/use_api_response";
 import WidgetTreeErrorBoundary from "Components/v2/widget_tree_error_boundary";
+import { classWithModifier, getScreenSide } from "Util/utils";
 
 interface SimulationScreenLayoutProps {
   apiResponse: ApiResponse;
@@ -43,7 +44,10 @@ const SimulationScreenLayout: ComponentType<SimulationScreenLayoutProps> = ({
         {apiResponse && (
           <div className="simulation__full-page">
             <div className="simulation__title">Live view</div>
-            <div className="simulation" id="simulation">
+            <div
+              className={classWithModifier("simulation", getScreenSide())}
+              id="simulation"
+            >
               <WidgetTreeErrorBoundary>
                 <Widget data={fullPage} />
               </WidgetTreeErrorBoundary>


Reviews:
user: login: digitalcora
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T15:19:09Z
user: login: deanshi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T15:58:08Z
user: login: digitalcora
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T16:00:15Z
user: login: digitalcora
body: Seems good to me though I haven't personally checked the final appearance in Screenplay — doing that would be a good exercise if you haven't already (either pointing your local copy of Screenplay to your local copy of Screens, or deploying this branch to dev-green and looking at Screenplay dev-green).
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T18:33:38Z

Review comments:
diff_hunk: @@ -24,13 +24,40 @@
   .simulation {
     transform: scale(17.92%);
     transform-origin: top left;
+
+    --panel-width: 1080px;
+
+    &--duo {
+      width: calc(var(--panel-width) * 2);
+    }
+
+    &--left,
+    &--right,
+    &--solo {
+      width: var(--panel-width);
+    }
+
+    &--right > *,
+    &--solo > * {
+      margin-left: calc(var(--panel-width) * -1);
+    }
path: assets/css/v2/pre_fare/simulation.scss
user: login: digitalcora
body: Since all this is identical to the rules for `.screen-container` with only the selector being different, can we extract to a shared selector targeted at `.screen-container, .simulation`? This could be in a separate file, though I'm not sure what a good name would be. `pre_fare/viewport`?
created_at: 2025-03-07T15:13:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,13 +24,40 @@
   .simulation {
     transform: scale(17.92%);
     transform-origin: top left;
+
+    --panel-width: 1080px;
+
+    &--duo {
+      width: calc(var(--panel-width) * 2);
+    }
+
+    &--left,
+    &--right,
+    &--solo {
+      width: var(--panel-width);
+    }
+
+    &--right > *,
+    &--solo > * {
+      margin-left: calc(var(--panel-width) * -1);
+    }
   }
 
   .simulation__full-page {
     z-index: 999;
-    max-width: 388px;
     max-height: 407px;
-    margin: 16px;
+
+    --width: 200px;
+
+    &--duo {
+      width: calc(var(--width) * 2);
path: assets/css/v2/pre_fare/simulation.scss
user: login: digitalcora
body: What's the reason we need to set a width on this, separately from `.simulation`? It seems redundant, and fragile (assuming the width set here needs to line up with the width above multiplied by the transform scale, though this is not _quite_ true of the new value you've set it to).
created_at: 2025-03-07T15:17:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,13 +24,40 @@
   .simulation {
     transform: scale(17.92%);
     transform-origin: top left;
+
+    --panel-width: 1080px;
+
+    &--duo {
+      width: calc(var(--panel-width) * 2);
+    }
+
+    &--left,
+    &--right,
+    &--solo {
+      width: var(--panel-width);
+    }
+
+    &--right > *,
+    &--solo > * {
+      margin-left: calc(var(--panel-width) * -1);
+    }
   }
 
   .simulation__full-page {
     z-index: 999;
-    max-width: 388px;
     max-height: 407px;
-    margin: 16px;
+
+    --width: 200px;
+
+    &--duo {
+      width: calc(var(--width) * 2);
path: assets/css/v2/pre_fare/simulation.scss
user: login: deanshi
body: Ah this was leftover code from me trying to fix the issue with the left side and right side pages not showing up as individual items in the simulation.

I was able to get the right side to show up (by changing some filtering and length logic in `simulation_screen_container.tsx`) and this styling was just to handle some of the extra white space due to the solo layout. None of that really for anything more than just me playing around to try and understand the code base.

I eventually took out the code because I wasn't quite sure what the logic of the flex space and the rightScreenPage logic, but I forgot to take this width part out. 
created_at: 2025-03-07T15:58:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -41,9 +42,17 @@ const SimulationScreenLayout: ComponentType<SimulationScreenLayoutProps> = ({
     <div className="simulation-screen-centering-container">
       <div className="simulation-screen-scrolling-container">
         {apiResponse && (
-          <div className="simulation__full-page">
+          <div
+            className={classWithModifier(
+              "simulation__full-page",
+              getScreenSide(),
+            )}
+          >
path: assets/src/components/v2/pre_fare/simulation_screen_container.tsx
user: login: digitalcora
body: The screen-side modifier added to this class is now unused.
created_at: 2025-03-07T16:00:15Z
author_association: CONTRIBUTOR

PR comments:
user: login: deanshi
created_at: 2025-03-07T18:49:34Z
body: > Seems good to me though I haven't personally checked the final appearance in Screenplay — doing that would be a good exercise if you haven't already (either pointing your local copy of Screenplay to your local copy of Screens, or deploying this branch to dev-green and looking at Screenplay dev-green).

Good call - let me push to dev-green real quick and see if it looks good. I looked at things locally but I think it'd make me feel better if it was on a dev environment without my weird local config stuff. 
author_association: CONTRIBUTOR
user: login: deanshi
created_at: 2025-03-07T19:05:09Z
body: screenplay dev-green is looking good, no more cut off simulation, going to get this merged in!
author_association: CONTRIBUTOR