Skip to content

Commit 1fc57f9

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. - 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 - convert in line to functions - add test for HighlightButton - updates for preview and auto save - move steps to header - play entire recording preview - auto segment highlight step - remove scroll bar from steps - remove navigation player navigation buttons - remove previous segment control - delete leads to record - auto save segments - auto save recordings - click in segment starts play at beginning - update logic for working through the steps - only show undo if possible - dont show clear all segments - show play and pause for player - add undo for segments - first click positions at start of the region. - second click in a region positions on click
1 parent 2a958d5 commit 1fc57f9

File tree

64 files changed

+4496
-554
lines changed

Some content is hidden

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

64 files changed

+4496
-554
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: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,13 @@
15361536
<context context-type="sourcefile">SpeakerName.tsx</context>
15371537
</context-group>
15381538
</trans-unit>
1539+
<trans-unit id="community.autoSegment">
1540+
<source>Use {0} for autosegmentation, or tap in the waveform and use + for manual segmentation</source>
1541+
<target/>
1542+
<context-group>
1543+
<context context-type="sourcefile">SpeakerName.tsx</context>
1544+
</context-group>
1545+
</trans-unit>
15391546
<trans-unit id="community.backTranslationComplete">
15401547
<source>Version {0}: Back translation: {1}</source>
15411548
<target/>
@@ -1564,6 +1571,13 @@
15641571
<context context-type="sourcefile">SpeakerName.tsx</context>
15651572
</context-group>
15661573
</trans-unit>
1574+
<trans-unit id="community.listen">
1575+
<source>Use {0} to listen to the passage</source>
1576+
<target/>
1577+
<context-group>
1578+
<context context-type="sourcefile">SpeakerName.tsx</context>
1579+
</context-group>
1580+
</trans-unit>
15671581
<trans-unit id="community.loading">
15681582
<source>Loading:</source>
15691583
<target/>
@@ -5211,6 +5225,56 @@
52115225
<context context-type="sourcefile">MediaUpload.tsx</context>
52125226
</context-group>
52135227
</trans-unit>
5228+
<trans-unit id="mobile.addSegment">
5229+
<source>Add segment boundary</source>
5230+
<target/>
5231+
<context-group>
5232+
<context context-type="sourcefile">SegmentControlIsMobile.tsx</context>
5233+
</context-group>
5234+
</trans-unit>
5235+
<trans-unit id="mobile.next">
5236+
<source>Next</source>
5237+
<target/>
5238+
<context-group>
5239+
<context context-type="sourcefile">PassageDetailMobileFooter.tsx</context>
5240+
</context-group>
5241+
</trans-unit>
5242+
<trans-unit id="mobile.previous">
5243+
<source>Previous</source>
5244+
<target/>
5245+
<context-group>
5246+
<context context-type="sourcefile">PassageDetailMobileFooter.tsx</context>
5247+
</context-group>
5248+
</trans-unit>
5249+
<trans-unit id="mobile.removeSegment">
5250+
<source>Remove next segment boundary</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.resetBT">
5257+
<source>Reset back translation</source>
5258+
<target/>
5259+
<context-group>
5260+
<context context-type="sourcefile">SegmentControlIsMobile.tsx</context>
5261+
</context-group>
5262+
</trans-unit>
5263+
<trans-unit id="mobile.restoreBoundaries">
5264+
<source>Restore original segment boundaries</source>
5265+
<target/>
5266+
<context-group>
5267+
<context context-type="sourcefile">SegmentControlIsMobile.tsx</context>
5268+
</context-group>
5269+
</trans-unit>
5270+
<trans-unit id="mobile.segment">
5271+
<source>Segment: {0}</source>
5272+
<target/>
5273+
<context-group>
5274+
<context context-type="sourcefile">SegmentControlIsMobile.tsx</context>
5275+
</context-group>
5276+
</trans-unit>
5277+
52145278
<trans-unit id="newProject.audioProduct">
52155279
<source>Audio Product</source>
52165280
<target/>
@@ -7480,6 +7544,27 @@
74807544
<context context-type="sourcefile">ResourceOverview.tsx</context>
74817545
</context-group>
74827546
</trans-unit>
7547+
<trans-unit id="recordButton.record">
7548+
<source>RECORD</source>
7549+
<target/>
7550+
<context-group>
7551+
<context context-type="sourcefile">RecordButton.tsx</context>
7552+
</context-group>
7553+
</trans-unit>
7554+
<trans-unit id="recordButton.rerecord">
7555+
<source>RERECORD</source>
7556+
<target/>
7557+
<context-group>
7558+
<context context-type="sourcefile">RecordButton.tsx</context>
7559+
</context-group>
7560+
</trans-unit>
7561+
<trans-unit id="recordButton.resume">
7562+
<source>RESUME</source>
7563+
<target/>
7564+
<context-group>
7565+
<context context-type="sourcefile">RecordButton.tsx</context>
7566+
</context-group>
7567+
</trans-unit>
74837568
<trans-unit id="recordStepSettings.custom">
74847569
<source>Custom</source>
74857570
<target/>
@@ -11010,6 +11095,13 @@
1101011095
<context context-type="sourcefile">wsAudioPlayer.tsx</context>
1101111096
</context-group>
1101211097
</trans-unit>
11098+
<trans-unit id="wsAudioPlayer.reset">
11099+
<source>Reset</source>
11100+
<target/>
11101+
<context-group>
11102+
<context context-type="sourcefile">wsAudioPlayer.tsx</context>
11103+
</context-group>
11104+
</trans-unit>
1101311105
<trans-unit id="wsAudioPlayer.resume">
1101411106
<source>Resume</source>
1101511107
<target/>

localization/TranscriberAdmin-en.xlf

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,6 +1318,12 @@
13181318
<target/>
13191319
</segment>
13201320
</unit>
1321+
<unit id="community.autoSegment">
1322+
<segment>
1323+
<source>Use {0} for autosegmentation, or tap in the waveform and use + for manual segmentation</source>
1324+
<target/>
1325+
</segment>
1326+
</unit>
13211327
<unit id="community.backTranslationComplete">
13221328
<segment>
13231329
<source>Version {0}: Back translation: {1}</source>
@@ -1342,6 +1348,12 @@
13421348
<target/>
13431349
</segment>
13441350
</unit>
1351+
<unit id="community.listen">
1352+
<segment>
1353+
<source>Use {0} to listen to the passage</source>
1354+
<target/>
1355+
</segment>
1356+
</unit>
13451357
<unit id="community.loading">
13461358
<segment>
13471359
<source>Loading:</source>
@@ -4468,6 +4480,48 @@
44684480
<target/>
44694481
</segment>
44704482
</unit>
4483+
<unit id="mobile.addSegment">
4484+
<segment>
4485+
<source>Add segment boundary</source>
4486+
<target/>
4487+
</segment>
4488+
</unit>
4489+
<unit id="mobile.next">
4490+
<segment>
4491+
<source>Next</source>
4492+
<target/>
4493+
</segment>
4494+
</unit>
4495+
<unit id="mobile.previous">
4496+
<segment>
4497+
<source>Previous</source>
4498+
<target/>
4499+
</segment>
4500+
</unit>
4501+
<unit id="mobile.removeSegment">
4502+
<segment>
4503+
<source>Remove next segment boundary</source>
4504+
<target/>
4505+
</segment>
4506+
</unit>
4507+
<unit id="mobile.resetBT">
4508+
<segment>
4509+
<source>Reset back translation</source>
4510+
<target/>
4511+
</segment>
4512+
</unit>
4513+
<unit id="mobile.restoreBoundaries">
4514+
<segment>
4515+
<source>Restore original segment boundaries</source>
4516+
<target/>
4517+
</segment>
4518+
</unit>
4519+
<unit id="mobile.segment">
4520+
<segment>
4521+
<source>Segment: {0}</source>
4522+
<target/>
4523+
</segment>
4524+
</unit>
44714525
<unit id="newProject.audioProduct">
44724526
<segment>
44734527
<source>Audio Product</source>
@@ -6412,6 +6466,24 @@
64126466
<target/>
64136467
</segment>
64146468
</unit>
6469+
<unit id="recordButton.record">
6470+
<segment>
6471+
<source>RECORD</source>
6472+
<target/>
6473+
</segment>
6474+
</unit>
6475+
<unit id="recordButton.rerecord">
6476+
<segment>
6477+
<source>RERECORD</source>
6478+
<target/>
6479+
</segment>
6480+
</unit>
6481+
<unit id="recordButton.resume">
6482+
<segment>
6483+
<source>RESUME</source>
6484+
<target/>
6485+
</segment>
6486+
</unit>
64156487
<unit id="recordStepSettings.custom">
64166488
<segment>
64176489
<source>Custom</source>
@@ -9436,6 +9508,12 @@
94369508
<target/>
94379509
</segment>
94389510
</unit>
9511+
<unit id="wsAudioPlayer.reset">
9512+
<segment>
9513+
<source>Reset</source>
9514+
<target/>
9515+
</segment>
9516+
</unit>
94399517
<unit id="wsAudioPlayer.resume">
94409518
<segment>
94419519
<source>Resume</source>

src/renderer/public/localization/stringsbd78e002.json

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

src/renderer/public/localization/stringsf10b854f.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/renderer/src/business/player/usePlayerLogic.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export const usePlayerLogic = (props: PlayerLogicProps) => {
7070

7171
useEffect(() => {
7272
if (allowSegment)
73-
if (suggestedSegments) {
73+
if (suggestedSegments && segmentsRef.current !== suggestedSegments) {
7474
segmentsRef.current = suggestedSegments;
7575
setDefaultSegments(segmentsRef.current);
7676
onSegment && onSegment(segmentsRef.current, true);

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

Lines changed: 13 additions & 9 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]);
@@ -284,6 +282,12 @@ export const AppHead = (props: IProps) => {
284282
return undefined;
285283
};
286284

285+
const handleTeamNav = () => {
286+
checkSavedFn(() => navigate('/team'));
287+
};
288+
289+
const handlePlanNav = () => checkSavedFn(() => navigate(planUrl || '/team'));
290+
287291
useEffect(() => {
288292
window.addEventListener('beforeunload', handleUnload);
289293
if (!user) {
@@ -344,7 +348,7 @@ export const AppHead = (props: IProps) => {
344348
if (view === 'Terms') navigate('/terms');
345349
if (view === 'Privacy') navigate('/privacy');
346350

347-
return !mobileView && !isMobileWidth ? (
351+
return !isMobileView && !isMobileWidth ? (
348352
<AppBar
349353
position="fixed"
350354
sx={{ width: '100%', display: 'flex' }}
@@ -413,15 +417,15 @@ export const AppHead = (props: IProps) => {
413417
<>
414418
<Toolbar>
415419
{!isDetail ? (
416-
<IconButton onClick={() => navigate('/team')} sx={{ p: 0 }}>
420+
<IconButton onClick={handleTeamNav} sx={{ p: 0 }}>
417421
<ApmLogo sx={{ width: '24px', height: '24px' }} />
418422
</IconButton>
419423
) : (
420-
<IconButton onClick={() => navigate(planUrl || '/team')}>
424+
<IconButton onClick={handlePlanNav}>
421425
<ArrowBackIcon sx={{ width: '24px', height: '24px' }} />
422426
</IconButton>
423427
)}
424-
<OrgHead />
428+
{isDetail ? <MobileDetailTitle /> : <OrgHead />}
425429
<GrowingSpacer />
426430
{!isMobileWidth && (
427431
<HeadStatus

0 commit comments

Comments
 (0)