AlexiCauvin 5 years ago
parent
commit
627e0573c3

+ 9 - 0
build_full_frontend.sh View File

@@ -21,6 +21,10 @@ log "npm run build$windoz # for frontend_app_html-document"
21 21
 npm run build$windoz
22 22
 log "cp dist/html-document.app.js"
23 23
 cp dist/html-document.app.js ../frontend/dist/app
24
+log "cp i18next.scanner/en/translation.json ../frontend/dist/app/tml-document_en_translation.json"
25
+cp i18next.scanner/en/translation.json ../frontend/dist/app/html-document_en_translation.json
26
+log "cp i18next.scanner/fr/translation.json ../frontend/dist/app/html-document_fr_translation.json"
27
+cp i18next.scanner/fr/translation.json ../frontend/dist/app/html-document_fr_translation.json
24 28
 cd -
25 29
 
26 30
 log "cd frontend_app_thread"
@@ -29,3 +33,8 @@ log "npm run build$windoz # for frontend_app_thread"
29 33
 npm run build$windoz
30 34
 log "cp dist/thread.app.js"
31 35
 cp dist/thread.app.js ../frontend/dist/app
36
+log "cp i18next.scanner/en/translation.json ../frontend/dist/app/thread_en_translation.json"
37
+cp i18next.scanner/en/translation.json ../frontend/dist/app/thread_en_translation.json
38
+log "cp i18next.scanner/fr/translation.json ../frontend/dist/app/thread_fr_translation.json"
39
+cp i18next.scanner/fr/translation.json ../frontend/dist/app/thread_fr_translation.json
40
+cd -

+ 2 - 0
frontend/package.json View File

@@ -10,6 +10,7 @@
10 10
     "servdev-dashboard": "NODE_ENV=development webpack-dashboard -m -- webpack-dev-server --watch --colors --inline --hot --progress",
11 11
     "buildwindoz": "set NODE_ENV=production&& webpack -p",
12 12
     "build": "NODE_ENV=production webpack -p",
13
+    "build-translation": "node i18next.scanner.js",
13 14
     "test": "echo \"Error: no test specified\" && exit 1"
14 15
   },
15 16
   "author": "",
@@ -52,6 +53,7 @@
52 53
     "whatwg-fetch": "^2.0.3"
53 54
   },
54 55
   "devDependencies": {
56
+    "i18next-scanner": "^2.6.1",
55 57
     "json-server": "^0.12.0",
56 58
     "webpack-dashboard": "^1.0.2",
57 59
     "webpack-dev-server": "^2.9.2"

+ 5 - 1
frontend/src/appFactory.js View File

@@ -1,5 +1,8 @@
1 1
 import React from 'react'
2 2
 import { FETCH_CONFIG } from './helper.js'
3
+import i18n from './i18n.js'
4
+
5
+console.log('appFactory', i18n)
3 6
 
4 7
 export function appFactory (WrappedComponent) {
5 8
   return class AppFactory extends React.Component {
@@ -10,7 +13,8 @@ export function appFactory (WrappedComponent) {
10 13
         domContainer: 'appContainer',
11 14
         apiUrl: FETCH_CONFIG.apiUrl,
12 15
         mockApiUrl: FETCH_CONFIG.mockApiUrl,
13
-        apiHeader: FETCH_CONFIG.headers
16
+        apiHeader: FETCH_CONFIG.headers,
17
+        translation: i18n.store.data
14 18
       },
15 19
       content
16 20
     })

+ 1 - 1
frontend/src/component/FlashMessage.jsx View File

@@ -22,7 +22,7 @@ const FlashMessage = props => {
22 22
 
23 23
               <div className='flashmessage__container__content__text'>
24 24
                 <div className='flashmessage__container__content__text__title'>
25
-                  {props.t('FlashMessage.error')}
25
+                  {props.t('Error')}
26 26
                 </div>
27 27
                 <div className='flashmessage__container__content__text__paragraph'>
28 28
                   {props.flashMessage[0].message}

+ 1 - 1
frontend/src/component/Footer.jsx View File

@@ -7,7 +7,7 @@ const Footer = ({ t }) => {
7 7
   return (
8 8
     <footer className='footer text-right'>
9 9
       <div className='footer__text'>
10
-        {t('Footer.marketing_msg')} - {t('Footer.copyright')}
10
+        {t('Create your own collaborative workspaces on trac.im')} - {t('Copyright 2013 - 2017')}
11 11
       </div>
12 12
       <img className='footer__logo' src={logoFooter} />
13 13
     </footer>

+ 1 - 1
frontend/src/component/Header/MenuActionListItem/Search.jsx View File

@@ -9,7 +9,7 @@ const Search = props => {
9 9
         <input
10 10
           type='text'
11 11
           className='search__input form-control'
12
-          placeholder={`${props.t('Header.Search')}...`}
12
+          placeholder={`${props.t('Search...')}`}
13 13
           aria-describedby='headerInputSearch'
14 14
           onChange={props.onChangeInput}
15 15
         />

+ 3 - 3
frontend/src/component/Workspace/ContentItemHeader.jsx View File

@@ -5,13 +5,13 @@ const FileItemHeader = props => {
5 5
   return (
6 6
     <div className='content__header'>
7 7
       <div className='content__header__type'>
8
-        {props.t('FileItemHeader.type')}
8
+        {props.t('Type')}
9 9
       </div>
10 10
       <div className='content__header__name'>
11
-        {props.t('FileItemHeader.document_name')}
11
+        {props.t("Document's name")}
12 12
       </div>
13 13
       <div className='content__header__status'>
14
-        {props.t('FileItemHeader.status')}
14
+        {props.t('Status')}
15 15
       </div>
16 16
     </div>
17 17
   )

+ 1 - 1
frontend/src/component/Workspace/Folder.jsx View File

@@ -65,7 +65,7 @@ class Folder extends React.Component {
65 65
                 aria-expanded='false'
66 66
                 onClick={e => e.stopPropagation()}
67 67
               >
68
-                {t('Folder.create')} ...
68
+                {t('Create in folder...')}
69 69
               </button>
70 70
 
71 71
               <div className='addbtn__subdropdown dropdown-menu' aria-labelledby='dropdownMenuButton'>

+ 1 - 1
frontend/src/container/Header.jsx View File

@@ -49,7 +49,7 @@ class Header extends React.Component {
49 49
 
50 50
       dispatch(setUserDisconnected())
51 51
     } else {
52
-      dispatch(newFlashMessage(t('Login.logout_error', 'danger')))
52
+      dispatch(newFlashMessage(t('Disconnection error', 'danger')))
53 53
     }
54 54
   }
55 55
 

+ 1 - 1
frontend/src/container/Login.jsx View File

@@ -57,7 +57,7 @@ class Login extends React.Component {
57 57
 
58 58
       history.push(PAGE.HOME)
59 59
     } else if (fetchPostUserLogin.status === 400) {
60
-      dispatch(newFlashMessage(t('Login.fail'), 'danger'))
60
+      dispatch(newFlashMessage(t('Email or password invalid'), 'danger'))
61 61
     }
62 62
   }
63 63
 

+ 1 - 1
frontend/src/container/Sidebar.jsx View File

@@ -86,7 +86,7 @@ class Sidebar extends React.Component {
86 86
 
87 87
             <div className='sidebar__btnnewworkspace'>
88 88
               <button className='sidebar__btnnewworkspace__btn btn btn-primary primaryColorBg primaryColorBorder primaryColorBorderDarkenHover mb-5'>
89
-                {t('Sidebar.create_new_workspace')}
89
+                {t('Create new workspace')}
90 90
               </button>
91 91
             </div>
92 92
 

+ 19 - 9
frontend/src/i18n.js View File

@@ -1,29 +1,39 @@
1 1
 import i18n from 'i18next'
2 2
 import { reactI18nextModule } from 'react-i18next'
3
-import { langFr, langEn } from 'tracim_frontend_lib'
4
-import fr from './translate/fr.js'
5
-import en from './translate/en.js'
3
+import { frLib, enLib } from 'tracim_frontend_lib'
4
+import en from '../i18next.scanner/en/translation.json'
5
+import fr from '../i18next.scanner/fr/translation.json'
6
+
7
+// get translation files of apps
8
+// theses files are generated by build_appname.sh
9
+const htmlDocEnTranslation = require('../dist/app/html-document_en_translation.json')
10
+const htmlDocFrTranslation = require('../dist/app/html-document_fr_translation.json')
6 11
 
7 12
 i18n
8 13
   .use(reactI18nextModule)
9 14
   .init({
10
-    fallbackLng: 'fr',
15
+    fallbackLng: 'en',
11 16
     // have a common namespace used around the full app
12 17
     ns: ['translation'], // namespace
13 18
     defaultNS: 'translation',
14 19
     debug: true,
15
-    // interpolation: {
16
-    //   escapeValue: false, // not needed for react!!
17
-    // },
18 20
     react: {
19 21
       wait: true
20 22
     },
21 23
     resources: {
22 24
       en: {
23
-        translation: {...langEn.translation, ...en.translation}
25
+        translation: {
26
+          ...enLib, // fronted_lib
27
+          ...en, // frontend
28
+          ...htmlDocEnTranslation // html-document
29
+        }
24 30
       },
25 31
       fr: {
26
-        translation: {...langFr.translation, ...fr.translation}
32
+        translation: {
33
+          ...frLib, // fronted_lib
34
+          ...fr, // frontend
35
+          ...htmlDocFrTranslation // html-document
36
+        }
27 37
       }
28 38
     }
29 39
   })

+ 3 - 1
frontend_app_html-document/package.json View File

@@ -7,8 +7,9 @@
7 7
     "servdev": "NODE_ENV=development webpack-dev-server --watch --colors --inline --hot --progress",
8 8
     "servdevwindoz": "set NODE_ENV=development&& webpack-dev-server --watch --colors --inline --hot --progress",
9 9
     "servdev-dashboard": "NODE_ENV=development webpack-dashboard -m -p 9871 -- webpack-dev-server --watch --colors --inline --hot --progress",
10
-    "buildwindoz": "set NODE_ENV=production&& webpack -p",
11 10
     "build": "NODE_ENV=production webpack -p",
11
+    "build-translation": "node i18next.scanner.js",
12
+    "buildwindoz": "set NODE_ENV=production&& webpack -p",
12 13
     "test": "echo \"Error: no test specified\" && exit 1"
13 14
   },
14 15
   "author": "",
@@ -41,6 +42,7 @@
41 42
     "whatwg-fetch": "^2.0.3"
42 43
   },
43 44
   "devDependencies": {
45
+    "i18next-scanner": "^2.6.1",
44 46
     "webpack-dashboard": "^1.1.1",
45 47
     "webpack-dev-server": "^2.9.2"
46 48
   },

+ 0 - 13
frontend_app_html-document/rebuild_html-document.sh View File

@@ -1,13 +0,0 @@
1
-#!/bin/bash
2
-
3
-. ../bash_library.sh # source bash_library.sh
4
-
5
-windoz=""
6
-if  [[ $1 = "-w" ]]; then
7
-    windoz="windoz"
8
-fi
9
-
10
-log "npm run build$windoz"
11
-npm run build$windoz
12
-log "cp dist/html-document.app.js ../frontend/dist/app"
13
-cp dist/html-document.app.js ../frontend/dist/app

+ 10 - 4
frontend_app_html-document/src/container/HtmlDocument.jsx View File

@@ -1,6 +1,9 @@
1 1
 import React from 'react'
2 2
 import HtmlDocumentComponent from '../component/HtmlDocument.jsx'
3
+import { translate } from 'react-i18next'
4
+import i18n from '../i18n.js'
3 5
 import {
6
+  addAllResourceI18n,
4 7
   handleFetchResult,
5 8
   PopinFixed,
6 9
   PopinFixedHeader,
@@ -20,13 +23,12 @@ import {
20 23
   putHtmlDocContent,
21 24
   putHtmlDocStatus
22 25
 } from '../action.async.js'
23
-import i18n from '../i18n.js'
24 26
 
25 27
 class HtmlDocument extends React.Component {
26 28
   constructor (props) {
27 29
     super(props)
28 30
     this.state = {
29
-      appName: 'html-documents',
31
+      appName: 'html-document',
30 32
       isVisible: true,
31 33
       config: props.data ? props.data.config : debug.config,
32 34
       loggedUser: props.data ? props.data.loggedUser : debug.loggedUser,
@@ -38,6 +40,9 @@ class HtmlDocument extends React.Component {
38 40
       mode: MODE.VIEW
39 41
     }
40 42
 
43
+    // i18n has been init, add resources from frontend
44
+    addAllResourceI18n(i18n, props.data ? props.data.config.translation : debug.config.translation)
45
+
41 46
     document.addEventListener('appCustomEvent', this.customEventReducer)
42 47
   }
43 48
 
@@ -284,6 +289,7 @@ class HtmlDocument extends React.Component {
284 289
 
285 290
   render () {
286 291
     const { isVisible, loggedUser, content, timeline, newComment, timelineWysiwyg, config, mode } = this.state
292
+    const { t } = this.props
287 293
 
288 294
     if (!isVisible) return null
289 295
 
@@ -321,7 +327,7 @@ class HtmlDocument extends React.Component {
321 327
                   style={{backgroundColor: config.hexcolor, color: '#fdfdfd'}}
322 328
                 >
323 329
                   <i className='fa fa-code-fork' />
324
-                  Dernière version
330
+                  {t('Last version')}
325 331
                 </button>
326 332
               }
327 333
             </div>
@@ -381,4 +387,4 @@ class HtmlDocument extends React.Component {
381 387
   }
382 388
 }
383 389
 
384
-export default HtmlDocument
390
+export default translate()(HtmlDocument)

+ 5 - 0
frontend_app_html-document/src/container/PopupCreateHtmlDocument.jsx View File

@@ -3,6 +3,8 @@ import {
3 3
   CardPopupCreateContent, handleFetchResult
4 4
 } from 'tracim_frontend_lib'
5 5
 import { postHtmlDocContent } from '../action.async.js'
6
+import {addAllResourceForI18n, addAllResourceI18n} from '../../../frontend_lib'
7
+import i18n from '../i18n.js'
6 8
 
7 9
 const debug = { // outdated
8 10
   config: {
@@ -42,6 +44,9 @@ class PopupCreateHtmlDocument extends React.Component {
42 44
       idFolder: props.data ? props.data.idFolder : debug.idFolder,
43 45
       newContentName: ''
44 46
     }
47
+
48
+    // i18n has been init, add resources from frontend
49
+    addAllResourceI18n(i18n, props.data ? props.data.config.translation : debug.config.translation)
45 50
   }
46 51
 
47 52
   handleChangeNewContentName = e => this.setState({newContentName: e.target.value})

+ 13 - 1
frontend_app_html-document/src/helper.js View File

@@ -51,7 +51,19 @@ export const debug = {
51 51
       faIcon: 'warning',
52 52
       hexcolor: '#ababab',
53 53
       globalStatus: 'closed'
54
-    }]
54
+    }],
55
+    translation: {
56
+      en: {
57
+        translation: {
58
+          'Last version': 'Last version debug en'
59
+        }
60
+      },
61
+      fr: {
62
+        translation: {
63
+          'Last version': 'Dernière version debug fr'
64
+        }
65
+      }
66
+    }
55 67
   },
56 68
   loggedUser: { // @FIXME this object is outdated
57 69
     user_id: 5,

+ 1 - 11
frontend_app_html-document/src/i18n.js View File

@@ -1,8 +1,5 @@
1 1
 import i18n from 'i18next'
2 2
 import { reactI18nextModule } from 'react-i18next'
3
-import { langFr, langEn } from 'tracim_frontend_lib'
4
-import fr from './translate/fr.js'
5
-import en from './translate/en.js'
6 3
 
7 4
 i18n
8 5
   .use(reactI18nextModule)
@@ -18,14 +15,7 @@ i18n
18 15
     react: {
19 16
       wait: true
20 17
     },
21
-    resources: {
22
-      en: {
23
-        translation: {...langEn.translation, ...en.translation}
24
-      },
25
-      fr: {
26
-        translation: {...langFr.translation, ...fr.translation}
27
-      }
28
-    }
18
+    resources: {} // init with empty resources, they will come from frontend in app constructor
29 19
   })
30 20
 
31 21
 export default i18n

+ 2 - 0
frontend_app_thread/package.json View File

@@ -8,6 +8,7 @@
8 8
     "servdevwindoz": "set NODE_ENV=development&& webpack-dev-server --watch --colors --inline --hot --progress",
9 9
     "servdev-dashboard": "NODE_ENV=development webpack-dashboard -m -p 9872 -- webpack-dev-server --watch --colors --inline --hot --progress",
10 10
     "build": "NODE_ENV=production webpack -p",
11
+    "build-translation": "node i18next.scanner.js",
11 12
     "buildwindoz": "set NODE_ENV=production&& webpack -p",
12 13
     "test": "echo \"Error: no test specified\" && exit 1"
13 14
   },
@@ -41,6 +42,7 @@
41 42
     "whatwg-fetch": "^2.0.3"
42 43
   },
43 44
   "devDependencies": {
45
+    "i18next-scanner": "^2.6.1",
44 46
     "webpack-dashboard": "^1.1.1",
45 47
     "webpack-dev-server": "^2.9.2"
46 48
   },

+ 0 - 13
frontend_app_thread/rebuild_thread.sh View File

@@ -1,13 +0,0 @@
1
-#!/bin/bash
2
-
3
-. ../bash_library.sh # source bash_library.sh
4
-
5
-windoz=""
6
-if  [[ $1 = "-w" ]]; then
7
-    windoz="windoz"
8
-fi
9
-
10
-log "npm run build$windoz"
11
-npm run build$windoz
12
-log "cp dist/thread.app.js ../frontend/dist/app"
13
-cp dist/thread.app.js ../frontend/dist/app

+ 12 - 0
frontend_app_thread/src/container/PopupCreateThread.jsx View File

@@ -1,5 +1,6 @@
1 1
 import React from 'react'
2 2
 import {
3
+  addAllResourceI18n,
3 4
   CardPopupCreateContent,
4 5
   handleFetchResult
5 6
 } from 'tracim_frontend_lib'
@@ -19,6 +20,14 @@ const debug = { // outdated
19 20
       'Accept': 'application/json',
20 21
       'Content-Type': 'application/json',
21 22
       'Authorization': 'Basic ' + btoa(`${'admin@admin.admin'}:${'admin@admin.admin'}`)
23
+    },
24
+    translation: {
25
+      en: {
26
+        translation: {}
27
+      },
28
+      fr: {
29
+        translation: {}
30
+      }
22 31
     }
23 32
   },
24 33
   loggedUser: {
@@ -44,6 +53,9 @@ class PopupCreateHtmlDocument extends React.Component {
44 53
       idFolder: props.data ? props.data.idFolder : debug.idFolder,
45 54
       newContentName: ''
46 55
     }
56
+
57
+    // i18n has been init, add resources from frontend
58
+    addAllResourceI18n(i18n, props.data ? props.data.config.translation : debug.config.translation)
47 59
   }
48 60
 
49 61
   handleChangeNewContentName = e => this.setState({newContentName: e.target.value})

+ 4 - 0
frontend_app_thread/src/container/Thread.jsx View File

@@ -2,6 +2,7 @@ import React from 'react'
2 2
 import i18n from '../i18n.js'
3 3
 import { debug } from '../helper.js'
4 4
 import {
5
+  addAllResourceI18n,
5 6
   handleFetchResult,
6 7
   PopinFixed,
7 8
   PopinFixedHeader,
@@ -33,6 +34,9 @@ class Thread extends React.Component {
33 34
       timelineWysiwyg: false
34 35
     }
35 36
 
37
+    // i18n has been init, add resources from frontend
38
+    addAllResourceI18n(i18n, props.data ? props.data.config.translation : debug.config.translation)
39
+
36 40
     document.addEventListener('appCustomEvent', this.customEventReducer)
37 41
   }
38 42
 

+ 2 - 2
frontend_lib/src/component/Input/SelectStatus/SelectStatus.jsx View File

@@ -27,7 +27,7 @@ export const SelectStatus = props => {
27 27
       </button>
28 28
 
29 29
       <div className='selectStatus__submenu dropdown-menu' aria-labelledby='dropdownMenu2'>
30
-        <h6 className='dropdown-header'>{props.t('Input.SelectStatus.file_status')}</h6>
30
+        <h6 className='dropdown-header'>{props.t('File status')}</h6>
31 31
 
32 32
         <div className='dropdown-divider' />
33 33
 
@@ -39,7 +39,7 @@ export const SelectStatus = props => {
39 39
             key={`status_${s.slug}`}
40 40
             style={{color: s.hexcolor}}
41 41
           >
42
-            {s.label /* props.t('Input.SelectStatus.ongoing') */}
42
+            {s.label}
43 43
             <div className='selectStatus__submenu__item__icon'>
44 44
               <i className={`fa fa-fw fa-${s.faIcon}`} />
45 45
             </div>

+ 8 - 0
frontend_lib/src/helper.js View File

@@ -20,3 +20,11 @@ export const libHandleFetchResult = async fetchResult => {
20 20
       return new Promise((resolve, reject) => reject(fetchResult)) // @TODO : handle errors from api result
21 21
   }
22 22
 }
23
+
24
+export const libAddAllResourceI18n = (i18n, translation) => {
25
+  Object.keys(translation).forEach(lang =>
26
+    Object.keys(translation[lang]).forEach(namespace =>
27
+      i18n.addResources(lang, namespace, translation[lang][namespace])
28
+    )
29
+  )
30
+}

+ 5 - 1
frontend_lib/src/index.js View File

@@ -1,4 +1,6 @@
1
-import { libHandleFetchResult } from './helper.js'
1
+import { libAddAllResourceI18n, libHandleFetchResult } from './helper.js'
2
+
3
+// fr and en are deprecated
2 4
 import fr from './translate/fr.js'
3 5
 import en from './translate/en.js'
4 6
 
@@ -24,6 +26,8 @@ import libSelectStatus from './component/Input/SelectStatus/SelectStatus.jsx'
24 26
 export const langFr = fr
25 27
 export const langEn = en
26 28
 
29
+export const addAllResourceI18n = libAddAllResourceI18n
30
+
27 31
 export const handleFetchResult = libHandleFetchResult
28 32
 
29 33
 export const PopinFixed = libPopinFixed

+ 8 - 0
install_frontend_dependencies.sh View File

@@ -18,6 +18,14 @@ log "npm link tracim_frontend_lib"
18 18
 npm link tracim_frontend_lib
19 19
 cd -
20 20
 
21
+log "cd frontend_app_thread"
22
+cd frontend_app_thread
23
+log "npm i"
24
+npm i
25
+log "npm link tracim_frontend_lib"
26
+npm link tracim_frontend_lib
27
+cd -
28
+
21 29
 log "cd frontend"
22 30
 cd frontend
23 31
 log "npm i"