Skip to content

Commit 3a231d5

Browse files
committed
getting there
1 parent ffce18b commit 3a231d5

Some content is hidden

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

51 files changed

+793
-979
lines changed

packages/selenium-ide/src/browser/I18N/en/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Commands as commandMapEnglish } from '@seleniumhq/side-model'
2+
import { flattenNestedObject } from '../util'
23

34
const windowTabEnglish = {
45
file: '&File',
@@ -112,7 +113,7 @@ const suitesTabEnglish = {
112113
suiteName: 'Suite Name',
113114
cancel: 'Cancel',
114115
create: 'Create',
115-
deleteNotice: 'Delete this suite?',
116+
deleteNotice: 'Are you sure you want to delete suite {name}?',
116117
tooltip:
117118
'double click to modify the name,right click to export or delete suites',
118119
notDeleteNotice: 'only one suites is not allowed to be deleted!',
@@ -195,7 +196,7 @@ const testCoreEnglish = {
195196
playFromStart: 'Play From Start',
196197
}
197198

198-
const langaugeMap = {
199+
export const langaugeMapEn = {
199200
windowTab: windowTabEnglish,
200201
electronMenuTree: electronMenuTreeEnglish,
201202
fileMenuTree: fileMenuTreeEnglish,
@@ -217,6 +218,7 @@ const langaugeMap = {
217218

218219
// Creating a type of this so other locales are prompted to be filled in by
219220
// the developer
220-
export type LanguageMap = typeof langaugeMap
221+
export type LanguageMap = typeof langaugeMapEn
221222

222-
export default langaugeMap
223+
const flattenedMap = flattenNestedObject(langaugeMapEn)
224+
export default flattenedMap
Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,10 @@
1-
import en, { LanguageMap } from './en'
2-
3-
const processOneLevel = (
4-
prefix: string,
5-
obj: LanguageMap
6-
): LanguageMap => {
7-
return Object.entries(obj).reduce((acc, [key, value]) => {
8-
const keyPath = `${prefix}.${key}`;
9-
if (typeof value === 'string') {
10-
// @ts-expect-error - we know this is a string
11-
acc[key] = keyPath;
12-
} else {
13-
// @ts-expect-error - we know this is an object
14-
acc[key] = processOneLevel(keyPath, value);
15-
}
16-
return acc;
17-
}, {} as LanguageMap);
18-
}
1+
import {langaugeMapEn} from './en'
2+
import {transformNestedObject} from './util'
193

204
/**
215
* Take this nested object, keep the shape, but make the final keys the dot delimited string
226
* path of the nested key
237
*/
24-
export default processOneLevel('en', en)
8+
const languageMap = transformNestedObject((key) => key, langaugeMapEn)
9+
10+
export default languageMap
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
interface RecursiveShape {
2+
[key: string]: boolean | string | RecursiveShape
3+
}
4+
5+
const processOneLevel = <T extends RecursiveShape>(
6+
prefix: string,
7+
getValue: (key: string, value: string) => any,
8+
obj: T
9+
): Record<string, any> => {
10+
return Object.entries(obj).reduce((acc, [key, value]) => {
11+
const keyPath = prefix ? `${prefix}.${key}` : key
12+
if (value && typeof value === 'object') {
13+
// @ts-expect-error our shape traversal kinda sucks :(
14+
acc[key] = processOneLevel<T>(keyPath, getValue, value)
15+
} else {
16+
// @ts-expect-error our shape traversal kinda sucks :(
17+
acc[key] = getValue(keyPath, value)
18+
}
19+
return acc
20+
}, {} as T)
21+
}
22+
23+
/**
24+
* Take this nested object, keep the shape, but make the final keys the dot delimited string
25+
* path of the nested key
26+
*/
27+
28+
export const transformNestedObject = <T extends RecursiveShape>(
29+
getValue: (key: string, value: string) => any,
30+
obj: T
31+
): Record<string, any> => processOneLevel<T>('', getValue, obj)
32+
33+
const flattenOneLevel = <T extends RecursiveShape>(
34+
prefix: string,
35+
getValue: (key: string, value: string) => any,
36+
target: Record<string, any>,
37+
source: T
38+
): Record<string, any> => {
39+
return Object.entries(source).reduce((acc, [key, value]) => {
40+
const keyPath = prefix ? `${prefix}.${key}` : key
41+
if (value && typeof value === 'object') {
42+
flattenOneLevel<T>(keyPath, getValue, target, value as T)
43+
} else {
44+
// @ts-expect-error our shape traversal kinda sucks :(
45+
acc[keyPath] = getValue(keyPath, value)
46+
}
47+
return acc
48+
}, target as T)
49+
}
50+
51+
export const flattenNestedObject = <T extends RecursiveShape>(
52+
obj: T
53+
): Record<string, any> => flattenOneLevel('', (_k, v) => v, {}, obj)

packages/selenium-ide/src/browser/I18N/zh/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type {LanguageMap} from '../en/index';
1+
import type { LanguageMap } from '../en/index'
22
import Commands from '@seleniumhq/side-model/dist/I18N/zh/Commands'
3-
3+
import {transformNestedObject} from '../util'
44

55
// 窗口顶部菜单
66
const windowTabChinese = {
@@ -202,7 +202,7 @@ const testCoreChinese = {
202202
playFromStart: '从头开始回放',
203203
}
204204

205-
export const languageMap: LanguageMap = {
205+
export const languageMapZh: LanguageMap = {
206206
windowTab: windowTabChinese,
207207
electronMenuTree: electronMenuTreeChinese,
208208
fileMenuTree: fileMenuTreeChinese,
@@ -222,4 +222,4 @@ export const languageMap: LanguageMap = {
222222
commandMap: Commands,
223223
}
224224

225-
export default languageMap
225+
export default transformNestedObject((_k, v) => v, languageMapZh)

packages/selenium-ide/src/browser/components/AppBar/AppBarTabs.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import Tabs from '@mui/material/Tabs'
22
import Tab from '@mui/material/Tab'
33
import React from 'react'
44
import { PROJECT_TAB, SUITES_TAB, TESTS_TAB } from 'browser/enums/tab'
5-
import { PROJECT_TAB, SUITES_TAB, TESTS_TAB } from 'browser/I18N/keys'
5+
import languageMap from 'browser/I18N/keys'
66
import { SIDEMainProps } from '../types'
7+
import { FormattedMessage } from 'react-intl'
78

89
/**********顶部菜单栏tab*************/
910
function a11yProps(index: number) {

packages/selenium-ide/src/browser/components/AppWrapper.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,16 @@ const AppWrapper: FC<AppWrapperProps> = ({ children }) => {
3030
}),
3131
[prefersDarkMode]
3232
)
33+
const [languageMap, setLanguageMap] = React.useState<any>({})
34+
React.useEffect(() => {
35+
window.sideAPI.system.getLanguageMap().then((result) => {
36+
console.log(result)
37+
setLanguageMap(result)
38+
})
39+
}, [])
3340

3441
return (
35-
<IntlProvider defaultLocale='en'>
42+
<IntlProvider defaultLocale="en" messages={languageMap}>
3643
{/* @ts-expect-error react-intl has funky versions */}
3744
<ThemeProvider theme={theme}>
3845
<CssBaseline />
Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,24 @@
11
import PauseIcon from '@mui/icons-material/Pause'
22
import IconButton from '@mui/material/IconButton'
33
import Tooltip from '@mui/material/Tooltip'
4-
import React, { FC, useEffect, useState } from 'react'
4+
import React, { FC } from 'react'
55
import baseControlProps from './BaseProps'
6+
import { FormattedMessage } from 'react-intl'
7+
import languageMap from 'browser/I18N/keys'
68

7-
const PauseButton: FC = () => {
8-
const [languageMap, setLanguageMap] = useState<any>({
9-
testCore: {
10-
pause: 'Pause',
11-
},
12-
})
13-
14-
useEffect(() => {
15-
window.sideAPI.system.getLanguageMap().then((result) => {
16-
setLanguageMap(result)
17-
})
18-
}, [])
19-
return (
20-
<Tooltip title={languageMap.testCore.pause} aria-label="pause">
21-
<IconButton
22-
{...baseControlProps}
23-
data-pause
24-
onClick={() => window.sideAPI.playback.pause()}
25-
>
26-
<PauseIcon />
27-
</IconButton>
28-
</Tooltip>
29-
)
30-
}
9+
const PauseButton: FC = () => (
10+
<Tooltip
11+
title={<FormattedMessage id={languageMap.testCore.pause} />}
12+
aria-label="pause"
13+
>
14+
<IconButton
15+
{...baseControlProps}
16+
data-pause
17+
onClick={() => window.sideAPI.playback.pause()}
18+
>
19+
<PauseIcon />
20+
</IconButton>
21+
</Tooltip>
22+
)
3123

3224
export default PauseButton

packages/selenium-ide/src/browser/components/Controls/PlayButton.tsx

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,22 @@
11
import PlayArrowIcon from '@mui/icons-material/PlayArrow'
22
import IconButton from '@mui/material/IconButton'
33
import Tooltip from '@mui/material/Tooltip'
4-
import React, { FC, useContext, useEffect, useState } from 'react'
4+
import React, { FC, useContext } from 'react'
55
import { badIndex } from '@seleniumhq/side-api/dist/constants/badIndex'
66
import baseControlProps from './BaseProps'
77
import { context as playbackCurrentIndexContext } from 'browser/contexts/playback-current-index'
88
import { context as activeTestContext } from 'browser/contexts/active-test'
9+
import { FormattedMessage } from 'react-intl'
10+
import languageMap from 'browser/I18N/keys'
911

1012
const PlayButton: FC = () => {
1113
const { activeTestID } = useContext(activeTestContext)
1214
const currentIndex = useContext(playbackCurrentIndexContext)
13-
const [languageMap, setLanguageMap] = useState<any>({
14-
testCore: {
15-
play: 'Play',
16-
},
17-
})
18-
19-
useEffect(() => {
20-
window.sideAPI.system.getLanguageMap().then((result) => {
21-
setLanguageMap(result)
22-
})
23-
}, [])
2415
return (
25-
<Tooltip title={languageMap.testCore.play} aria-label="play">
16+
<Tooltip
17+
title={<FormattedMessage id={languageMap.testCore.play} />}
18+
aria-label="play"
19+
>
2620
<IconButton
2721
{...baseControlProps}
2822
data-play
Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,24 @@
11
import PlaylistPlayIcon from '@mui/icons-material/PlaylistPlay'
22
import IconButton from '@mui/material/IconButton'
33
import Tooltip from '@mui/material/Tooltip'
4-
import React, { FC, useEffect, useState } from 'react'
4+
import React, { FC } from 'react'
55
import baseControlProps from './BaseProps'
6+
import { FormattedMessage } from 'react-intl'
7+
import languageMap from 'browser/I18N/keys'
68

7-
const PlayListButton: FC = () => {
8-
const [languageMap, setLanguageMap] = useState<any>({
9-
suitesTab: {
10-
playSuite: 'Play Suite',
11-
},
12-
})
13-
14-
useEffect(() => {
15-
window.sideAPI.system.getLanguageMap().then((result) => {
16-
setLanguageMap(result)
17-
})
18-
}, [])
19-
return (
20-
<Tooltip title={languageMap.suitesTab.playSuite} aria-label="play-suite">
21-
<IconButton
22-
{...baseControlProps}
23-
data-play-suite
24-
onClick={() => window.sideAPI.playback.playSuite()}
25-
>
26-
<PlaylistPlayIcon />
27-
</IconButton>
28-
</Tooltip>
29-
)
30-
}
9+
const PlayListButton: FC = () => (
10+
<Tooltip
11+
title={<FormattedMessage id={languageMap.suitesTab.playSuite} />}
12+
aria-label="play-suite"
13+
>
14+
<IconButton
15+
{...baseControlProps}
16+
data-play-suite
17+
onClick={() => window.sideAPI.playback.playSuite()}
18+
>
19+
<PlaylistPlayIcon />
20+
</IconButton>
21+
</Tooltip>
22+
)
3123

3224
export default PlayListButton
Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,24 @@
11
import RecordIcon from '@mui/icons-material/FiberManualRecord'
22
import IconButton from '@mui/material/IconButton'
33
import Tooltip from '@mui/material/Tooltip'
4-
import React, { FC, useEffect, useState } from 'react'
4+
import React, { FC } from 'react'
55
import baseControlProps from './BaseProps'
6+
import { FormattedMessage } from 'react-intl'
7+
import languageMap from 'browser/I18N/keys'
68

7-
const RecordButton: FC = () => {
8-
const [languageMap, setLanguageMap] = useState<any>({
9-
testCore: {
10-
record: 'Record',
11-
},
12-
})
13-
14-
useEffect(() => {
15-
window.sideAPI.system.getLanguageMap().then((result) => {
16-
setLanguageMap(result)
17-
})
18-
}, [])
19-
return (
20-
<Tooltip title={languageMap.testCore.record} aria-label="record">
21-
<IconButton
22-
{...baseControlProps}
23-
data-record
24-
onClick={() => window.sideAPI.recorder.start()}
25-
>
26-
<RecordIcon color="error" />
27-
</IconButton>
28-
</Tooltip>
29-
)
30-
}
9+
const RecordButton: FC = () => (
10+
<Tooltip
11+
title={<FormattedMessage id={languageMap.testCore.record} />}
12+
aria-label="record"
13+
>
14+
<IconButton
15+
{...baseControlProps}
16+
data-record
17+
onClick={() => window.sideAPI.recorder.start()}
18+
>
19+
<RecordIcon color="error" />
20+
</IconButton>
21+
</Tooltip>
22+
)
3123

3224
export default RecordButton

0 commit comments

Comments
 (0)