mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
MM-52261: Remove boards language selector, use Language in Display Settings (#23095)
Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
parent
a1470c77ac
commit
657c0024f9
@ -259,7 +259,6 @@
|
||||
"Sidebar.no-boards-in-category": "No boards inside",
|
||||
"Sidebar.product-tour": "Product tour",
|
||||
"Sidebar.random-icons": "Random icons",
|
||||
"Sidebar.set-language": "Set language",
|
||||
"Sidebar.set-theme": "Set theme",
|
||||
"Sidebar.settings": "Settings",
|
||||
"Sidebar.template-from-board": "New template from board",
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React, {useEffect} from 'react'
|
||||
import {IntlProvider} from 'react-intl'
|
||||
import {DndProvider} from 'react-dnd'
|
||||
import {HTML5Backend} from 'react-dnd-html5-backend'
|
||||
import {TouchBackend} from 'react-dnd-touch-backend'
|
||||
@ -9,12 +8,10 @@ import {History} from 'history'
|
||||
|
||||
import TelemetryClient from './telemetry/telemetryClient'
|
||||
|
||||
import {getMessages} from './i18n'
|
||||
import FlashMessages from './components/flashMessages'
|
||||
import NewVersionBanner from './components/newVersionBanner'
|
||||
import {Utils} from './utils'
|
||||
import {fetchMe, getMe} from './store/users'
|
||||
import {fetchLanguage, getLanguage} from './store/language'
|
||||
import {useAppDispatch, useAppSelector} from './store/hooks'
|
||||
import {fetchClientConfig} from './store/clientConfig'
|
||||
import FocalboardRouter from './router'
|
||||
@ -26,12 +23,10 @@ type Props = {
|
||||
}
|
||||
|
||||
const App = (props: Props): JSX.Element => {
|
||||
const language = useAppSelector<string>(getLanguage)
|
||||
const me = useAppSelector<IUser|null>(getMe)
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchLanguage())
|
||||
dispatch(fetchMe())
|
||||
dispatch(fetchClientConfig())
|
||||
}, [])
|
||||
@ -43,20 +38,15 @@ const App = (props: Props): JSX.Element => {
|
||||
}, [me])
|
||||
|
||||
return (
|
||||
<IntlProvider
|
||||
locale={language.split(/[_]/)[0]}
|
||||
messages={getMessages(language)}
|
||||
>
|
||||
<DndProvider backend={Utils.isMobile() ? TouchBackend : HTML5Backend}>
|
||||
<FlashMessages milliseconds={2000}/>
|
||||
<div id='frame'>
|
||||
<div id='main'>
|
||||
<NewVersionBanner/>
|
||||
<FocalboardRouter history={props.history}/>
|
||||
</div>
|
||||
<DndProvider backend={Utils.isMobile() ? TouchBackend : HTML5Backend}>
|
||||
<FlashMessages milliseconds={2000}/>
|
||||
<div id='frame'>
|
||||
<div id='main'>
|
||||
<NewVersionBanner/>
|
||||
<FocalboardRouter history={props.history}/>
|
||||
</div>
|
||||
</DndProvider>
|
||||
</IntlProvider>
|
||||
</div>
|
||||
</DndProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,11 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React, {useCallback, useMemo, useState} from 'react'
|
||||
import {FormattedMessage, IntlProvider, useIntl} from 'react-intl'
|
||||
import {FormattedMessage, useIntl} from 'react-intl'
|
||||
import debounce from 'lodash/debounce'
|
||||
|
||||
import {SuiteWindow} from 'src/types/index'
|
||||
|
||||
import {getMessages} from 'src/i18n'
|
||||
import {getLanguage} from 'src/store/language'
|
||||
|
||||
import {useWebsockets} from 'src/hooks/websockets'
|
||||
|
||||
import octoClient from 'src/octoClient'
|
||||
@ -220,17 +217,4 @@ const BoardSelector = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const IntlBoardSelector = () => {
|
||||
const language = useAppSelector<string>(getLanguage)
|
||||
|
||||
return (
|
||||
<IntlProvider
|
||||
locale={language.split(/[_]/)[0]}
|
||||
messages={getMessages(language)}
|
||||
>
|
||||
<BoardSelector/>
|
||||
</IntlProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default IntlBoardSelector
|
||||
export default BoardSelector
|
||||
|
@ -1,19 +1,17 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import {FormattedMessage, IntlProvider, useIntl} from 'react-intl'
|
||||
import {FormattedMessage, useIntl} from 'react-intl'
|
||||
|
||||
import WithWebSockets from 'src/components/withWebSockets'
|
||||
import {useWebsockets} from 'src/hooks/websockets'
|
||||
|
||||
import {getLanguage} from 'src/store/language'
|
||||
import {useAppSelector} from 'src/store/hooks'
|
||||
import {getCurrentTeamId} from 'src/store/teams'
|
||||
|
||||
import {MMWebSocketClient, WSClient} from 'src/wsclient'
|
||||
import manifest from 'src/manifest'
|
||||
|
||||
import {getMessages} from 'src/i18n'
|
||||
import {Utils} from 'src/utils'
|
||||
import {Block} from 'src/blocks/block'
|
||||
import {Card} from 'src/blocks/card'
|
||||
@ -278,17 +276,4 @@ export const BoardsUnfurl = (props: Props): JSX.Element => {
|
||||
)
|
||||
}
|
||||
|
||||
const IntlBoardsUnfurl = (props: Props) => {
|
||||
const language = useAppSelector<string>(getLanguage)
|
||||
|
||||
return (
|
||||
<IntlProvider
|
||||
locale={language.split(/[_]/)[0]}
|
||||
messages={getMessages(language)}
|
||||
>
|
||||
<BoardsUnfurl {...props}/>
|
||||
</IntlProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default IntlBoardsUnfurl
|
||||
export default BoardsUnfurl
|
||||
|
@ -7,8 +7,6 @@ import React, {
|
||||
useState,
|
||||
} from 'react'
|
||||
|
||||
import {IntlProvider, createIntl, createIntlCache} from 'react-intl'
|
||||
|
||||
import Select from 'react-select/async'
|
||||
import {
|
||||
FormatOptionLabelMeta,
|
||||
@ -20,10 +18,9 @@ import {
|
||||
|
||||
import {CSSObject} from '@emotion/serialize'
|
||||
|
||||
import {getCurrentLanguage, getMessages} from 'src/i18n'
|
||||
import {getLanguage} from 'src/store/language'
|
||||
import {useIntl} from 'react-intl'
|
||||
|
||||
import CompassIcon from 'src/widgets/icons/compassIcon'
|
||||
import {useAppSelector} from 'src/store/hooks'
|
||||
import {mutator} from 'src/mutator'
|
||||
import {useGetAllTemplates} from 'src/hooks/useGetAllTemplates'
|
||||
|
||||
@ -46,12 +43,6 @@ type ReactSelectItem = {
|
||||
const EMPTY_BOARD = 'empty_board'
|
||||
const TEMPLATE_DESCRIPTION_LENGTH = 70
|
||||
|
||||
const cache = createIntlCache()
|
||||
const intl = createIntl({
|
||||
locale: getCurrentLanguage(),
|
||||
messages: getMessages(getCurrentLanguage()),
|
||||
}, cache)
|
||||
|
||||
const {ValueContainer, Placeholder} = components
|
||||
const CustomValueContainer = ({children, ...props}: any) => {
|
||||
return (
|
||||
@ -67,6 +58,7 @@ const CustomValueContainer = ({children, ...props}: any) => {
|
||||
}
|
||||
|
||||
const CreateBoardFromTemplate = (props: Props) => {
|
||||
const intl = useIntl()
|
||||
const {formatMessage} = intl
|
||||
|
||||
const [addBoard, setAddBoard] = useState(false)
|
||||
@ -259,17 +251,4 @@ const CreateBoardFromTemplate = (props: Props) => {
|
||||
)
|
||||
}
|
||||
|
||||
const IntlCreateBoardFromTemplate = (props: Props) => {
|
||||
const language = useAppSelector<string>(getLanguage)
|
||||
|
||||
return (
|
||||
<IntlProvider
|
||||
locale={language.split(/[_]/)[0]}
|
||||
messages={getMessages(language)}
|
||||
>
|
||||
<CreateBoardFromTemplate {...props}/>
|
||||
</IntlProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default IntlCreateBoardFromTemplate
|
||||
export default CreateBoardFromTemplate
|
||||
|
@ -238,24 +238,6 @@ exports[`components/sidebar/GlobalHeaderSettingsMenu imports menu open should ma
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="MenuOption SubMenuOption menu-option open-left"
|
||||
id="lang"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Set language
|
||||
</div>
|
||||
<i
|
||||
class="CompassIcon icon-chevron-right"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="Random icons"
|
||||
@ -390,499 +372,6 @@ exports[`components/sidebar/GlobalHeaderSettingsMenu languages menu open should
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="MenuOption SubMenuOption menu-option open-left menu-option-active"
|
||||
id="lang"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Set language
|
||||
</div>
|
||||
<i
|
||||
class="CompassIcon icon-chevron-right"
|
||||
/>
|
||||
<div
|
||||
class="SubMenu Menu noselect left-bottom"
|
||||
>
|
||||
<div
|
||||
class="menu-contents"
|
||||
>
|
||||
<div
|
||||
class="menu-options"
|
||||
>
|
||||
<div
|
||||
aria-label="English"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
English
|
||||
</div>
|
||||
</div>
|
||||
<svg
|
||||
class="CheckIcon Icon"
|
||||
viewBox="0 0 100 100"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<polyline
|
||||
points="20,60 40,80 80,40"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Español"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Español
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Deutsch"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Deutsch
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="日本語"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
日本語
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Français"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Français
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Nederlands"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Nederlands
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Pусский"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Pусский
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="中文 (繁體)"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
中文 (繁體)
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="中文 (简体)"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
中文 (简体)
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Türkçe"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Türkçe
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Occitan"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Occitan
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Português (Brasil)"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Português (Brasil)
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Català"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Català
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Ελληνικά"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Ελληνικά
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="bahasa Indonesia"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
bahasa Indonesia
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Italiano"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Italiano
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Svenska"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Svenska
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="menu-spacer hideOnWidescreen"
|
||||
/>
|
||||
<div
|
||||
class="menu-options hideOnWidescreen"
|
||||
>
|
||||
<div
|
||||
aria-label="Cancel"
|
||||
class="MenuOption TextOption menu-option menu-cancel"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Cancel
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="Random icons"
|
||||
@ -1039,24 +528,6 @@ exports[`components/sidebar/GlobalHeaderSettingsMenu settings menu open should m
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="MenuOption SubMenuOption menu-option open-left"
|
||||
id="lang"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Set language
|
||||
</div>
|
||||
<i
|
||||
class="CompassIcon icon-chevron-right"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
aria-label="Random icons"
|
||||
|
@ -3,14 +3,10 @@
|
||||
//
|
||||
import React from 'react'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
import {IntlProvider} from 'react-intl'
|
||||
import {History} from 'history'
|
||||
|
||||
import HelpIcon from 'src/widgets/icons/help'
|
||||
import store from 'src/store'
|
||||
import {useAppSelector} from 'src/store/hooks'
|
||||
import {getLanguage} from 'src/store/language'
|
||||
import {getMessages} from 'src/i18n'
|
||||
|
||||
import {Constants} from 'src/constants'
|
||||
|
||||
@ -23,27 +19,21 @@ type HeaderItemProps = {
|
||||
}
|
||||
|
||||
const HeaderItems = (props: HeaderItemProps) => {
|
||||
const language = useAppSelector<string>(getLanguage)
|
||||
const helpUrl = 'https://www.focalboard.com/fwlink/doc-boards.html?v=' + Constants.versionString
|
||||
|
||||
return (
|
||||
<IntlProvider
|
||||
locale={language.split(/[_]/)[0]}
|
||||
messages={getMessages(language)}
|
||||
>
|
||||
<div className='GlobalHeaderComponent'>
|
||||
<span className='spacer'/>
|
||||
<a
|
||||
href={helpUrl}
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
className='GlobalHeaderComponent__button help-button'
|
||||
>
|
||||
<HelpIcon/>
|
||||
</a>
|
||||
<GlobalHeaderSettingsMenu history={props.history}/>
|
||||
</div>
|
||||
</IntlProvider>
|
||||
<div className='GlobalHeaderComponent'>
|
||||
<span className='spacer'/>
|
||||
<a
|
||||
href={helpUrl}
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
className='GlobalHeaderComponent__button help-button'
|
||||
>
|
||||
<HelpIcon/>
|
||||
</a>
|
||||
<GlobalHeaderSettingsMenu history={props.history}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -8,13 +8,11 @@ import {Archiver} from 'src/archiver'
|
||||
import Menu from 'src/widgets/menu'
|
||||
import MenuWrapper from 'src/widgets/menuWrapper'
|
||||
import {useAppDispatch, useAppSelector} from 'src/store/hooks'
|
||||
import {storeLanguage} from 'src/store/language'
|
||||
import {getMe, patchProps} from 'src/store/users'
|
||||
import {Team, getCurrentTeam} from 'src/store/teams'
|
||||
import {IUser, UserConfigPatch} from 'src/user'
|
||||
import octoClient from 'src/octoClient'
|
||||
import {UserSettings} from 'src/userSettings'
|
||||
import CheckIcon from 'src/widgets/icons/check'
|
||||
import SettingsIcon from 'src/widgets/icons/settings'
|
||||
|
||||
import {Constants} from 'src/constants'
|
||||
@ -72,23 +70,6 @@ const GlobalHeaderSettingsMenu = (props: Props) => {
|
||||
))
|
||||
}
|
||||
</Menu.SubMenu>
|
||||
<Menu.SubMenu
|
||||
id='lang'
|
||||
name={intl.formatMessage({id: 'Sidebar.set-language', defaultMessage: 'Set language'})}
|
||||
position='left-bottom'
|
||||
>
|
||||
{
|
||||
Constants.languages.map((language) => (
|
||||
<Menu.Text
|
||||
key={language.code}
|
||||
id={`${language.name}-lang`}
|
||||
name={language.displayName}
|
||||
onClick={async () => dispatch(storeLanguage(language.code))}
|
||||
rightIcon={intl.locale.toLowerCase() === language.code ? <CheckIcon/> : null}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</Menu.SubMenu>
|
||||
<Menu.Switch
|
||||
id='random-icons'
|
||||
name={intl.formatMessage({id: 'Sidebar.random-icons', defaultMessage: 'Random icons'})}
|
||||
|
@ -1,10 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React, {useEffect} from 'react'
|
||||
import {FormattedMessage, IntlProvider, useIntl} from 'react-intl'
|
||||
|
||||
import {getMessages} from 'src/i18n'
|
||||
import {getLanguage} from 'src/store/language'
|
||||
import {FormattedMessage, useIntl} from 'react-intl'
|
||||
|
||||
import {useWebsockets} from 'src/hooks/websockets'
|
||||
|
||||
@ -169,17 +166,4 @@ const RHSChannelBoards = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const IntlRHSChannelBoards = () => {
|
||||
const language = useAppSelector<string>(getLanguage)
|
||||
|
||||
return (
|
||||
<IntlProvider
|
||||
locale={language.split(/[_]/)[0]}
|
||||
messages={getMessages(language)}
|
||||
>
|
||||
<RHSChannelBoards/>
|
||||
</IntlProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default IntlRHSChannelBoards
|
||||
export default RHSChannelBoards
|
||||
|
@ -1,10 +1,8 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React from 'react'
|
||||
import {FormattedMessage, IntlProvider} from 'react-intl'
|
||||
import {FormattedMessage} from 'react-intl'
|
||||
|
||||
import {getMessages} from 'src/i18n'
|
||||
import {getLanguage} from 'src/store/language'
|
||||
import {getCurrentChannel} from 'src/store/channels'
|
||||
import {useAppSelector} from 'src/store/hooks'
|
||||
|
||||
@ -12,31 +10,25 @@ import appBarIcon from 'static/app-bar-icon.png'
|
||||
|
||||
const RHSChannelBoardsHeader = () => {
|
||||
const currentChannel = useAppSelector(getCurrentChannel)
|
||||
const language = useAppSelector<string>(getLanguage)
|
||||
|
||||
if (!currentChannel) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<IntlProvider
|
||||
locale={language.split(/[_]/)[0]}
|
||||
messages={getMessages(language)}
|
||||
>
|
||||
<div>
|
||||
<img
|
||||
className='boards-rhs-header-logo'
|
||||
src={appBarIcon}
|
||||
<div>
|
||||
<img
|
||||
className='boards-rhs-header-logo'
|
||||
src={appBarIcon}
|
||||
/>
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id='rhs-channel-boards-header.title'
|
||||
defaultMessage='Boards'
|
||||
/>
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id='rhs-channel-boards-header.title'
|
||||
defaultMessage='Boards'
|
||||
/>
|
||||
</span>
|
||||
<span className='style--none sidebar--right__title__subtitle'>{currentChannel.display_name}</span>
|
||||
</div>
|
||||
</IntlProvider>
|
||||
</span>
|
||||
<span className='style--none sidebar--right__title__subtitle'>{currentChannel.display_name}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -263,24 +263,6 @@ exports[`components/sidebar/SidebarSettingsMenu imports menu open should match s
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="MenuOption SubMenuOption menu-option"
|
||||
id="lang"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Set language
|
||||
</div>
|
||||
<i
|
||||
class="CompassIcon icon-chevron-right"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="MenuOption SubMenuOption menu-option"
|
||||
@ -431,499 +413,6 @@ exports[`components/sidebar/SidebarSettingsMenu languages menu open should match
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="MenuOption SubMenuOption menu-option menu-option-active"
|
||||
id="lang"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Set language
|
||||
</div>
|
||||
<i
|
||||
class="CompassIcon icon-chevron-right"
|
||||
/>
|
||||
<div
|
||||
class="SubMenu Menu noselect top"
|
||||
>
|
||||
<div
|
||||
class="menu-contents"
|
||||
>
|
||||
<div
|
||||
class="menu-options"
|
||||
>
|
||||
<div
|
||||
aria-label="English"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
English
|
||||
</div>
|
||||
</div>
|
||||
<svg
|
||||
class="CheckIcon Icon"
|
||||
viewBox="0 0 100 100"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<polyline
|
||||
points="20,60 40,80 80,40"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Español"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Español
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Deutsch"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Deutsch
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="日本語"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
日本語
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Français"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Français
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Nederlands"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Nederlands
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Pусский"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Pусский
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="中文 (繁體)"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
中文 (繁體)
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="中文 (简体)"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
中文 (简体)
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Türkçe"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Türkçe
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Occitan"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Occitan
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Português (Brasil)"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Português (Brasil)
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Català"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Català
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Ελληνικά"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Ελληνικά
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="bahasa Indonesia"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
bahasa Indonesia
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Italiano"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Italiano
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
aria-label="Svenska"
|
||||
class="MenuOption TextOption menu-option"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Svenska
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="menu-spacer hideOnWidescreen"
|
||||
/>
|
||||
<div
|
||||
class="menu-options hideOnWidescreen"
|
||||
>
|
||||
<div
|
||||
aria-label="Cancel"
|
||||
class="MenuOption TextOption menu-option menu-cancel"
|
||||
role="button"
|
||||
>
|
||||
<div
|
||||
class="d-flex"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="menu-option__content"
|
||||
>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Cancel
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="MenuOption SubMenuOption menu-option"
|
||||
@ -1094,24 +583,6 @@ exports[`components/sidebar/SidebarSettingsMenu settings menu open should match
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="MenuOption SubMenuOption menu-option"
|
||||
id="lang"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Set language
|
||||
</div>
|
||||
<i
|
||||
class="CompassIcon icon-chevron-right"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="MenuOption SubMenuOption menu-option"
|
||||
@ -1262,24 +733,6 @@ exports[`components/sidebar/SidebarSettingsMenu theme menu open should match sna
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="MenuOption SubMenuOption menu-option"
|
||||
id="lang"
|
||||
>
|
||||
<div
|
||||
class="noicon"
|
||||
/>
|
||||
<div
|
||||
class="menu-name"
|
||||
>
|
||||
Set language
|
||||
</div>
|
||||
<i
|
||||
class="CompassIcon icon-chevron-right"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="MenuOption SubMenuOption menu-option menu-option-active"
|
||||
|
@ -17,8 +17,7 @@ import {
|
||||
} from 'src/theme'
|
||||
import Menu from 'src/widgets/menu'
|
||||
import MenuWrapper from 'src/widgets/menuWrapper'
|
||||
import {useAppDispatch, useAppSelector} from 'src/store/hooks'
|
||||
import {storeLanguage} from 'src/store/language'
|
||||
import {useAppSelector} from 'src/store/hooks'
|
||||
import {Team, getCurrentTeam} from 'src/store/teams'
|
||||
import {UserSettings} from 'src/userSettings'
|
||||
|
||||
@ -34,7 +33,6 @@ type Props = {
|
||||
|
||||
const SidebarSettingsMenu = (props: Props) => {
|
||||
const intl = useIntl()
|
||||
const dispatch = useAppDispatch()
|
||||
const currentTeam = useAppSelector<Team|null>(getCurrentTeam)
|
||||
|
||||
// we need this as the sidebar doesn't always need to re-render
|
||||
@ -123,23 +121,6 @@ const SidebarSettingsMenu = (props: Props) => {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Menu.SubMenu
|
||||
id='lang'
|
||||
name={intl.formatMessage({id: 'Sidebar.set-language', defaultMessage: 'Set language'})}
|
||||
position='top'
|
||||
>
|
||||
{
|
||||
Constants.languages.map((language) => (
|
||||
<Menu.Text
|
||||
key={language.code}
|
||||
id={`${language.name}-lang`}
|
||||
name={language.displayName}
|
||||
onClick={async () => dispatch(storeLanguage(language.code))}
|
||||
rightIcon={intl.locale.toLowerCase() === language.code ? <CheckIcon/> : null}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</Menu.SubMenu>
|
||||
<Menu.SubMenu
|
||||
id='theme'
|
||||
name={intl.formatMessage({id: 'Sidebar.set-theme', defaultMessage: 'Set theme'})}
|
||||
|
@ -5,79 +5,81 @@ import messages_ca from 'i18n/ca.json'
|
||||
import messages_de from 'i18n/de.json'
|
||||
import messages_el from 'i18n/el.json'
|
||||
import messages_en from 'i18n/en.json'
|
||||
import messages_enAu from 'i18n/en_AU.json'
|
||||
import messages_es from 'i18n/es.json'
|
||||
import messages_fa from 'i18n/fa.json'
|
||||
import messages_fr from 'i18n/fr.json'
|
||||
import messages_hu from 'i18n/hu.json'
|
||||
import messages_id from 'i18n/id.json'
|
||||
import messages_it from 'i18n/it.json'
|
||||
import messages_ja from 'i18n/ja.json'
|
||||
import messages_ko from 'i18n/ko.json'
|
||||
import messages_nl from 'i18n/nl.json'
|
||||
import messages_oc from 'i18n/oc.json'
|
||||
import messages_pl from 'i18n/pl.json'
|
||||
import messages_ptBr from 'i18n/pt_BR.json'
|
||||
import messages_ru from 'i18n/ru.json'
|
||||
import messages_sv from 'i18n/sv.json'
|
||||
import messages_tr from 'i18n/tr.json'
|
||||
import messages_uk from 'i18n/uk.json'
|
||||
import messages_zhHans from 'i18n/zh_Hans.json'
|
||||
import messages_zhHant from 'i18n/zh_Hant.json'
|
||||
|
||||
import {UserSettings} from './userSettings'
|
||||
|
||||
const supportedLanguages = ['ca', 'de', 'el', 'en', 'es', 'fr', 'id', 'it', 'ja', 'nl', 'oc', 'pt-br', 'ru', 'sv', 'tr', 'zh-cn', 'zh-tw']
|
||||
|
||||
export function getMessages(lang: string): {[key: string]: string} {
|
||||
switch (lang) {
|
||||
export function getMessages(locale: string): {[key: string]: string} {
|
||||
switch (locale) {
|
||||
// case 'bg':
|
||||
// return messages_bg // TODO missing translation sourcefile
|
||||
case 'ca':
|
||||
return messages_ca
|
||||
return messages_ca // TODO missing option in language selector
|
||||
case 'de':
|
||||
return messages_de
|
||||
case 'el':
|
||||
return messages_el
|
||||
return messages_el // TODO missing option in language selector
|
||||
case 'en':
|
||||
default:
|
||||
return messages_en
|
||||
case 'en-AU':
|
||||
return messages_enAu
|
||||
case 'es':
|
||||
return messages_es
|
||||
case 'fa':
|
||||
return messages_fa
|
||||
case 'fr':
|
||||
return messages_fr
|
||||
case 'hu':
|
||||
return messages_hu
|
||||
case 'id':
|
||||
return messages_id
|
||||
return messages_id // TODO missing option in language selector
|
||||
case 'it':
|
||||
return messages_it
|
||||
case 'ja':
|
||||
return messages_ja
|
||||
case 'ko':
|
||||
return messages_ko
|
||||
case 'nl':
|
||||
return messages_nl
|
||||
case 'oc':
|
||||
return messages_oc
|
||||
case 'pt-br':
|
||||
return messages_oc // TODO missing option in language selector
|
||||
case 'pl':
|
||||
return messages_pl
|
||||
case 'pt-BR':
|
||||
return messages_ptBr
|
||||
|
||||
// case 'ro':
|
||||
// return messages_ro // TODO missing translation sourcefile
|
||||
case 'ru':
|
||||
return messages_ru
|
||||
case 'sv':
|
||||
return messages_sv
|
||||
case 'tr':
|
||||
return messages_tr
|
||||
case 'zh-cn':
|
||||
case 'uk':
|
||||
return messages_uk
|
||||
case 'zh-Hans':
|
||||
case 'zh-CN':
|
||||
return messages_zhHans
|
||||
case 'zh-Hant':
|
||||
case 'zh-TW':
|
||||
return messages_zhHant
|
||||
case 'zh-tx':
|
||||
return messages_zhHans
|
||||
case 'zh-tw':
|
||||
return messages_zhHans
|
||||
}
|
||||
|
||||
return messages_en
|
||||
}
|
||||
export function getCurrentLanguage(): string {
|
||||
let lang = UserSettings.language
|
||||
if (!lang) {
|
||||
if (supportedLanguages.includes(navigator.language)) {
|
||||
lang = navigator.language
|
||||
} else if (supportedLanguages.includes(navigator.language.split(/[-_]/)[0])) {
|
||||
lang = navigator.language.split(/[-_]/)[0]
|
||||
} else {
|
||||
lang = 'en'
|
||||
}
|
||||
}
|
||||
|
||||
return lang
|
||||
}
|
||||
|
||||
export function storeLanguage(lang: string): void {
|
||||
UserSettings.language = lang
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React, {useEffect} from 'react'
|
||||
import {createIntl, createIntlCache} from 'react-intl'
|
||||
import {FormattedMessage} from 'react-intl'
|
||||
import {Action, Store} from 'redux'
|
||||
import {Provider as ReduxProvider} from 'react-redux'
|
||||
import {History, createBrowserHistory} from 'history'
|
||||
@ -21,7 +21,7 @@ import {Constants} from 'src/constants'
|
||||
import {setTeam} from 'src/store/teams'
|
||||
|
||||
import {UserSettings} from 'src/userSettings'
|
||||
import {getCurrentLanguage, getMessages} from 'src/i18n'
|
||||
import {getMessages} from 'src/i18n'
|
||||
|
||||
const windowAny = (window as SuiteWindow)
|
||||
windowAny.baseURL = '/plugins/boards'
|
||||
@ -232,13 +232,6 @@ export default class Plugin {
|
||||
windowAny.frontendBaseURL = subpath + windowAny.frontendBaseURL
|
||||
windowAny.baseURL = subpath + windowAny.baseURL
|
||||
browserHistory = customHistory()
|
||||
const cache = createIntlCache()
|
||||
const intl = createIntl({
|
||||
|
||||
// modeled after <IntlProvider> in app.tsx
|
||||
locale: getCurrentLanguage(),
|
||||
messages: getMessages(getCurrentLanguage()),
|
||||
}, cache)
|
||||
|
||||
this.registry = registry
|
||||
|
||||
@ -248,6 +241,16 @@ export default class Plugin {
|
||||
|
||||
const productID = 'boards'
|
||||
|
||||
registry.registerTranslations((locale: string) => {
|
||||
try {
|
||||
const messages = getMessages(locale)
|
||||
|
||||
return messages
|
||||
} catch {
|
||||
return {}
|
||||
}
|
||||
})
|
||||
|
||||
// register websocket handlers
|
||||
this.registry?.registerWebSocketEventHandler(`custom_${productID}_${ACTION_UPDATE_BOARD}`, (e: any) => wsClient.updateHandler(e.data))
|
||||
this.registry?.registerWebSocketEventHandler(`custom_${productID}_${ACTION_UPDATE_CATEGORY}`, (e: any) => wsClient.updateHandler(e.data))
|
||||
@ -389,11 +392,25 @@ export default class Plugin {
|
||||
}
|
||||
|
||||
if (registry.registerChannelIntroButtonAction) {
|
||||
this.channelHeaderButtonId = registry.registerChannelIntroButtonAction(<FocalboardIcon/>, goToFocalboardTemplate, intl.formatMessage({id: 'ChannelIntro.CreateBoard', defaultMessage: 'Create a board'}))
|
||||
this.channelHeaderButtonId = registry.registerChannelIntroButtonAction(
|
||||
<FocalboardIcon/>,
|
||||
goToFocalboardTemplate,
|
||||
<FormattedMessage
|
||||
id='ChannelIntro.CreateBoard'
|
||||
defaultMessage='Create a board'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (this.registry.registerAppBarComponent) {
|
||||
this.registry.registerAppBarComponent(appBarIcon, () => mmStore.dispatch(toggleRHSPlugin), intl.formatMessage({id: 'AppBar.Tooltip', defaultMessage: 'Toggle linked boards'}))
|
||||
this.registry.registerAppBarComponent(
|
||||
appBarIcon,
|
||||
() => mmStore.dispatch(toggleRHSPlugin),
|
||||
<FormattedMessage
|
||||
id='AppBar.Tooltip'
|
||||
defaultMessage='Toggle linked boards'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (this.registry.registerActionAfterChannelCreation) {
|
||||
@ -447,13 +464,23 @@ export default class Plugin {
|
||||
if (siteStats) {
|
||||
return {
|
||||
boards_count: {
|
||||
name: intl.formatMessage({id: 'SiteStats.total_boards', defaultMessage: 'Total boards'}),
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id='SiteStats.total_boards'
|
||||
defaultMessage='Total boards'
|
||||
/>
|
||||
),
|
||||
id: 'total_boards',
|
||||
icon: 'icon-product-boards',
|
||||
value: siteStats.board_count,
|
||||
},
|
||||
cards_count: {
|
||||
name: intl.formatMessage({id: 'SiteStats.total_cards', defaultMessage: 'Total cards'}),
|
||||
name: (
|
||||
<FormattedMessage
|
||||
id='SiteStats.total_cards'
|
||||
defaultMessage='Total cards'
|
||||
/>
|
||||
),
|
||||
id: 'total_cards',
|
||||
icon: 'icon-products',
|
||||
value: siteStats.card_count,
|
||||
|
@ -3,7 +3,6 @@
|
||||
import React from 'react'
|
||||
import {Router, Switch} from 'react-router-dom'
|
||||
|
||||
import {IntlProvider} from 'react-intl'
|
||||
import {DndProvider} from 'react-dnd'
|
||||
import {HTML5Backend} from 'react-dnd-html5-backend'
|
||||
import {TouchBackend} from 'react-dnd-touch-backend'
|
||||
@ -12,12 +11,9 @@ import {createBrowserHistory} from 'history'
|
||||
import BoardPage from 'src/pages/boardPage/boardPage'
|
||||
import FBRoute from 'src/route'
|
||||
|
||||
import {getMessages} from 'src/i18n'
|
||||
import FlashMessages from 'src/components/flashMessages'
|
||||
import NewVersionBanner from 'src/components/newVersionBanner'
|
||||
import {Utils} from 'src/utils'
|
||||
import {getLanguage} from 'src/store/language'
|
||||
import {useAppSelector} from 'src/store/hooks'
|
||||
|
||||
export const publicBaseURL = () => {
|
||||
return Utils.getFrontendBaseURL() + '/public'
|
||||
@ -38,23 +34,16 @@ const PublicRouter = () => {
|
||||
}
|
||||
|
||||
const PublicApp = (): JSX.Element => {
|
||||
const language = useAppSelector<string>(getLanguage)
|
||||
|
||||
return (
|
||||
<IntlProvider
|
||||
locale={language.split(/[_]/)[0]}
|
||||
messages={getMessages(language)}
|
||||
>
|
||||
<DndProvider backend={Utils.isMobile() ? TouchBackend : HTML5Backend}>
|
||||
<FlashMessages milliseconds={2000}/>
|
||||
<div id='frame'>
|
||||
<div id='main'>
|
||||
<NewVersionBanner/>
|
||||
<PublicRouter/>
|
||||
</div>
|
||||
<DndProvider backend={Utils.isMobile() ? TouchBackend : HTML5Backend}>
|
||||
<FlashMessages milliseconds={2000}/>
|
||||
<div id='frame'>
|
||||
<div id='main'>
|
||||
<NewVersionBanner/>
|
||||
<PublicRouter/>
|
||||
</div>
|
||||
</DndProvider>
|
||||
</IntlProvider>
|
||||
</div>
|
||||
</DndProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ import {configureStore} from '@reduxjs/toolkit'
|
||||
import {reducer as usersReducer} from './users'
|
||||
import {reducer as teamsReducer} from './teams'
|
||||
import {reducer as channelsReducer} from './channels'
|
||||
import {reducer as languageReducer} from './language'
|
||||
import {reducer as globalTemplatesReducer} from './globalTemplates'
|
||||
import {reducer as boardsReducer} from './boards'
|
||||
import {reducer as viewsReducer} from './views'
|
||||
@ -25,7 +24,6 @@ const store = configureStore({
|
||||
users: usersReducer,
|
||||
teams: teamsReducer,
|
||||
channels: channelsReducer,
|
||||
language: languageReducer,
|
||||
globalTemplates: globalTemplatesReducer,
|
||||
boards: boardsReducer,
|
||||
views: viewsReducer,
|
||||
|
@ -1,46 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {PayloadAction, createAsyncThunk, createSlice} from '@reduxjs/toolkit'
|
||||
|
||||
import {getCurrentLanguage, storeLanguage as i18nStoreLanguage} from 'src/i18n'
|
||||
|
||||
import {RootState} from './index'
|
||||
|
||||
export const fetchLanguage = createAsyncThunk(
|
||||
'language/fetch',
|
||||
async () => getCurrentLanguage(),
|
||||
)
|
||||
|
||||
export const storeLanguage = createAsyncThunk(
|
||||
'language/store',
|
||||
(lang: string) => {
|
||||
i18nStoreLanguage(lang)
|
||||
|
||||
return lang
|
||||
},
|
||||
)
|
||||
|
||||
const languageSlice = createSlice({
|
||||
name: 'language',
|
||||
initialState: {value: 'en'} as {value: string},
|
||||
reducers: {
|
||||
setLanguage: (state, action: PayloadAction<string>) => {
|
||||
state.value = action.payload
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder.addCase(fetchLanguage.fulfilled, (state, action) => {
|
||||
state.value = action.payload
|
||||
})
|
||||
builder.addCase(storeLanguage.fulfilled, (state, action) => {
|
||||
state.value = action.payload
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
export const {reducer} = languageSlice
|
||||
|
||||
export function getLanguage(state: RootState): string {
|
||||
return state.language.value
|
||||
}
|
@ -8,9 +8,10 @@ import type {Channel, ChannelMembership} from '@mattermost/types/channels'
|
||||
type ReactResolvable = React.ReactNode | React.ElementType
|
||||
|
||||
export interface PluginRegistry {
|
||||
registerTranslations(getTranslationsForLocale: (locale: string) => Record<string, string>): void
|
||||
registerPostTypeComponent(typeName: string, component: ReactResolvable): any
|
||||
registerChannelHeaderButtonAction(icon: ReactResolvable, action: () => void, dropdownText: string, tooltipText: string): any
|
||||
registerChannelIntroButtonAction(icon: ReactResolvable, action: () => void, tooltipText: string): any
|
||||
registerChannelIntroButtonAction(icon: ReactResolvable, action: () => void, tooltipText: ReactResolvable): any
|
||||
registerCustomRoute(route: string, component: ReactResolvable): any
|
||||
registerProductRoute(route: string, component: ReactResolvable): any
|
||||
unregisterComponent(componentId: string): any
|
||||
|
@ -25,7 +25,6 @@ const PluggableIntroButtons = React.memo((props: Props) => {
|
||||
key={buttonProps.id}
|
||||
className={'intro-links color--link channelIntroButton style--none'}
|
||||
onClick={() => buttonProps.action?.(props.channel, props.channelMember)}
|
||||
aria-label={buttonProps.text}
|
||||
>
|
||||
{buttonProps.icon}
|
||||
{buttonProps.text}
|
||||
|
@ -208,7 +208,7 @@ export default class PluginRegistry {
|
||||
// Accepts the following:
|
||||
// - icon - React element to use as the button's icon
|
||||
// - action - a function called when the button is clicked, passed the channel and channel member as arguments
|
||||
// - text - a localized string to use as the button's text
|
||||
// - text - a localized string or React element to use as the button's text
|
||||
registerChannelIntroButtonAction = reArg([
|
||||
'icon',
|
||||
'action',
|
||||
@ -220,8 +220,7 @@ export default class PluginRegistry {
|
||||
}: {
|
||||
icon: ReactResolvable;
|
||||
action: PluginComponent['action'];
|
||||
tooltipText: string;
|
||||
text: string;
|
||||
text: ReactResolvable;
|
||||
}) => {
|
||||
const id = generateId();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user