Skip to content

Commit 1bd90d4

Browse files
author
Greg Trihus
committed
TT-6814-17, TT-6428 Add Phrase Back Translation mobile layout
- Introduced Cypress component testing takeaways to guide best practices in testing setups and assertions. - Added Jest testing takeaways for unit tests, emphasizing mocking strategies and edge case coverage. - Refactored MediaRecord, WSAudioPlayer, and related components to improve props handling and mobile responsiveness. - Updated UserMenu and PlanTabs components to utilize new mobile utility functions for better layout management. TT-6814-17, TT-6428 Add Phrase Back Translation mobile layout - Introduced Cypress component testing takeaways to guide best practices in testing setups and assertions. - Added Jest testing takeaways for unit tests, emphasizing mocking strategies and edge case coverage. - Refactored MediaRecord, WSAudioPlayer, and related components to improve props handling and mobile responsiveness. - Updated UserMenu and PlanTabs components to utilize new mobile utility functions for better layout management. - feedback fixes Highlight and play segment logic
1 parent 39163a7 commit 1bd90d4

File tree

61 files changed

+4216
-521
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+4216
-521
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
description: Cypress component test takeaways for this repo
3+
alwaysApply: true
4+
---
5+
6+
# Cypress Component Testing Takeaways
7+
8+
- Avoid stubbing ESM imports in Cypress CT; prefer data-driven setup via providers.
9+
- Build the full provider stack: `GlobalProvider`, Redux store, `OrbitContext`,
10+
and any feature contexts (e.g. `PassageDetailContext`, `UnsavedContext`).
11+
- For permission logic (`useStepPermissions`), drive outcomes with real mock records and relationships.
12+
- Localization selectors need `LocalizedStrings` in the correct `strings` slice keys.
13+
- Use stable DOM selectors (ids/data-cy) for assertions.
14+
- When testing navigation that uses `usePassageNavigate`, include a `MemoryRouter`
15+
- `Routes` and stub `UnsavedContext.checkSavedFn` to run immediately.
16+
- `nextPasId`/`prevPasId` depend on `section.relationships.passages` and
17+
`memory` records; empty relationships mean no neighbors.
18+
- `WorkflowStepsMobile` renders SVG stages (no visible text nodes). Assert on
19+
structure (`svg`, `svg g`) or wrapper labels, not `cy.contains` on step names.
20+
- `WorkflowStepsMobile` depends on `workflow`/`currentstep` from context; keep
21+
defaults intact when overriding to avoid empty steps.
22+
- For `WorkflowStepsMobile`, set viewport and dispatch a `resize` after mount so
23+
the width-driven step list is computed.
24+
- When testing busy/recording state, assert via `setCurrentStep` calls and snack
25+
messages rather than DOM class changes.
26+
- Pagination needs enough steps and a small viewport to expose `prev`/`next`.
27+
- Run the component spec and iterate on failures:
28+
- `cd src\renderer`
29+
- `npm run cy:run-ct -- --spec=**/YourComponent.cy.tsx`
30+
31+
## Example: Minimal Strings Slice
32+
33+
```ts
34+
const mockStringsReducer = () => ({
35+
loaded: true,
36+
lang: 'en',
37+
passageDetailStepComplete: new LocalizedStrings({
38+
en: { title: 'Complete' },
39+
}),
40+
});
41+
```
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
description: Jest testing takeaways for this repo
3+
alwaysApply: true
4+
---
5+
6+
# Jest Testing Takeaways
7+
8+
- Favor unit tests for non-React modules (pure functions, CRUD helpers).
9+
- Mock Orbit helpers (`related`, `findRecord`) and other dependencies; keep test data minimal.
10+
- Cover edge cases: missing relationships, missing current id, filtering, wrap-around.
11+
- Prefer deterministic sorting in tests (explicit `sequencenum`).
12+
- Use `--runInBand --watchAll=false` to avoid hanging runs in CI/automation.
13+
14+
## Running a New Jest Test Module
15+
16+
Run Jest from `src/renderer` (required for this repo).
17+
18+
```bash
19+
cd src/renderer
20+
npm test -- <moduleName> --runInBand --watchAll=false
21+
```

localization/TranscriberAdmin-en-1.2.xliff

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5211,6 +5211,56 @@
52115211
<context context-type="sourcefile">MediaUpload.tsx</context>
52125212
</context-group>
52135213
</trans-unit>
5214+
<trans-unit id="mobile.addSegment">
5215+
<source>Add segment boundary</source>
5216+
<target/>
5217+
<context-group>
5218+
<context context-type="sourcefile">SegmentControlIsMobile.tsx</context>
5219+
</context-group>
5220+
</trans-unit>
5221+
<trans-unit id="mobile.next">
5222+
<source>Next</source>
5223+
<target/>
5224+
<context-group>
5225+
<context context-type="sourcefile">PassageDetailMobileFooter.tsx</context>
5226+
</context-group>
5227+
</trans-unit>
5228+
<trans-unit id="mobile.previous">
5229+
<source>Previous</source>
5230+
<target/>
5231+
<context-group>
5232+
<context context-type="sourcefile">PassageDetailMobileFooter.tsx</context>
5233+
</context-group>
5234+
</trans-unit>
5235+
<trans-unit id="mobile.removeSegment">
5236+
<source>Remove next segment boundary</source>
5237+
<target/>
5238+
<context-group>
5239+
<context context-type="sourcefile">SegmentControlIsMobile.tsx</context>
5240+
</context-group>
5241+
</trans-unit>
5242+
<trans-unit id="mobile.resetBT">
5243+
<source>Reset back translation</source>
5244+
<target/>
5245+
<context-group>
5246+
<context context-type="sourcefile">SegmentControlIsMobile.tsx</context>
5247+
</context-group>
5248+
</trans-unit>
5249+
<trans-unit id="mobile.restoreBoundaries">
5250+
<source>Restore original segment boundaries</source>
5251+
<target/>
5252+
<context-group>
5253+
<context context-type="sourcefile">SegmentControlIsMobile.tsx</context>
5254+
</context-group>
5255+
</trans-unit>
5256+
<trans-unit id="mobile.segment">
5257+
<source>Segment: {0}</source>
5258+
<target/>
5259+
<context-group>
5260+
<context context-type="sourcefile">SegmentControlIsMobile.tsx</context>
5261+
</context-group>
5262+
</trans-unit>
5263+
52145264
<trans-unit id="newProject.audioProduct">
52155265
<source>Audio Product</source>
52165266
<target/>
@@ -7480,6 +7530,27 @@
74807530
<context context-type="sourcefile">ResourceOverview.tsx</context>
74817531
</context-group>
74827532
</trans-unit>
7533+
<trans-unit id="recordButton.record">
7534+
<source>RECORD</source>
7535+
<target/>
7536+
<context-group>
7537+
<context context-type="sourcefile">RecordButton.tsx</context>
7538+
</context-group>
7539+
</trans-unit>
7540+
<trans-unit id="recordButton.rerecord">
7541+
<source>RERECORD</source>
7542+
<target/>
7543+
<context-group>
7544+
<context context-type="sourcefile">RecordButton.tsx</context>
7545+
</context-group>
7546+
</trans-unit>
7547+
<trans-unit id="recordButton.resume">
7548+
<source>RESUME</source>
7549+
<target/>
7550+
<context-group>
7551+
<context context-type="sourcefile">RecordButton.tsx</context>
7552+
</context-group>
7553+
</trans-unit>
74837554
<trans-unit id="recordStepSettings.custom">
74847555
<source>Custom</source>
74857556
<target/>
@@ -11010,6 +11081,13 @@
1101011081
<context context-type="sourcefile">wsAudioPlayer.tsx</context>
1101111082
</context-group>
1101211083
</trans-unit>
11084+
<trans-unit id="wsAudioPlayer.reset">
11085+
<source>Reset</source>
11086+
<target/>
11087+
<context-group>
11088+
<context context-type="sourcefile">wsAudioPlayer.tsx</context>
11089+
</context-group>
11090+
</trans-unit>
1101311091
<trans-unit id="wsAudioPlayer.resume">
1101411092
<source>Resume</source>
1101511093
<target/>

localization/TranscriberAdmin-en.xlf

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4468,6 +4468,48 @@
44684468
<target/>
44694469
</segment>
44704470
</unit>
4471+
<unit id="mobile.addSegment">
4472+
<segment>
4473+
<source>Add segment boundary</source>
4474+
<target/>
4475+
</segment>
4476+
</unit>
4477+
<unit id="mobile.next">
4478+
<segment>
4479+
<source>Next</source>
4480+
<target/>
4481+
</segment>
4482+
</unit>
4483+
<unit id="mobile.previous">
4484+
<segment>
4485+
<source>Previous</source>
4486+
<target/>
4487+
</segment>
4488+
</unit>
4489+
<unit id="mobile.removeSegment">
4490+
<segment>
4491+
<source>Remove next segment boundary</source>
4492+
<target/>
4493+
</segment>
4494+
</unit>
4495+
<unit id="mobile.resetBT">
4496+
<segment>
4497+
<source>Reset back translation</source>
4498+
<target/>
4499+
</segment>
4500+
</unit>
4501+
<unit id="mobile.restoreBoundaries">
4502+
<segment>
4503+
<source>Restore original segment boundaries</source>
4504+
<target/>
4505+
</segment>
4506+
</unit>
4507+
<unit id="mobile.segment">
4508+
<segment>
4509+
<source>Segment: {0}</source>
4510+
<target/>
4511+
</segment>
4512+
</unit>
44714513
<unit id="newProject.audioProduct">
44724514
<segment>
44734515
<source>Audio Product</source>
@@ -6412,6 +6454,24 @@
64126454
<target/>
64136455
</segment>
64146456
</unit>
6457+
<unit id="recordButton.record">
6458+
<segment>
6459+
<source>RECORD</source>
6460+
<target/>
6461+
</segment>
6462+
</unit>
6463+
<unit id="recordButton.rerecord">
6464+
<segment>
6465+
<source>RERECORD</source>
6466+
<target/>
6467+
</segment>
6468+
</unit>
6469+
<unit id="recordButton.resume">
6470+
<segment>
6471+
<source>RESUME</source>
6472+
<target/>
6473+
</segment>
6474+
</unit>
64156475
<unit id="recordStepSettings.custom">
64166476
<segment>
64176477
<source>Custom</source>
@@ -9436,6 +9496,12 @@
94369496
<target/>
94379497
</segment>
94389498
</unit>
9499+
<unit id="wsAudioPlayer.reset">
9500+
<segment>
9501+
<source>Reset</source>
9502+
<target/>
9503+
</segment>
9504+
</unit>
94399505
<unit id="wsAudioPlayer.resume">
94409506
<segment>
94419507
<source>Resume</source>

src/renderer/public/localization/strings30ef9214.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

src/renderer/src/components/App/AppHead.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import {
1111
LinearProgress,
1212
Tooltip,
1313
Box,
14-
useTheme,
15-
useMediaQuery,
1614
} from '@mui/material';
1715
import HomeIcon from '@mui/icons-material/Home';
1816
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
@@ -35,6 +33,7 @@ import {
3533
exitApp,
3634
useMyNavigate,
3735
useWaitForRemoteQueue,
36+
useMobile,
3837
} from '../../utils';
3938
import { withBucket } from '../../hoc/withBucket';
4039
import { usePlan } from '../../crud';
@@ -48,6 +47,7 @@ import { useHome } from '../../utils/useHome';
4847
import { ApmLogo } from '../../control/ApmLogo';
4948
import { OrgHead } from './OrgHead';
5049
import { HeadStatus } from './HeadStatus';
50+
import MobileDetailTitle from './MobileDetailTitle';
5151

5252
const twoIcon = { minWidth: `calc(${48 * 2}px)` } as React.CSSProperties;
5353
const threeIcon = { minWidth: `calc(${48 * 3}px)` } as React.CSSProperties;
@@ -115,8 +115,7 @@ export const AppHead = (props: IProps) => {
115115
const orbitErrorMsg = useSelector((state: IState) => state.orbit.message);
116116
const { pathname } = useLocation();
117117
const navigate = useMyNavigate();
118-
const theme = useTheme();
119-
const isMobileWidth = useMediaQuery(theme.breakpoints.down('sm'));
118+
const { isMobileView, isMobileWidth } = useMobile();
120119
const [home] = useGlobal('home'); //verified this is not used in a function 2/18/25
121120
const [orgRole] = useGlobal('orgRole'); //verified this is not used in a function 2/18/25
122121
const [errorReporter] = useGlobal('errorReporter');
@@ -149,7 +148,6 @@ export const AppHead = (props: IProps) => {
149148
const [showTerms, setShowTerms] = useState('');
150149
const waitForRemoteQueue = useWaitForRemoteQueue();
151150
const waitForDataChangesQueue = useWaitForRemoteQueue('datachanges');
152-
const [mobileView] = useGlobal('mobileView');
153151

154152
// eslint-disable-next-line react-hooks/exhaustive-deps
155153
const saving = useMemo(() => anySaving(), [toolsChanged]);
@@ -344,7 +342,7 @@ export const AppHead = (props: IProps) => {
344342
if (view === 'Terms') navigate('/terms');
345343
if (view === 'Privacy') navigate('/privacy');
346344

347-
return !mobileView && !isMobileWidth ? (
345+
return !isMobileView && !isMobileWidth ? (
348346
<AppBar
349347
position="fixed"
350348
sx={{ width: '100%', display: 'flex' }}
@@ -417,11 +415,13 @@ export const AppHead = (props: IProps) => {
417415
<ApmLogo sx={{ width: '24px', height: '24px' }} />
418416
</IconButton>
419417
) : (
420-
<IconButton onClick={() => navigate(planUrl || '/team')}>
418+
<IconButton
419+
onClick={() => checkSavedFn(() => navigate(planUrl || '/team'))}
420+
>
421421
<ArrowBackIcon sx={{ width: '24px', height: '24px' }} />
422422
</IconButton>
423423
)}
424-
<OrgHead />
424+
{isDetail ? <MobileDetailTitle /> : <OrgHead />}
425425
<GrowingSpacer />
426426
{!isMobileWidth && (
427427
<HeadStatus

0 commit comments

Comments
 (0)