Skip to content

Commit 4ee818e

Browse files
committed
feat: add english translations for all hardcoded text
1 parent c2361c2 commit 4ee818e

25 files changed

+321
-283
lines changed

.eslintignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ build
22
public
33
coverage
44
src/registerServiceWorker.js
5-
cypress/integration/examples
5+
cypress/integration/examples

package.json

+2-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"@emotion/styled": "11.11.0",
1515
"@graasp/apps-query-client": "3.3.0",
1616
"@graasp/sdk": "3.3.0",
17+
"@graasp/translations": "^1.23.0",
1718
"@graasp/ui": "4.1.1",
1819
"@mui/icons-material": "5.11.16",
1920
"@mui/lab": "5.0.0-alpha.136",
@@ -26,15 +27,14 @@
2627
"@testing-library/jest-dom": "5.16.5",
2728
"@testing-library/react": "14.1.2",
2829
"cypress-vite": "^1.5.0",
29-
"i18next": "22.5.0",
3030
"lodash.isequal": "^4.5.0",
3131
"lodash.isobject": "3.0.2",
3232
"lodash.isstring": "4.0.1",
3333
"qs": "6.11.2",
3434
"randomcolor": "0.6.2",
3535
"react": "18.2.0",
3636
"react-dom": "18.2.0",
37-
"react-i18next": "12.3.1",
37+
"react-i18next": "14.0.5",
3838
"react-markdown": "^8.0.7",
3939
"react-toastify": "9.1.3",
4040
"remark-breaks": "^3.0.3",
@@ -75,7 +75,6 @@
7575
"@commitlint/config-conventional": "17.6.7",
7676
"@cypress/code-coverage": "3.12.17",
7777
"@trivago/prettier-plugin-sort-imports": "4.3.0",
78-
"@types/i18n": "0.13.10",
7978
"@types/jest": "29.5.11",
8079
"@types/lodash.isequal": "^4.5.6",
8180
"@types/lodash.isobject": "3.0.7",

src/components/Root.tsx

+50-48
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@ import { CssBaseline, ThemeProvider, createTheme, styled } from '@mui/material';
1414
import { grey, orange, pink } from '@mui/material/colors';
1515
import { StyledEngineProvider } from '@mui/material/styles';
1616

17+
import { TEXT_ANALYSIS } from '@/langs/constants';
18+
1719
import { ENABLE_MOCK_API } from '../config/env';
18-
import i18nConfig from '../config/i18n';
19-
import {
20-
CONTEXT_FETCHING_ERROR_MESSAGE,
21-
TOKEN_REQUEST_ERROR_MESSAGE,
22-
} from '../config/messages';
20+
import i18nConfig, { useTextAnalysisTranslation } from '../config/i18n';
2321
import {
2422
QueryClientProvider,
2523
ReactQueryDevtools,
@@ -75,53 +73,57 @@ const RootDiv = styled('div')({
7573
height: '100%',
7674
});
7775

78-
const Root: FC = () => {
76+
// This function is necessary to allow to use translations.
77+
const AppWithContext = (): JSX.Element => {
7978
const [mockContext, setMockContext] = useObjectState(defaultMockContext);
79+
const { t } = useTextAnalysisTranslation();
8080

8181
return (
82-
<RootDiv>
83-
{/* Used to define the order of injected properties between JSS and emotion */}
84-
<StyledEngineProvider injectFirst>
85-
<ThemeProvider theme={theme}>
86-
<CssBaseline enableColorScheme />
87-
<I18nextProvider i18n={i18nConfig}>
88-
<QueryClientProvider client={queryClient}>
89-
<WithLocalContext
90-
defaultValue={window.Cypress ? window.appContext : mockContext}
91-
LoadingComponent={<Loader />}
92-
useGetLocalContext={hooks.useGetLocalContext}
93-
useAutoResize={hooks.useAutoResize}
94-
onError={() => {
95-
showErrorToast(CONTEXT_FETCHING_ERROR_MESSAGE);
96-
}}
97-
>
98-
<WithTokenContext
99-
LoadingComponent={<Loader />}
100-
useAuthToken={hooks.useAuthToken}
101-
onError={() => {
102-
showErrorToast(TOKEN_REQUEST_ERROR_MESSAGE);
103-
}}
104-
>
105-
<ToastContainer position="bottom-right" />
106-
<App />
107-
{import.meta.env.DEV && ENABLE_MOCK_API && (
108-
<GraaspContextDevTool
109-
members={mockMembers}
110-
context={mockContext}
111-
setContext={setMockContext}
112-
/>
113-
)}
114-
</WithTokenContext>
115-
</WithLocalContext>
116-
{import.meta.env.DEV && (
117-
<ReactQueryDevtools position="top-right" />
118-
)}
119-
</QueryClientProvider>
120-
</I18nextProvider>
121-
</ThemeProvider>
122-
</StyledEngineProvider>
123-
</RootDiv>
82+
<WithLocalContext
83+
defaultValue={window.Cypress ? window.appContext : mockContext}
84+
LoadingComponent={<Loader />}
85+
useGetLocalContext={hooks.useGetLocalContext}
86+
useAutoResize={hooks.useAutoResize}
87+
onError={() => {
88+
showErrorToast(t(TEXT_ANALYSIS.CONTEXT_FETCHING_ERROR_MESSAGE));
89+
}}
90+
>
91+
<WithTokenContext
92+
LoadingComponent={<Loader />}
93+
useAuthToken={hooks.useAuthToken}
94+
onError={() => {
95+
showErrorToast(t(TEXT_ANALYSIS.TOKEN_REQUEST_ERROR_MESSAGE));
96+
}}
97+
>
98+
<ToastContainer position="bottom-right" />
99+
<App />
100+
{import.meta.env.DEV && ENABLE_MOCK_API && (
101+
<GraaspContextDevTool
102+
members={mockMembers}
103+
context={mockContext}
104+
setContext={setMockContext}
105+
/>
106+
)}
107+
</WithTokenContext>
108+
</WithLocalContext>
124109
);
125110
};
126111

112+
const Root: FC = () => (
113+
<RootDiv>
114+
{/* Used to define the order of injected properties between JSS and emotion */}
115+
<StyledEngineProvider injectFirst>
116+
<ThemeProvider theme={theme}>
117+
<CssBaseline enableColorScheme />
118+
<I18nextProvider i18n={i18nConfig}>
119+
<QueryClientProvider client={queryClient}>
120+
<AppWithContext />
121+
{import.meta.env.DEV && <ReactQueryDevtools position="top-right" />}
122+
</QueryClientProvider>
123+
</I18nextProvider>
124+
</ThemeProvider>
125+
</StyledEngineProvider>
126+
</RootDiv>
127+
);
128+
127129
export default Root;

src/components/common/PublicAlert.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { useTranslation } from 'react-i18next';
2-
31
import { useLocalContext } from '@graasp/apps-query-client';
42

53
import Alert from '@mui/material/Alert';
64

5+
import { useTextAnalysisTranslation } from '@/config/i18n';
6+
import { TEXT_ANALYSIS } from '@/langs/constants';
7+
78
const PublicAlert = (): JSX.Element | null => {
8-
const { t } = useTranslation();
9+
const { t } = useTextAnalysisTranslation();
910

1011
const context = useLocalContext();
1112

@@ -16,7 +17,7 @@ const PublicAlert = (): JSX.Element | null => {
1617

1718
return (
1819
<Alert severity="error">
19-
{t('You are not authenticated. You cannot save any data')}
20+
{t(TEXT_ANALYSIS.PUBLIC_ALERT_NOT_AUTHENTICATED)}
2021
</Alert>
2122
);
2223
};

src/components/common/chat/ChatBox.tsx

+7-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import {
99
useLocalContext,
1010
} from '@graasp/apps-query-client';
1111

12-
import { Alert, AlertTitle, Box, Stack, styled } from '@mui/material';
12+
import { Alert, Box, Stack, styled } from '@mui/material';
13+
14+
import { useTextAnalysisTranslation } from '@/config/i18n';
15+
import { TEXT_ANALYSIS } from '@/langs/constants';
1316

1417
import { APP_DATA_TYPES, ChatAppData } from '../../../config/appDataTypes';
1518
import {
@@ -20,10 +23,8 @@ import { DEFAULT_INITIAL_PROMPT } from '../../../config/appSettings';
2023
import {
2124
ANONYMOUS_USER,
2225
MAX_CONVERSATION_LENGTH,
23-
MAX_CONVERSATION_LENGTH_ALERT,
2426
SCROLL_SAFETY_MARGIN,
2527
} from '../../../config/constants';
26-
import { CHAT_BOT_ERROR_MESSAGE } from '../../../config/messages';
2728
import { mutations } from '../../../config/queryClient';
2829
import { CHATBOT_MODE_CY, messagesDataCy } from '../../../config/selectors';
2930
import {
@@ -73,6 +74,7 @@ const StyledReactMarkdown = styled(ReactMarkdown)(({ theme }) => ({
7374
type Prop = { focusWord: string; isOpen: boolean };
7475

7576
const ChatBox: FC<Prop> = ({ focusWord, isOpen }) => {
77+
const { t } = useTextAnalysisTranslation();
7678
const { postAppDataAsync, postAppData, appDataArray } = useAppDataContext();
7779
const { appSettingArray } = useAppSettingContext();
7880
const context = useLocalContext();
@@ -113,7 +115,7 @@ const ChatBox: FC<Prop> = ({ focusWord, isOpen }) => {
113115
setLoading(true);
114116

115117
const appData = {
116-
message: CHAT_BOT_ERROR_MESSAGE,
118+
message: t(TEXT_ANALYSIS.CHAT_BOT_ERROR_MESSAGE),
117119
keyword: focusWord,
118120
};
119121

@@ -135,8 +137,7 @@ const ChatBox: FC<Prop> = ({ focusWord, isOpen }) => {
135137
const renderBar =
136138
chatAppData.length > MAX_CONVERSATION_LENGTH ? (
137139
<Alert severity="info">
138-
<AlertTitle>Info</AlertTitle>
139-
{MAX_CONVERSATION_LENGTH_ALERT}
140+
{t(TEXT_ANALYSIS.MAX_CONVERSATION_LENGTH_ALERT)}
140141
</Alert>
141142
) : (
142143
<InputBar onSend={(input) => onSend(input)} />

src/components/common/chat/InputBar.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ import {
99
OutlinedInput,
1010
} from '@mui/material';
1111

12+
import { useTextAnalysisTranslation } from '@/config/i18n';
13+
import { TEXT_ANALYSIS } from '@/langs/constants';
14+
1215
import { ENTER_KEY } from '../../../config/constants';
1316

1417
type Prop = {
1518
onSend: (input: string) => void;
1619
};
1720

1821
const InputBar: FC<Prop> = ({ onSend }) => {
22+
const { t } = useTextAnalysisTranslation();
1923
const [comment, setComment] = useState('');
2024

2125
const onChange = ({ target }: { target: { value: string } }): void => {
@@ -37,23 +41,23 @@ const InputBar: FC<Prop> = ({ onSend }) => {
3741

3842
return (
3943
<FormControl sx={{ m: 1 }} variant="outlined">
40-
<InputLabel>reply here ...</InputLabel>
44+
<InputLabel>{t(TEXT_ANALYSIS.INPUT_BAR_REPLY_HERE)}</InputLabel>
4145
<OutlinedInput
4246
value={comment}
4347
onChange={onChange}
4448
onKeyDown={onEnterPress}
4549
endAdornment={
4650
<InputAdornment position="end">
4751
<IconButton
48-
aria-label="send"
52+
aria-label={t(TEXT_ANALYSIS.INPUT_BAR_SEND_BTN)}
4953
onClick={() => handleClickSend(comment)}
5054
edge="end"
5155
>
5256
<SendIcon />
5357
</IconButton>
5458
</InputAdornment>
5559
}
56-
label="reply here ..."
60+
label={t(TEXT_ANALYSIS.INPUT_BAR_REPLY_HERE)}
5761
/>
5862
</FormControl>
5963
);

src/components/common/display/Banner.tsx

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { FC, useState } from 'react';
22

33
import { Box, Button, Typography } from '@mui/material';
44

5+
import { useTextAnalysisTranslation } from '@/config/i18n';
6+
import { TEXT_ANALYSIS } from '@/langs/constants';
7+
58
import { BANNER_CY, SHOW_KEYWORDS_BUTTON_CY } from '../../../config/selectors';
69
import {
710
DEFAULT_MARGIN,
@@ -15,11 +18,11 @@ type Prop = {
1518
};
1619

1720
const Banner: FC<Prop> = ({ title, disabled, onClick }) => {
21+
const { t } = useTextAnalysisTranslation();
1822
const [showKeywords, setShowKeywords] = useState(false);
1923

20-
// TODO: translate me
21-
const SHOW_KEYWORDS_LABEL = 'show keywords';
22-
const HIDE_KEYWORDS_LABEL = 'hide keywords';
24+
const SHOW_KEYWORDS_LABEL = t(TEXT_ANALYSIS.BANNER_SHOW_KEYWORDS_BTN);
25+
const HIDE_KEYWORDS_LABEL = t(TEXT_ANALYSIS.BANNER_HIDE_KEYWORDS_BTN);
2326

2427
const toggleKeywords = (): void => {
2528
onClick(!showKeywords);

0 commit comments

Comments
 (0)