mirror of
https://github.com/strapi/strapi.git
synced 2025-12-11 15:04:33 +00:00
Merge branch 'core/admin-apis' of github.com:strapi/strapi into core/menu-api
This commit is contained in:
commit
c68f815a51
15
examples/getstarted/admin/admin.config.js
Normal file
15
examples/getstarted/admin/admin.config.js
Normal file
@ -0,0 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
webpack: (config, webpack) => {
|
||||
// Note: we provide webpack above so you should not `require` it
|
||||
// Perform customizations to webpack config
|
||||
// Important: return the modified config
|
||||
return config;
|
||||
},
|
||||
app: config => {
|
||||
config.locales = ['fr'];
|
||||
|
||||
return config;
|
||||
},
|
||||
};
|
||||
@ -1,3 +1,4 @@
|
||||
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginId from './pluginId';
|
||||
|
||||
@ -15,8 +16,6 @@ export default {
|
||||
isRequired: pluginPkg.strapi.required || false,
|
||||
mainComponent: () => 'My plugin',
|
||||
name,
|
||||
settings: null,
|
||||
trads: {},
|
||||
menu: {
|
||||
pluginsSectionLinks: [
|
||||
{
|
||||
@ -34,4 +33,27 @@ export default {
|
||||
});
|
||||
},
|
||||
boot() {},
|
||||
async registerTrads({ locales }) {
|
||||
const importedTrads = await Promise.all(
|
||||
locales.map(locale => {
|
||||
return import(
|
||||
/* webpackChunkName: "[pluginId]-[request]" */ `./translations/${locale}.json`
|
||||
)
|
||||
.then(({ default: data }) => {
|
||||
return {
|
||||
data: prefixPluginTranslations(data, pluginId),
|
||||
locale,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
data: {},
|
||||
locale,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.resolve(importedTrads);
|
||||
},
|
||||
};
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import getTrad from '../../utils/getTrad';
|
||||
|
||||
const App = () => {
|
||||
return <FormattedMessage id={getTrad('plugin.name')} defaultMessage="My plugin" />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"plugin.name": "My plugin"
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
import pluginId from '../pluginId';
|
||||
|
||||
const getTrad = id => `${pluginId}.${id}`;
|
||||
|
||||
export default getTrad;
|
||||
@ -54,7 +54,10 @@ module.exports = {
|
||||
],
|
||||
moduleNameMapper,
|
||||
rootDir: process.cwd(),
|
||||
setupFiles: ['<rootDir>/test/config/front/test-bundler.js'],
|
||||
setupFiles: [
|
||||
'<rootDir>/test/config/front/test-bundler.js',
|
||||
'<rootDir>/packages/admin-test-utils/lib/mocks/LocalStorageMock.js',
|
||||
],
|
||||
testPathIgnorePatterns: [
|
||||
'/node_modules/',
|
||||
'<rootDir>/examples/getstarted/',
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
const { combineReducers, createStore } = require('redux');
|
||||
|
||||
const reducers = {
|
||||
language: jest.fn(() => ({ locale: 'en' })),
|
||||
menu: jest.fn(() => ({
|
||||
generalSectionLinks: [
|
||||
{
|
||||
|
||||
25
packages/admin-test-utils/lib/mocks/LocalStorageMock.js
Normal file
25
packages/admin-test-utils/lib/mocks/LocalStorageMock.js
Normal file
@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
class LocalStorageMock {
|
||||
constructor() {
|
||||
this.store = {};
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.store = {};
|
||||
}
|
||||
|
||||
getItem(key) {
|
||||
return this.store[key] || null;
|
||||
}
|
||||
|
||||
setItem(key, value) {
|
||||
this.store[key] = String(value);
|
||||
}
|
||||
|
||||
removeItem(key) {
|
||||
delete this.store[key];
|
||||
}
|
||||
}
|
||||
|
||||
global.localStorage = new LocalStorageMock();
|
||||
@ -4,6 +4,7 @@ import { BrowserRouter } from 'react-router-dom';
|
||||
import { QueryClientProvider, QueryClient } from 'react-query';
|
||||
import { ThemeProvider } from 'styled-components';
|
||||
import { LibraryProvider, StrapiAppProvider } from '@strapi/helper-plugin';
|
||||
import pick from 'lodash/pick';
|
||||
import createHook from '@strapi/hooks';
|
||||
import invariant from 'invariant';
|
||||
import configureStore from './core/store/configureStore';
|
||||
@ -17,9 +18,7 @@ import Fonts from './components/Fonts';
|
||||
import GlobalStyle from './components/GlobalStyle';
|
||||
import Notifications from './components/Notifications';
|
||||
import themes from './themes';
|
||||
|
||||
// TODO
|
||||
import translations from './translations';
|
||||
import languageNativeNames from './translations/languageNativeNames';
|
||||
|
||||
window.strapi = {
|
||||
backendURL: process.env.STRAPI_ADMIN_BACKEND_URL,
|
||||
@ -33,16 +32,15 @@ const queryClient = new QueryClient({
|
||||
},
|
||||
});
|
||||
|
||||
const appLocales = Object.keys(translations);
|
||||
|
||||
class StrapiApp {
|
||||
constructor({ appPlugins, library, middlewares, reducers }) {
|
||||
constructor({ appPlugins, library, locales, middlewares, reducers }) {
|
||||
this.appLocales = ['en', ...locales.filter(loc => loc !== 'en')];
|
||||
this.appPlugins = appPlugins || {};
|
||||
this.library = library;
|
||||
this.middlewares = middlewares;
|
||||
this.plugins = {};
|
||||
this.reducers = reducers;
|
||||
this.translations = translations;
|
||||
this.translations = {};
|
||||
this.hooksDict = {};
|
||||
this.menu = [];
|
||||
this.settings = {
|
||||
@ -186,20 +184,51 @@ class StrapiApp {
|
||||
return this.plugins[pluginId];
|
||||
};
|
||||
|
||||
// FIXME
|
||||
registerPluginTranslations(pluginId, trads) {
|
||||
const pluginTranslations = appLocales.reduce((acc, currentLanguage) => {
|
||||
const currentLocale = trads[currentLanguage];
|
||||
async loadAdminTrads() {
|
||||
const arrayOfPromises = this.appLocales.map(locale => {
|
||||
return import(/* webpackChunkName: "[request]" */ `./translations/${locale}.json`)
|
||||
.then(({ default: data }) => {
|
||||
return { data, locale };
|
||||
})
|
||||
.catch(() => {
|
||||
return { data: {}, locale };
|
||||
});
|
||||
});
|
||||
const adminLocales = await Promise.all(arrayOfPromises);
|
||||
|
||||
if (currentLocale) {
|
||||
const localeprefixedWithPluginId = Object.keys(currentLocale).reduce((acc2, current) => {
|
||||
acc2[`${pluginId}.${current}`] = currentLocale[current];
|
||||
this.translations = adminLocales.reduce((acc, current) => {
|
||||
acc[current.locale] = current.data;
|
||||
|
||||
return acc2;
|
||||
}, {});
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
acc[currentLanguage] = localeprefixedWithPluginId;
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
async loadTrads() {
|
||||
const arrayOfPromises = Object.keys(this.appPlugins)
|
||||
.map(plugin => {
|
||||
const registerTrads = this.appPlugins[plugin].registerTrads;
|
||||
|
||||
if (registerTrads) {
|
||||
return registerTrads({ locales: this.appLocales });
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.filter(a => a);
|
||||
|
||||
const pluginsTrads = await Promise.all(arrayOfPromises);
|
||||
const mergedTrads = pluginsTrads.reduce((acc, currentPluginTrads) => {
|
||||
const pluginTrads = currentPluginTrads.reduce((acc1, current) => {
|
||||
acc1[current.locale] = current.data;
|
||||
|
||||
return acc1;
|
||||
}, {});
|
||||
|
||||
Object.keys(pluginTrads).forEach(locale => {
|
||||
acc[locale] = { ...acc[locale], ...pluginTrads[locale] };
|
||||
});
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
@ -207,19 +236,16 @@ class StrapiApp {
|
||||
this.translations = Object.keys(this.translations).reduce((acc, current) => {
|
||||
acc[current] = {
|
||||
...this.translations[current],
|
||||
...(pluginTranslations[current] || {}),
|
||||
...(mergedTrads[current] || {}),
|
||||
};
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
registerPlugin = pluginConf => {
|
||||
// FIXME
|
||||
// Translations should be loaded differently
|
||||
// This is a temporary fix
|
||||
this.registerPluginTranslations(pluginConf.id, pluginConf.trads);
|
||||
|
||||
const plugin = Plugin(pluginConf);
|
||||
|
||||
this.plugins[plugin.pluginId] = plugin;
|
||||
@ -245,6 +271,7 @@ class StrapiApp {
|
||||
|
||||
render() {
|
||||
const store = this.createStore();
|
||||
const localeNames = pick(languageNativeNames, this.appLocales);
|
||||
|
||||
const {
|
||||
components: { components },
|
||||
@ -266,7 +293,7 @@ class StrapiApp {
|
||||
settings={this.settings}
|
||||
>
|
||||
<LibraryProvider components={components} fields={fields}>
|
||||
<LanguageProvider messages={this.translations}>
|
||||
<LanguageProvider messages={this.translations} localeNames={localeNames}>
|
||||
<AutoReloadOverlayBlockerProvider>
|
||||
<OverlayBlocker>
|
||||
<Notifications>
|
||||
@ -286,5 +313,5 @@ class StrapiApp {
|
||||
}
|
||||
}
|
||||
|
||||
export default ({ appPlugins, library, middlewares, reducers }) =>
|
||||
new StrapiApp({ appPlugins, library, middlewares, reducers });
|
||||
export default ({ appPlugins, library, locales, middlewares, reducers }) =>
|
||||
new StrapiApp({ appPlugins, library, locales, middlewares, reducers });
|
||||
|
||||
7
packages/core/admin/admin/src/admin.config.js
Normal file
7
packages/core/admin/admin/src/admin.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
app: config => {
|
||||
config.locales = ['fr'];
|
||||
|
||||
return config;
|
||||
},
|
||||
};
|
||||
@ -1,16 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* LanguageProvider actions
|
||||
*
|
||||
*/
|
||||
|
||||
/* eslint-disable */
|
||||
|
||||
import { CHANGE_LOCALE } from './constants';
|
||||
|
||||
export function changeLocale(languageLocale) {
|
||||
return {
|
||||
type: CHANGE_LOCALE,
|
||||
locale: languageLocale,
|
||||
};
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* LanguageProvider constants
|
||||
*
|
||||
*/
|
||||
|
||||
/* eslint-disable */
|
||||
export const CHANGE_LOCALE = 'app/LanguageToggle/CHANGE_LOCALE';
|
||||
@ -1,14 +0,0 @@
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { changeLocale } from '../actions';
|
||||
|
||||
const useChangeLanguage = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const changeLanguage = nextLocale => {
|
||||
dispatch(changeLocale(nextLocale));
|
||||
};
|
||||
|
||||
return changeLanguage;
|
||||
};
|
||||
|
||||
export default useChangeLanguage;
|
||||
@ -6,44 +6,45 @@
|
||||
* IntlProvider component and i18n messages (loaded from `app/translations`)
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect, useReducer } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { defaultsDeep } from 'lodash';
|
||||
import { selectLocale } from './selectors';
|
||||
import defaultsDeep from 'lodash/defaultsDeep';
|
||||
import LocalesProvider from '../LocalesProvider';
|
||||
import localStorageKey from './utils/localStorageKey';
|
||||
import init from './init';
|
||||
import reducer, { initialState } from './reducer';
|
||||
|
||||
// eslint-disable-next-line react/prefer-stateless-function
|
||||
export class LanguageProvider extends React.Component {
|
||||
render() {
|
||||
const messages = defaultsDeep(this.props.messages[this.props.locale], this.props.messages.en);
|
||||
const LanguageProvider = ({ children, localeNames, messages }) => {
|
||||
const [{ locale }, dispatch] = useReducer(reducer, initialState, () => init(localeNames));
|
||||
|
||||
return (
|
||||
<IntlProvider
|
||||
locale={this.props.locale}
|
||||
defaultLocale="en"
|
||||
messages={messages}
|
||||
textComponent="span"
|
||||
>
|
||||
{React.Children.only(this.props.children)}
|
||||
</IntlProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
// Set user language in local storage.
|
||||
window.localStorage.setItem(localStorageKey, locale);
|
||||
}, [locale]);
|
||||
|
||||
const changeLocale = locale => {
|
||||
dispatch({
|
||||
type: 'CHANGE_LOCALE',
|
||||
locale,
|
||||
});
|
||||
};
|
||||
|
||||
const appMessages = defaultsDeep(messages[locale], messages.en);
|
||||
|
||||
return (
|
||||
<IntlProvider locale={locale} defaultLocale="en" messages={appMessages} textComponent="span">
|
||||
<LocalesProvider changeLocale={changeLocale} localeNames={localeNames} messages={appMessages}>
|
||||
{children}
|
||||
</LocalesProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
};
|
||||
|
||||
LanguageProvider.propTypes = {
|
||||
children: PropTypes.element.isRequired,
|
||||
locale: PropTypes.string.isRequired,
|
||||
localeNames: PropTypes.objectOf(PropTypes.string).isRequired,
|
||||
messages: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
const mapStateToProps = createSelector(selectLocale(), locale => ({ locale }));
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
dispatch,
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(LanguageProvider);
|
||||
export default LanguageProvider;
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
import localStorageKey from './utils/localStorageKey';
|
||||
|
||||
const init = localeNames => {
|
||||
const languageFromLocaleStorage = window.localStorage.getItem(localStorageKey);
|
||||
const appLanguage = localeNames[languageFromLocaleStorage] ? languageFromLocaleStorage : 'en';
|
||||
|
||||
return {
|
||||
locale: appLanguage,
|
||||
localeNames,
|
||||
};
|
||||
};
|
||||
|
||||
export default init;
|
||||
@ -4,47 +4,27 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import { get, includes, split } from 'lodash';
|
||||
|
||||
// Import supported languages from the translations folder
|
||||
import trads from '../../translations';
|
||||
import { CHANGE_LOCALE } from './constants';
|
||||
|
||||
const languages = Object.keys(trads);
|
||||
|
||||
// Define a key to store and get user preferences in local storage.
|
||||
const localStorageKey = 'strapi-admin-language';
|
||||
|
||||
// Detect user language.
|
||||
const userLanguage =
|
||||
window.localStorage.getItem(localStorageKey) ||
|
||||
window.navigator.language ||
|
||||
window.navigator.userLanguage;
|
||||
|
||||
let foundLanguage = includes(languages, userLanguage) && userLanguage;
|
||||
|
||||
if (!foundLanguage) {
|
||||
// Split user language in a correct format.
|
||||
const userLanguageShort = get(split(userLanguage, '-'), '0');
|
||||
|
||||
// Check that the language is included in the admin configuration.
|
||||
foundLanguage = includes(languages, userLanguageShort) && userLanguageShort;
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
locale: foundLanguage || 'en',
|
||||
localeNames: { en: 'English' },
|
||||
locale: 'en',
|
||||
};
|
||||
|
||||
function languageProviderReducer(state = initialState, action) {
|
||||
const languageProviderReducer = (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case CHANGE_LOCALE:
|
||||
// Set user language in local storage.
|
||||
window.localStorage.setItem(localStorageKey, action.locale);
|
||||
case 'CHANGE_LOCALE': {
|
||||
const { locale } = action;
|
||||
|
||||
return { ...state, locale: action.locale };
|
||||
default:
|
||||
if (!state.localeNames[locale]) {
|
||||
return state;
|
||||
}
|
||||
|
||||
return { ...state, locale };
|
||||
}
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default languageProviderReducer;
|
||||
export { initialState };
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
/**
|
||||
* Direct selector to the languageToggle state domain
|
||||
*/
|
||||
const selectLanguage = () => state => state.language;
|
||||
|
||||
/**
|
||||
* Select the language locale
|
||||
*/
|
||||
|
||||
const selectLocale = () => createSelector(selectLanguage(), languageState => languageState.locale);
|
||||
|
||||
const makeSelectLocale = () => createSelector(selectLocale(), locale => ({ locale }));
|
||||
|
||||
export default makeSelectLocale;
|
||||
export { selectLanguage, selectLocale };
|
||||
@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { useIntl } from 'react-intl';
|
||||
import useLocalesProvider from '../../LocalesProvider/useLocalesProvider';
|
||||
import LanguageProvider from '../index';
|
||||
import en from '../../../translations/en.json';
|
||||
import fr from '../../../translations/fr.json';
|
||||
|
||||
const messages = { en, fr };
|
||||
const localeNames = { en: 'English', fr: 'Français' };
|
||||
|
||||
describe('LanguageProvider', () => {
|
||||
afterEach(() => {
|
||||
localStorage.removeItem('strapi-admin-language');
|
||||
});
|
||||
|
||||
it('should not crash', () => {
|
||||
const { container } = render(
|
||||
<LanguageProvider messages={messages} localeNames={localeNames}>
|
||||
<div>Test</div>
|
||||
</LanguageProvider>
|
||||
);
|
||||
|
||||
expect(container.firstChild).toMatchInlineSnapshot(`
|
||||
<div>
|
||||
Test
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
|
||||
it('should change the locale and set the strapi-admin-language item in the localStorage', () => {
|
||||
const Test = () => {
|
||||
const { locale } = useIntl();
|
||||
const { changeLocale } = useLocalesProvider();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>{localeNames[locale]}</h1>
|
||||
<button type="button" onClick={() => changeLocale('fr')}>
|
||||
CHANGE
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
render(
|
||||
<LanguageProvider messages={messages} localeNames={localeNames}>
|
||||
<Test />
|
||||
</LanguageProvider>
|
||||
);
|
||||
|
||||
expect(localStorage.getItem('strapi-admin-language')).toEqual('en');
|
||||
|
||||
expect(screen.getByText('English')).toBeInTheDocument();
|
||||
|
||||
userEvent.click(screen.getByText('CHANGE'));
|
||||
|
||||
expect(screen.getByText('Français')).toBeInTheDocument();
|
||||
expect(localStorage.getItem('strapi-admin-language')).toEqual('fr');
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,34 @@
|
||||
import init from '../init';
|
||||
|
||||
const localeNames = { en: 'English', fr: 'Français' };
|
||||
|
||||
describe('LanguageProvider | init', () => {
|
||||
afterEach(() => {
|
||||
localStorage.removeItem('strapi-admin-language');
|
||||
});
|
||||
|
||||
it('should return the language from the localStorage', () => {
|
||||
localStorage.setItem('strapi-admin-language', 'fr');
|
||||
|
||||
expect(init(localeNames)).toEqual({
|
||||
locale: 'fr',
|
||||
localeNames,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return "en" when the strapi-admin-language is not set in the locale storage', () => {
|
||||
expect(init(localeNames)).toEqual({
|
||||
locale: 'en',
|
||||
localeNames,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return "en" when the language from the local storage is not included in the localeNames', () => {
|
||||
localStorage.setItem('strapi-admin-language', 'foo');
|
||||
|
||||
expect(init(localeNames)).toEqual({
|
||||
locale: 'en',
|
||||
localeNames,
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,41 @@
|
||||
import reducer, { initialState } from '../reducer';
|
||||
|
||||
describe('LanguageProvider | reducer', () => {
|
||||
let state;
|
||||
|
||||
beforeEach(() => {
|
||||
state = initialState;
|
||||
});
|
||||
|
||||
it('should return the initialState', () => {
|
||||
const action = { type: undefined };
|
||||
|
||||
expect(reducer(state, action)).toEqual(initialState);
|
||||
});
|
||||
|
||||
it('should change the locale correctly when the locale is defined in the localeNames', () => {
|
||||
state = {
|
||||
localeNames: { en: 'English', fr: 'Français' },
|
||||
locale: 'en',
|
||||
};
|
||||
|
||||
const action = { type: 'CHANGE_LOCALE', locale: 'fr' };
|
||||
const expected = {
|
||||
localeNames: { en: 'English', fr: 'Français' },
|
||||
locale: 'fr',
|
||||
};
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should not change the locale when the language is not defined in the localeNames', () => {
|
||||
state = {
|
||||
localeNames: { en: 'English', fr: 'Français' },
|
||||
locale: 'en',
|
||||
};
|
||||
|
||||
const action = { type: 'CHANGE_LOCALE', locale: 'foo' };
|
||||
|
||||
expect(reducer(state, action)).toEqual(state);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,3 @@
|
||||
const localStorageKey = 'strapi-admin-language';
|
||||
|
||||
export default localStorageKey;
|
||||
@ -4,76 +4,42 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { createStructuredSelector } from 'reselect';
|
||||
import { bindActionCreators, compose } from 'redux';
|
||||
import cn from 'classnames';
|
||||
import React, { useState } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { ButtonDropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap';
|
||||
import translationMessages, { languageNativeNames } from '../../translations';
|
||||
import makeSelectLocale from '../LanguageProvider/selectors';
|
||||
import { changeLocale } from '../LanguageProvider/actions';
|
||||
import useLocalesProvider from '../LocalesProvider/useLocalesProvider';
|
||||
import Wrapper from './Wrapper';
|
||||
|
||||
// TODO
|
||||
const languages = Object.keys(translationMessages);
|
||||
export class LocaleToggle extends React.Component {
|
||||
// eslint-disable-line
|
||||
state = { isOpen: false };
|
||||
const LocaleToggle = () => {
|
||||
const { changeLocale, localeNames } = useLocalesProvider();
|
||||
|
||||
toggle = () => this.setState(prevState => ({ isOpen: !prevState.isOpen }));
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const toggle = () => setIsOpen(prev => !prev);
|
||||
const { locale } = useIntl();
|
||||
|
||||
render() {
|
||||
const {
|
||||
currentLocale: { locale },
|
||||
} = this.props;
|
||||
return (
|
||||
<Wrapper>
|
||||
<ButtonDropdown isOpen={isOpen} toggle={toggle}>
|
||||
<DropdownToggle className="localeDropdownContent">
|
||||
<span>{localeNames[locale]}</span>
|
||||
</DropdownToggle>
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<ButtonDropdown isOpen={this.state.isOpen} toggle={this.toggle}>
|
||||
<DropdownToggle className="localeDropdownContent">
|
||||
<span>{languageNativeNames[locale]}</span>
|
||||
</DropdownToggle>
|
||||
|
||||
<DropdownMenu className="localeDropdownMenu">
|
||||
{languages.map(language => (
|
||||
<DropdownMenu className="localeDropdownMenu">
|
||||
{Object.keys(localeNames).map(lang => {
|
||||
return (
|
||||
<DropdownItem
|
||||
key={language}
|
||||
onClick={() => this.props.changeLocale(language)}
|
||||
className={cn(
|
||||
'localeToggleItem',
|
||||
locale === language ? 'localeToggleItemActive' : ''
|
||||
)}
|
||||
key={lang}
|
||||
onClick={() => changeLocale(lang)}
|
||||
className={`localeToggleItem ${locale === lang ? 'localeToggleItemActive' : ''}`}
|
||||
>
|
||||
{languageNativeNames[language]}
|
||||
{localeNames[lang]}
|
||||
</DropdownItem>
|
||||
))}
|
||||
</DropdownMenu>
|
||||
</ButtonDropdown>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
LocaleToggle.propTypes = {
|
||||
changeLocale: PropTypes.func.isRequired,
|
||||
currentLocale: PropTypes.object.isRequired,
|
||||
);
|
||||
})}
|
||||
</DropdownMenu>
|
||||
</ButtonDropdown>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
currentLocale: makeSelectLocale(),
|
||||
});
|
||||
|
||||
export function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(
|
||||
{
|
||||
changeLocale,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
}
|
||||
|
||||
const withConnect = connect(mapStateToProps, mapDispatchToProps);
|
||||
|
||||
export default compose(withConnect)(LocaleToggle);
|
||||
export default LocaleToggle;
|
||||
|
||||
@ -1,61 +1,217 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { DropdownItem } from 'reactstrap';
|
||||
import { changeLocale } from '../../LanguageProvider/actions';
|
||||
import { LocaleToggle, mapDispatchToProps } from '../index';
|
||||
import { render } from '@testing-library/react';
|
||||
import LanguageProvider from '../../LanguageProvider';
|
||||
import en from '../../../translations/en.json';
|
||||
import LocaleToggle from '../index';
|
||||
|
||||
const messages = { en };
|
||||
const localeNames = { en: 'English' };
|
||||
|
||||
describe('<LocaleToggle />', () => {
|
||||
let props;
|
||||
|
||||
beforeEach(() => {
|
||||
props = {
|
||||
changeLocale: jest.fn(),
|
||||
currentLocale: {
|
||||
locale: 'en',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it('should not crash', () => {
|
||||
shallow(<LocaleToggle {...props} />);
|
||||
});
|
||||
const App = (
|
||||
<LanguageProvider messages={messages} localeNames={localeNames}>
|
||||
<LocaleToggle />
|
||||
</LanguageProvider>
|
||||
);
|
||||
|
||||
describe('<LocaleToggle />, toggle instance', () => {
|
||||
it('should update the state when called', () => {
|
||||
const renderedComponent = shallow(<LocaleToggle {...props} />);
|
||||
const { toggle } = renderedComponent.instance();
|
||||
const { container } = render(App);
|
||||
expect(container.firstChild).toMatchInlineSnapshot(`
|
||||
.c0 {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
toggle();
|
||||
.c0 > div {
|
||||
height: 6rem;
|
||||
line-height: 5.8rem;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
expect(renderedComponent.state('isOpen')).toBe(true);
|
||||
});
|
||||
.c0 > div > button {
|
||||
width: 100%;
|
||||
padding: 0 30px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
color: #333740;
|
||||
font-weight: 500;
|
||||
text-align: right;
|
||||
cursor: pointer;
|
||||
-webkit-transition: background 0.2s ease-out;
|
||||
transition: background 0.2s ease-out;
|
||||
}
|
||||
|
||||
it('call the toggle handle on click', () => {
|
||||
const renderedComponent = shallow(<LocaleToggle {...props} />);
|
||||
renderedComponent.setState({ isOpen: true });
|
||||
const dropDown = renderedComponent.find(DropdownItem).at(0);
|
||||
dropDown.simulate('click');
|
||||
.c0 > div > button:hover,
|
||||
.c0 > div > button:focus,
|
||||
.c0 > div > button:active {
|
||||
color: #333740;
|
||||
background-color: #fafafb !important;
|
||||
}
|
||||
|
||||
expect(props.changeLocale).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
.c0 > div > button > i,
|
||||
.c0 > div > button > svg {
|
||||
margin-left: 10px;
|
||||
-webkit-transition: -webkit-transform 0.3s ease-out;
|
||||
-webkit-transition: transform 0.3s ease-out;
|
||||
transition: transform 0.3s ease-out;
|
||||
}
|
||||
|
||||
describe('<LocaleToggle />, mapDispatchToProps', () => {
|
||||
describe('changeLocale', () => {
|
||||
it('should be injected', () => {
|
||||
const dispatch = jest.fn();
|
||||
const result = mapDispatchToProps(dispatch);
|
||||
.c0 > div > button > i[alt='true'],
|
||||
.c0 > div > button > svg[alt='true'] {
|
||||
-webkit-transform: rotateX(180deg);
|
||||
-ms-transform: rotateX(180deg);
|
||||
transform: rotateX(180deg);
|
||||
}
|
||||
|
||||
expect(result.changeLocale).toBeDefined();
|
||||
});
|
||||
.c0 .localeDropdownContent {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
it('should dispatch the changeLocale action when called', () => {
|
||||
const dispatch = jest.fn();
|
||||
const result = mapDispatchToProps(dispatch);
|
||||
result.changeLocale();
|
||||
.c0 .localeDropdownContent span {
|
||||
color: #333740;
|
||||
font-size: 13px;
|
||||
font-family: Lato;
|
||||
font-weight: 500;
|
||||
-webkit-letter-spacing: 0.5;
|
||||
-moz-letter-spacing: 0.5;
|
||||
-ms-letter-spacing: 0.5;
|
||||
letter-spacing: 0.5;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
expect(dispatch).toHaveBeenCalledWith(changeLocale());
|
||||
});
|
||||
});
|
||||
.c0 .localeDropdownMenu {
|
||||
min-width: 90px !important;
|
||||
max-height: 162px !important;
|
||||
overflow: auto !important;
|
||||
margin: 0 !important;
|
||||
padding: 0;
|
||||
line-height: 1.8rem;
|
||||
border: none !important;
|
||||
border-top-left-radius: 0 !important;
|
||||
border-top-right-radius: 0 !important;
|
||||
box-shadow: 0 1px 4px 0px rgba(40,42,49,0.05);
|
||||
}
|
||||
|
||||
.c0 .localeDropdownMenu:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -3px;
|
||||
left: -1px;
|
||||
width: calc(100% + 1px);
|
||||
height: 3px;
|
||||
box-shadow: 0 1px 2px 0 rgba(40,42,49,0.16);
|
||||
}
|
||||
|
||||
.c0 .localeDropdownMenu > button {
|
||||
height: 40px;
|
||||
padding: 0px 15px;
|
||||
line-height: 40px;
|
||||
color: #f75b1d;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
-webkit-letter-spacing: 0.5;
|
||||
-moz-letter-spacing: 0.5;
|
||||
-ms-letter-spacing: 0.5;
|
||||
letter-spacing: 0.5;
|
||||
}
|
||||
|
||||
.c0 .localeDropdownMenu > button:hover,
|
||||
.c0 .localeDropdownMenu > button:focus,
|
||||
.c0 .localeDropdownMenu > button:active {
|
||||
background-color: #fafafb !important;
|
||||
border-radius: 0px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.c0 .localeDropdownMenu > button:first-child {
|
||||
line-height: 50px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.c0 .localeDropdownMenu > button:first-child:hover,
|
||||
.c0 .localeDropdownMenu > button:first-child:active {
|
||||
color: #333740;
|
||||
}
|
||||
|
||||
.c0 .localeDropdownMenu > button:not(:first-child) {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.c0 .localeDropdownMenu > button:not(:first-child) > i,
|
||||
.c0 .localeDropdownMenu > button:not(:first-child) > svg {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.c0 .localeDropdownMenuNotLogged {
|
||||
background: transparent !important;
|
||||
box-shadow: none !important;
|
||||
border: 1px solid #e3e9f3 !important;
|
||||
border-top: 0px !important;
|
||||
}
|
||||
|
||||
.c0 .localeDropdownMenuNotLogged button {
|
||||
padding-left: 17px;
|
||||
}
|
||||
|
||||
.c0 .localeDropdownMenuNotLogged button:hover {
|
||||
background-color: #f7f8f8 !important;
|
||||
}
|
||||
|
||||
.c0 .localeDropdownMenuNotLogged:before {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.c0 .localeToggleItem img {
|
||||
max-height: 13.37px;
|
||||
margin-left: 9px;
|
||||
}
|
||||
|
||||
.c0 .localeToggleItem:active {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.c0 .localeToggleItem:hover {
|
||||
background-color: #fafafb !important;
|
||||
}
|
||||
|
||||
.c0 .localeToggleItemActive {
|
||||
color: #333740 !important;
|
||||
}
|
||||
|
||||
<div
|
||||
class="c0"
|
||||
>
|
||||
<div
|
||||
class="btn-group"
|
||||
>
|
||||
<button
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
class="localeDropdownContent btn btn-secondary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
English
|
||||
</span>
|
||||
</button>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="localeDropdownMenu dropdown-menu"
|
||||
role="menu"
|
||||
tabindex="-1"
|
||||
>
|
||||
<button
|
||||
class="localeToggleItem localeToggleItemActive dropdown-item"
|
||||
role="menuitem"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
English
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
const LocalesProviderContext = createContext();
|
||||
|
||||
export default LocalesProviderContext;
|
||||
@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import LocalesProviderContext from './context';
|
||||
|
||||
const LocalesProvider = ({ changeLocale, children, localeNames, messages }) => {
|
||||
return (
|
||||
<LocalesProviderContext.Provider value={{ changeLocale, localeNames, messages }}>
|
||||
{children}
|
||||
</LocalesProviderContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
LocalesProvider.propTypes = {
|
||||
changeLocale: PropTypes.func.isRequired,
|
||||
children: PropTypes.element.isRequired,
|
||||
localeNames: PropTypes.object.isRequired,
|
||||
messages: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default LocalesProvider;
|
||||
@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import LocalesProvider from '../index';
|
||||
|
||||
describe('LocalesProvider', () => {
|
||||
it('should not crash', () => {
|
||||
const { container } = render(
|
||||
<LocalesProvider
|
||||
changeLocale={jest.fn()}
|
||||
localeNames={{ en: 'English' }}
|
||||
messages={{ en: {} }}
|
||||
>
|
||||
<div>Test</div>
|
||||
</LocalesProvider>
|
||||
);
|
||||
|
||||
expect(container.firstChild).toMatchInlineSnapshot(`
|
||||
<div>
|
||||
Test
|
||||
</div>
|
||||
`);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,10 @@
|
||||
import { useContext } from 'react';
|
||||
import LocalesProviderContext from './context';
|
||||
|
||||
const useLocalesProvider = () => {
|
||||
const { changeLocale, localeNames, messages } = useContext(LocalesProviderContext);
|
||||
|
||||
return { changeLocale, localeNames, messages };
|
||||
};
|
||||
|
||||
export default useLocalesProvider;
|
||||
@ -4,12 +4,12 @@ import PropTypes from 'prop-types';
|
||||
|
||||
import favicon from '../../favicon.png';
|
||||
|
||||
const PageTitle = ({ title }) => (
|
||||
<Helmet title={title} link={[{ rel: 'icon', type: 'image/png', href: favicon }]} />
|
||||
);
|
||||
const PageTitle = ({ title }) => {
|
||||
return <Helmet title={title} link={[{ rel: 'icon', type: 'image/png', href: favicon }]} />;
|
||||
};
|
||||
|
||||
PageTitle.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
title: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]).isRequired,
|
||||
};
|
||||
|
||||
export default memo(PageTitle);
|
||||
|
||||
@ -1,22 +1,37 @@
|
||||
import ReactDOM from 'react-dom';
|
||||
import StrapiApp from './StrapiApp';
|
||||
import { Components, Fields, Middlewares, Reducers } from './core/apis';
|
||||
import appCustomisations from './admin.config';
|
||||
import plugins from './plugins';
|
||||
import appReducers from './reducers';
|
||||
|
||||
const appConfig = {
|
||||
locales: [],
|
||||
};
|
||||
|
||||
const customConfig = appCustomisations.app(appConfig);
|
||||
|
||||
const library = {
|
||||
components: Components(),
|
||||
fields: Fields(),
|
||||
};
|
||||
const middlewares = Middlewares();
|
||||
const reducers = Reducers({ appReducers });
|
||||
const app = StrapiApp({ appPlugins: plugins, library, middlewares, reducers });
|
||||
const app = StrapiApp({
|
||||
appPlugins: plugins,
|
||||
library,
|
||||
locales: customConfig.locales,
|
||||
middlewares,
|
||||
reducers,
|
||||
});
|
||||
|
||||
const MOUNT_NODE = document.getElementById('app');
|
||||
|
||||
const run = async () => {
|
||||
await app.loadAdminTrads();
|
||||
await app.initialize();
|
||||
await app.boot();
|
||||
await app.loadTrads();
|
||||
|
||||
ReactDOM.render(app.render(), MOUNT_NODE);
|
||||
};
|
||||
|
||||
@ -13,13 +13,14 @@ import RBACProvider from '../../../components/RBACProvider';
|
||||
import Admin from '../index';
|
||||
|
||||
const messages = { en };
|
||||
const localeNames = { en: 'English' };
|
||||
|
||||
const store = fixtures.store.store;
|
||||
|
||||
const makeApp = (history, plugins) => (
|
||||
<Provider store={store}>
|
||||
<StrapiAppProvider plugins={plugins}>
|
||||
<LanguageProvider messages={messages}>
|
||||
<LanguageProvider messages={messages} localeNames={localeNames}>
|
||||
<Notifications>
|
||||
<AppInfosContext.Provider
|
||||
value={{ latestStrapiReleaseTag: 'v4', shouldUpdateStrapi: false }}
|
||||
|
||||
@ -6,7 +6,7 @@ import { BaselineAlignment, auth, useNotification, useQuery } from '@strapi/help
|
||||
import { Padded } from '@buffetjs/core';
|
||||
import PropTypes from 'prop-types';
|
||||
import forms from 'ee_else_ce/pages/AuthPage/utils/forms';
|
||||
|
||||
import useLocalesProvider from '../../components/LocalesProvider/useLocalesProvider';
|
||||
import NavTopRightWrapper from '../../components/NavTopRightWrapper';
|
||||
import PageTitle from '../../components/PageTitle';
|
||||
import LocaleToggle from '../../components/LocaleToggle';
|
||||
@ -14,12 +14,11 @@ import checkFormValidity from '../../utils/checkFormValidity';
|
||||
import formatAPIErrors from '../../utils/formatAPIErrors';
|
||||
import init from './init';
|
||||
import { initialState, reducer } from './reducer';
|
||||
import useChangeLanguage from '../../components/LanguageProvider/hooks/useChangeLanguage';
|
||||
|
||||
const AuthPage = ({ hasAdmin, setHasAdmin }) => {
|
||||
const toggleNotification = useNotification();
|
||||
const { push } = useHistory();
|
||||
const changeLocale = useChangeLanguage();
|
||||
const { changeLocale } = useLocalesProvider();
|
||||
const {
|
||||
params: { authType },
|
||||
} = useRouteMatch('/auth/:authType');
|
||||
|
||||
@ -108,7 +108,7 @@ const HomePage = ({ history: { push } }) => {
|
||||
return (
|
||||
<>
|
||||
<FormattedMessage id="HomePage.helmet.title">
|
||||
{title => <PageTitle title={title} />}
|
||||
{title => <PageTitle title={title[0]} />}
|
||||
</FormattedMessage>
|
||||
<Container className="container-fluid">
|
||||
<div className="row">
|
||||
|
||||
@ -4,25 +4,22 @@ import { Padded, Text } from '@buffetjs/core';
|
||||
import { Col } from 'reactstrap';
|
||||
import { get } from 'lodash';
|
||||
import { useIntl } from 'react-intl';
|
||||
import translationMessages, { languageNativeNames } from '../../translations';
|
||||
import ContainerFluid from '../../components/ContainerFluid';
|
||||
import useLocalesProvider from '../../components/LocalesProvider/useLocalesProvider';
|
||||
import PageTitle from '../../components/PageTitle';
|
||||
import SizedInput from '../../components/SizedInput';
|
||||
import { Header } from '../../components/Settings';
|
||||
import FormBloc from '../../components/FormBloc';
|
||||
import { useSettingsForm } from '../../hooks';
|
||||
import useChangeLanguage from '../../components/LanguageProvider/hooks/useChangeLanguage';
|
||||
import ProfilePageLabel from './components';
|
||||
import { form, schema } from './utils';
|
||||
|
||||
const languages = Object.keys(translationMessages);
|
||||
|
||||
const ProfilePage = () => {
|
||||
const changeLanguage = useChangeLanguage();
|
||||
const { changeLocale, localeNames } = useLocalesProvider();
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const onSubmitSuccessCb = data => {
|
||||
changeLanguage(data.preferedLanguage);
|
||||
changeLocale(data.preferedLanguage);
|
||||
auth.setUserInfo(data);
|
||||
};
|
||||
|
||||
@ -129,8 +126,8 @@ const ProfilePage = () => {
|
||||
selectedValue={get(modifiedData, 'preferedLanguage')}
|
||||
onChange={nextLocaleCode => setField('preferedLanguage', nextLocaleCode)}
|
||||
>
|
||||
{languages.map(language => {
|
||||
const langName = languageNativeNames[language];
|
||||
{Object.keys(localeNames).map(language => {
|
||||
const langName = localeNames[language];
|
||||
|
||||
return (
|
||||
<Option value={language} key={language}>
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import languageProviderReducer from './components/LanguageProvider/reducer';
|
||||
import menuReducer from './components/LeftMenu/reducer';
|
||||
import rbacProviderReducer from './components/RBACProvider/reducer';
|
||||
|
||||
const reducers = {
|
||||
language: languageProviderReducer,
|
||||
menu: menuReducer,
|
||||
rbacProvider: rbacProviderReducer,
|
||||
};
|
||||
|
||||
@ -6,10 +6,11 @@ import appReducers from '../reducers';
|
||||
const library = { fields: {}, components: {} };
|
||||
const middlewares = { middlewares: [] };
|
||||
const reducers = { reducers: appReducers };
|
||||
const locales = [];
|
||||
|
||||
describe('ADMIN | StrapiApp', () => {
|
||||
it('should render the app without plugins', () => {
|
||||
const app = StrapiApp({ middlewares, reducers, library });
|
||||
const app = StrapiApp({ middlewares, reducers, library, locales });
|
||||
const { container } = render(app.render());
|
||||
|
||||
expect(container.firstChild).toMatchInlineSnapshot(`
|
||||
@ -43,7 +44,7 @@ describe('ADMIN | StrapiApp', () => {
|
||||
});
|
||||
|
||||
it('should create a valid store', () => {
|
||||
const app = StrapiApp({ middlewares, reducers, library });
|
||||
const app = StrapiApp({ middlewares, reducers, library, locales });
|
||||
|
||||
const store = app.createStore();
|
||||
|
||||
@ -52,7 +53,7 @@ describe('ADMIN | StrapiApp', () => {
|
||||
|
||||
describe('Hook api', () => {
|
||||
it('runs the "moto" hooks in series', () => {
|
||||
const app = StrapiApp({ middlewares, reducers, library });
|
||||
const app = StrapiApp({ middlewares, reducers, library, locales });
|
||||
|
||||
app.createHook('hello');
|
||||
app.createHook('moto');
|
||||
@ -70,7 +71,7 @@ describe('ADMIN | StrapiApp', () => {
|
||||
});
|
||||
|
||||
it('runs the "moto" hooks in series asynchronously', async () => {
|
||||
const app = StrapiApp({ middlewares, reducers, library });
|
||||
const app = StrapiApp({ middlewares, reducers, library, locales });
|
||||
|
||||
app.createHook('hello');
|
||||
app.createHook('moto');
|
||||
@ -88,7 +89,7 @@ describe('ADMIN | StrapiApp', () => {
|
||||
});
|
||||
|
||||
it('runs the "moto" hooks in waterfall', () => {
|
||||
const app = StrapiApp({ middlewares, reducers, library });
|
||||
const app = StrapiApp({ middlewares, reducers, library, locales });
|
||||
|
||||
app.createHook('hello');
|
||||
app.createHook('moto');
|
||||
@ -104,7 +105,7 @@ describe('ADMIN | StrapiApp', () => {
|
||||
});
|
||||
|
||||
it('runs the "moto" hooks in waterfall asynchronously', async () => {
|
||||
const app = StrapiApp({ middlewares, reducers, library });
|
||||
const app = StrapiApp({ middlewares, reducers, library, locales });
|
||||
|
||||
app.createHook('hello');
|
||||
app.createHook('moto');
|
||||
@ -120,7 +121,7 @@ describe('ADMIN | StrapiApp', () => {
|
||||
});
|
||||
|
||||
it('runs the "moto" hooks in parallel', async () => {
|
||||
const app = StrapiApp({ middlewares, reducers, library });
|
||||
const app = StrapiApp({ middlewares, reducers, library, locales });
|
||||
|
||||
app.createHook('hello');
|
||||
app.createHook('moto');
|
||||
@ -140,14 +141,14 @@ describe('ADMIN | StrapiApp', () => {
|
||||
|
||||
describe('Settings api', () => {
|
||||
it('the settings should be defined', () => {
|
||||
const app = StrapiApp({ middlewares, reducers, library });
|
||||
const app = StrapiApp({ middlewares, reducers, library, locales });
|
||||
|
||||
expect(app.settings).toBeDefined();
|
||||
expect(app.settings.global).toBeDefined();
|
||||
});
|
||||
|
||||
it('should creates a new section', () => {
|
||||
const app = StrapiApp({ middlewares, reducers, library });
|
||||
const app = StrapiApp({ middlewares, reducers, library, locales });
|
||||
const section = { id: 'foo', intlLabel: { id: 'foo', defaultMessage: 'foo' } };
|
||||
const links = [
|
||||
{
|
||||
@ -164,7 +165,7 @@ describe('ADMIN | StrapiApp', () => {
|
||||
});
|
||||
|
||||
it('should add a link correctly to the global sectionn', () => {
|
||||
const app = StrapiApp({ middlewares, reducers, library });
|
||||
const app = StrapiApp({ middlewares, reducers, library, locales });
|
||||
const link = {
|
||||
Component: jest.fn(),
|
||||
to: '/bar',
|
||||
@ -179,7 +180,7 @@ describe('ADMIN | StrapiApp', () => {
|
||||
});
|
||||
|
||||
it('should add an array of links correctly to the global section', () => {
|
||||
const app = StrapiApp({ middlewares, reducers, library });
|
||||
const app = StrapiApp({ middlewares, reducers, library, locales });
|
||||
const links = [
|
||||
{
|
||||
Component: jest.fn(),
|
||||
|
||||
@ -1,85 +0,0 @@
|
||||
// FIXME:
|
||||
// Load only needed translations
|
||||
// import ar from './ar.json';
|
||||
// import cs from './cs.json';
|
||||
// import de from './de.json';
|
||||
// import dk from './dk.json';
|
||||
import en from './en.json';
|
||||
// import es from './es.json';
|
||||
import fr from './fr.json';
|
||||
// import he from './he.json';
|
||||
// import id from './id.json';
|
||||
// import it from './it.json';
|
||||
// import ja from './ja.json';
|
||||
// import ko from './ko.json';
|
||||
// import ms from './ms.json';
|
||||
// import nl from './nl.json';
|
||||
// import pl from './pl.json';
|
||||
// import ptBR from './pt-BR.json';
|
||||
// import pt from './pt.json';
|
||||
// import ru from './ru.json';
|
||||
// import th from './th.json';
|
||||
// import tr from './tr.json';
|
||||
// import vi from './vi.json';
|
||||
// import zhHans from './zh-Hans.json';
|
||||
// import zh from './zh.json';
|
||||
// import sk from './sk.json';
|
||||
// import uk from './uk.json';
|
||||
|
||||
const trads = {
|
||||
// ar,
|
||||
// cs,
|
||||
// de,
|
||||
// dk,
|
||||
en,
|
||||
// es,
|
||||
fr,
|
||||
// he,
|
||||
// id,
|
||||
// it,
|
||||
// ja,
|
||||
// ko,
|
||||
// ms,
|
||||
// nl,
|
||||
// pl,
|
||||
// 'pt-BR': ptBR,
|
||||
// pt,
|
||||
// ru,
|
||||
// sk,
|
||||
// th,
|
||||
// tr,
|
||||
// uk,
|
||||
// vi,
|
||||
// 'zh-Hans': zhHans,
|
||||
// zh,
|
||||
};
|
||||
|
||||
export const languageNativeNames = {
|
||||
// ar: 'العربية',
|
||||
// cs: 'Čeština',
|
||||
// de: 'Deutsch',
|
||||
// dk: 'Dansk',
|
||||
en: 'English',
|
||||
// es: 'Español',
|
||||
fr: 'Français',
|
||||
// he: 'עברית',
|
||||
// id: 'Indonesian',
|
||||
// it: 'Italiano',
|
||||
// ja: '日本語',
|
||||
// ko: '한국어',
|
||||
// ms: 'Melayu',
|
||||
// nl: 'Nederlands',
|
||||
// pl: 'Polski',
|
||||
// 'pt-BR': 'Português (Brasil)',
|
||||
// pt: 'Português (Portugal)',
|
||||
// ru: 'Русский',
|
||||
// sk: 'Slovenčina',
|
||||
// th: 'ไทย',
|
||||
// tr: 'Türkçe',
|
||||
// uk: 'Українська',
|
||||
// vi: 'Tiếng Việt',
|
||||
// 'zh-Hans': '中文 (简体)',
|
||||
// zh: '中文 (繁體)',
|
||||
};
|
||||
|
||||
export default trads;
|
||||
@ -0,0 +1,30 @@
|
||||
const languageNativeNames = {
|
||||
ar: 'العربية',
|
||||
cs: 'Čeština',
|
||||
de: 'Deutsch',
|
||||
dk: 'Dansk',
|
||||
en: 'English',
|
||||
es: 'Español',
|
||||
fr: 'Français',
|
||||
he: 'עברית',
|
||||
id: 'Indonesian',
|
||||
it: 'Italiano',
|
||||
ja: '日本語',
|
||||
ko: '한국어',
|
||||
ms: 'Melayu',
|
||||
nl: 'Nederlands',
|
||||
pl: 'Polski',
|
||||
'pt-BR': 'Português (Brasil)',
|
||||
pt: 'Português (Portugal)',
|
||||
ru: 'Русский',
|
||||
sk: 'Slovenčina',
|
||||
sv: 'Swedish',
|
||||
th: 'ไทย',
|
||||
tr: 'Türkçe',
|
||||
uk: 'Українська',
|
||||
vi: 'Tiếng Việt',
|
||||
'zh-Hans': '中文 (简体)',
|
||||
zh: '中文 (繁體)',
|
||||
};
|
||||
|
||||
export default languageNativeNames;
|
||||
@ -1,9 +1,15 @@
|
||||
import translationMessages, { languageNativeNames } from '../index';
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const languageNativeNames = require('../languageNativeNames').default;
|
||||
|
||||
const languages = fs
|
||||
.readdirSync(path.join(__dirname, '..'))
|
||||
.filter(file => file.includes('.json'))
|
||||
.map(file => file.replace('.json', ''));
|
||||
|
||||
describe('translations', () => {
|
||||
describe('languageNativeNames', () => {
|
||||
it('should has native name for every locale', () => {
|
||||
const languages = Object.keys(translationMessages);
|
||||
languages.forEach(language => {
|
||||
expect(typeof languageNativeNames[language] === 'string').toBe(true);
|
||||
expect(!!languageNativeNames[language]).toBe(true);
|
||||
|
||||
@ -199,6 +199,16 @@ async function createCacheDir(dir) {
|
||||
await copyCustomAdmin(path.join(dir, 'admin'), cacheDir);
|
||||
}
|
||||
|
||||
// Copy admin.config.js
|
||||
const customAdminConfigFilePath = path.join(dir, 'admin', 'admin.config.js');
|
||||
|
||||
if (fs.existsSync(customAdminConfigFilePath)) {
|
||||
await fs.copy(
|
||||
customAdminConfigFilePath,
|
||||
path.resolve(cacheDir, 'admin', 'src', 'admin.config.js')
|
||||
);
|
||||
}
|
||||
|
||||
// create plugins.js with plugins requires
|
||||
await createPluginsJs(pluginsToCopy, localPluginsToCopy, cacheDir);
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@
|
||||
"react-error-boundary": "3.1.1",
|
||||
"react-fast-compare": "^3.2.0",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-intl": "4.5.0",
|
||||
"react-intl": "5.20.2",
|
||||
"react-is": "^16.12.0",
|
||||
"react-loadable": "^5.5.0",
|
||||
"react-query": "3.8.3",
|
||||
|
||||
@ -4,12 +4,11 @@
|
||||
// Here's the file: strapi/docs/3.0.0-beta.x/guides/registering-a-field-in-admin.md
|
||||
// Also the strapi-generate-plugins/files/admin/src/index.js needs to be updated
|
||||
// IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
|
||||
|
||||
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginId from './pluginId';
|
||||
import pluginLogo from './assets/images/logo.svg';
|
||||
import reducers from './reducers';
|
||||
import trads from './translations';
|
||||
import pluginPermissions from './permissions';
|
||||
|
||||
const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
|
||||
@ -32,7 +31,6 @@ export default {
|
||||
isRequired: pluginPkg.strapi.required || false,
|
||||
name,
|
||||
pluginLogo,
|
||||
trads,
|
||||
menu: {
|
||||
pluginsSectionLinks: [
|
||||
{
|
||||
@ -49,4 +47,27 @@ export default {
|
||||
});
|
||||
},
|
||||
boot() {},
|
||||
async registerTrads({ locales }) {
|
||||
const importedTrads = await Promise.all(
|
||||
locales.map(locale => {
|
||||
return import(
|
||||
/* webpackChunkName: "content-manager-translation-[request]" */ `./translations/${locale}.json`
|
||||
)
|
||||
.then(({ default: data }) => {
|
||||
return {
|
||||
data: prefixPluginTranslations(data, pluginId),
|
||||
locale,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
data: {},
|
||||
locale,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.resolve(importedTrads);
|
||||
},
|
||||
};
|
||||
|
||||
@ -40,7 +40,7 @@ describe('Content manager | App | main', () => {
|
||||
uid: 'category',
|
||||
title: 'Categories',
|
||||
name: 'category',
|
||||
to: '/category',
|
||||
to: `/plugins/${pluginId}/collectionType/category`,
|
||||
kind: 'collectionType',
|
||||
isDisplayed: true,
|
||||
permissions: [
|
||||
@ -82,7 +82,7 @@ describe('Content manager | App | main', () => {
|
||||
const rootReducer = combineReducers(cmReducers);
|
||||
const store = createStore(rootReducer, { [`${pluginId}_app`]: contentManagerState });
|
||||
const history = createMemoryHistory();
|
||||
history.push('/plugins/content-manager/collectionType/category');
|
||||
history.push(`/plugins/${pluginId}`);
|
||||
|
||||
const { container } = render(
|
||||
<Provider store={store}>
|
||||
@ -94,6 +94,7 @@ describe('Content manager | App | main', () => {
|
||||
|
||||
expect(screen.getByText('Home page')).toBeVisible();
|
||||
expect(screen.getByText('Categories')).toBeVisible();
|
||||
expect(history.location.pathname).toEqual(`/plugins/${pluginId}/collectionType/category`);
|
||||
expect(container.firstChild).toMatchInlineSnapshot(`
|
||||
.c2 {
|
||||
margin-bottom: 0;
|
||||
@ -338,7 +339,9 @@ describe('Content manager | App | main', () => {
|
||||
>
|
||||
<li>
|
||||
<a
|
||||
href="/category"
|
||||
aria-current="page"
|
||||
class="active"
|
||||
href="/plugins/content-manager/collectionType/category"
|
||||
>
|
||||
<p>
|
||||
Categories
|
||||
@ -402,6 +405,53 @@ describe('Content manager | App | main', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should redirect to the single type', () => {
|
||||
const contentManagerState = {
|
||||
collectionTypeLinks: [],
|
||||
singleTypeLinks: [
|
||||
{
|
||||
uid: 'homepage',
|
||||
title: 'Home page',
|
||||
name: 'homepage',
|
||||
to: `/plugins/${pluginId}/homepage`,
|
||||
kind: 'singleType',
|
||||
isDisplayed: true,
|
||||
permissions: [
|
||||
{
|
||||
action: 'plugins::content-manager.explorer.read',
|
||||
subject: 'homepage',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
models: [
|
||||
{
|
||||
kind: 'collectionType',
|
||||
uid: 'category',
|
||||
info: { label: 'Categories', name: 'category' },
|
||||
},
|
||||
{ kind: 'singleType', uid: 'homepage', info: { label: 'Home page', name: 'homepage' } },
|
||||
],
|
||||
components: [],
|
||||
status: 'resolved',
|
||||
};
|
||||
useModels.mockImplementation(() => contentManagerState);
|
||||
const rootReducer = combineReducers(cmReducers);
|
||||
const store = createStore(rootReducer, { [`${pluginId}_app`]: contentManagerState });
|
||||
const history = createMemoryHistory();
|
||||
history.push(`/plugins/${pluginId}`);
|
||||
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<Router history={history}>
|
||||
<ContentManagerApp />
|
||||
</Router>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
expect(history.location.pathname).toEqual(`/plugins/${pluginId}/homepage`);
|
||||
});
|
||||
|
||||
it('should redirect to 403 page', () => {
|
||||
const history = createMemoryHistory();
|
||||
const contentManagerState = {
|
||||
@ -426,7 +476,7 @@ describe('Content manager | App | main', () => {
|
||||
);
|
||||
const rootReducer = combineReducers(cmReducers);
|
||||
const store = createStore(rootReducer, { [`${pluginId}_app`]: contentManagerState });
|
||||
history.push('/plugins/content-manager/collectionType/category');
|
||||
history.push(`/plugins/${pluginId}/collectionType/category`);
|
||||
|
||||
render(
|
||||
<Provider store={store}>
|
||||
@ -456,14 +506,11 @@ describe('Content manager | App | main', () => {
|
||||
);
|
||||
const rootReducer = combineReducers(cmReducers);
|
||||
const store = createStore(rootReducer, { [`${pluginId}_app`]: contentManagerState });
|
||||
history.push('/plugins/content-manager/collectionType/category');
|
||||
history.push(`/plugins/${pluginId}/collectionType/category`);
|
||||
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<Router
|
||||
history={history}
|
||||
// initialEntries={['/plugins/content-manager/collectionType/category']}
|
||||
>
|
||||
<Router history={history}>
|
||||
<ContentManagerApp />
|
||||
</Router>
|
||||
</Provider>
|
||||
|
||||
@ -163,7 +163,7 @@
|
||||
"permissions.not-allowed.update": "You are not allowed to see this document",
|
||||
"plugin.description.long": "Quick way to see, edit and delete the data in your database.",
|
||||
"plugin.description.short": "Quick way to see, edit and delete the data in your database.",
|
||||
"plugin.name": "Content manager",
|
||||
"plugin.name": "Content Manager",
|
||||
"popUpWarning.bodyMessage.contentType.delete": "Are you sure you want to delete this entry?",
|
||||
"popUpWarning.bodyMessage.contentType.delete.all": "Are you sure you want to delete these entries?",
|
||||
"popUpWarning.warning.cancelAllSettings": "Are you sure you want to cancel your modifications?",
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
// import ar from './ar.json';
|
||||
// import cs from './cs.json';
|
||||
// import de from './de.json';
|
||||
// import dk from './dk.json';
|
||||
import en from './en.json';
|
||||
// import es from './es.json';
|
||||
import fr from './fr.json';
|
||||
// import id from './id.json';
|
||||
// import it from './it.json';
|
||||
// import ja from './ja.json';
|
||||
// import ko from './ko.json';
|
||||
// import ms from './ms.json';
|
||||
// import nl from './nl.json';
|
||||
// import pl from './pl.json';
|
||||
// import ptBR from './pt-BR.json';
|
||||
// import pt from './pt.json';
|
||||
// import ru from './ru.json';
|
||||
// import th from './th.json';
|
||||
// import tr from './tr.json';
|
||||
// import uk from './uk.json';
|
||||
// import vi from './vi.json';
|
||||
// import zhHans from './zh-Hans.json';
|
||||
// import zh from './zh.json';
|
||||
// import sk from './sk.json';
|
||||
|
||||
const trads = {
|
||||
// ar,
|
||||
// cs,
|
||||
// de,
|
||||
// dk,
|
||||
en,
|
||||
// es,
|
||||
fr,
|
||||
// id,
|
||||
// it,
|
||||
// ja,
|
||||
// ko,
|
||||
// ms,
|
||||
// nl,
|
||||
// pl,
|
||||
// 'pt-BR': ptBR,
|
||||
// pt,
|
||||
// ru,
|
||||
// th,
|
||||
// tr,
|
||||
// uk,
|
||||
// vi,
|
||||
// 'zh-Hans': zhHans,
|
||||
// zh,
|
||||
// sk,
|
||||
};
|
||||
|
||||
export default trads;
|
||||
@ -16,6 +16,8 @@
|
||||
"@buffetjs/styles": "3.3.5",
|
||||
"@buffetjs/utils": "3.3.5",
|
||||
"@sindresorhus/slugify": "1.1.0",
|
||||
"@strapi/helper-plugin": "3.6.0",
|
||||
"@strapi/utils": "3.6.0",
|
||||
"classnames": "^2.3.1",
|
||||
"codemirror": "^5.61.0",
|
||||
"draft-js": "^0.11.5",
|
||||
@ -36,7 +38,7 @@
|
||||
"react": "^16.14.0",
|
||||
"react-dom": "^16.9.0",
|
||||
"react-fast-compare": "^3.2.0",
|
||||
"react-intl": "4.5.0",
|
||||
"react-intl": "5.20.2",
|
||||
"react-redux": "7.2.3",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.0.0",
|
||||
@ -45,8 +47,6 @@
|
||||
"redux-immutable": "^4.0.0",
|
||||
"reselect": "^4.0.0",
|
||||
"sanitize-html": "2.3.3",
|
||||
"@strapi/helper-plugin": "3.6.0",
|
||||
"@strapi/utils": "3.6.0",
|
||||
"yup": "^0.27.0"
|
||||
},
|
||||
"author": {
|
||||
|
||||
@ -4,10 +4,9 @@
|
||||
// Here's the file: strapi/docs/3.0.0-beta.x/guides/registering-a-field-in-admin.md
|
||||
// Also the strapi-generate-plugins/files/admin/src/index.js needs to be updated
|
||||
// IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
|
||||
|
||||
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginLogo from './assets/images/logo.svg';
|
||||
import trads from './translations';
|
||||
import pluginPermissions from './permissions';
|
||||
import pluginId from './pluginId';
|
||||
import reducers from './reducers';
|
||||
@ -28,7 +27,6 @@ export default {
|
||||
isReady: true,
|
||||
name,
|
||||
pluginLogo,
|
||||
trads,
|
||||
menu: {
|
||||
pluginsSectionLinks: [
|
||||
{
|
||||
@ -49,4 +47,27 @@ export default {
|
||||
});
|
||||
},
|
||||
boot() {},
|
||||
async registerTrads({ locales }) {
|
||||
const importedTrads = await Promise.all(
|
||||
locales.map(locale => {
|
||||
return import(
|
||||
/* webpackChunkName: "content-type-builder-translation-[request]" */ `./translations/${locale}.json`
|
||||
)
|
||||
.then(({ default: data }) => {
|
||||
return {
|
||||
data: prefixPluginTranslations(data, pluginId),
|
||||
locale,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
data: {},
|
||||
locale,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.resolve(importedTrads);
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
// import ar from './ar.json';
|
||||
// import cs from './cs.json';
|
||||
// import de from './de.json';
|
||||
// import dk from './dk.json';
|
||||
import en from './en.json';
|
||||
// import es from './es.json';
|
||||
import fr from './fr.json';
|
||||
// import id from './id.json';
|
||||
// import it from './it.json';
|
||||
// import ja from './ja.json';
|
||||
// import ko from './ko.json';
|
||||
// import ms from './ms.json';
|
||||
// import nl from './nl.json';
|
||||
// import pl from './pl.json';
|
||||
// import ptBR from './pt-BR.json';
|
||||
// import pt from './pt.json';
|
||||
// import ru from './ru.json';
|
||||
// import th from './th.json';
|
||||
// import tr from './tr.json';
|
||||
// import uk from './uk.json';
|
||||
// import zhHans from './zh-Hans.json';
|
||||
// import zh from './zh.json';
|
||||
// import sk from './sk.json';
|
||||
|
||||
const trads = {
|
||||
// ar,
|
||||
// cs,
|
||||
// de,
|
||||
// dk,
|
||||
en,
|
||||
// es,
|
||||
fr,
|
||||
// id,
|
||||
// it,
|
||||
// ja,
|
||||
// ko,
|
||||
// ms,
|
||||
// nl,
|
||||
// pl,
|
||||
// 'pt-BR': ptBR,
|
||||
// pt,
|
||||
// ru,
|
||||
// th,
|
||||
// tr,
|
||||
// uk,
|
||||
// 'zh-Hans': zhHans,
|
||||
// zh,
|
||||
// sk,
|
||||
};
|
||||
|
||||
export default trads;
|
||||
@ -15,13 +15,17 @@
|
||||
"@buffetjs/styles": "3.3.5",
|
||||
"@buffetjs/utils": "3.3.5",
|
||||
"@sindresorhus/slugify": "1.1.0",
|
||||
"@strapi/generate": "3.6.0",
|
||||
"@strapi/generate-api": "3.6.0",
|
||||
"@strapi/helper-plugin": "3.6.0",
|
||||
"@strapi/utils": "3.6.0",
|
||||
"fs-extra": "^9.1.0",
|
||||
"immutable": "^3.8.2",
|
||||
"lodash": "4.17.21",
|
||||
"pluralize": "^8.0.0",
|
||||
"react": "^16.14.0",
|
||||
"react-dom": "^16.9.0",
|
||||
"react-intl": "4.5.0",
|
||||
"react-intl": "5.20.2",
|
||||
"react-redux": "7.2.3",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.0.0",
|
||||
@ -29,10 +33,6 @@
|
||||
"redux": "^4.0.1",
|
||||
"redux-immutable": "^4.0.0",
|
||||
"reselect": "^4.0.0",
|
||||
"@strapi/generate": "3.6.0",
|
||||
"@strapi/generate-api": "3.6.0",
|
||||
"@strapi/helper-plugin": "3.6.0",
|
||||
"@strapi/utils": "3.6.0",
|
||||
"yup": "^0.27.0"
|
||||
},
|
||||
"author": {
|
||||
|
||||
@ -6,12 +6,11 @@
|
||||
// IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
|
||||
|
||||
import React from 'react';
|
||||
import { CheckPagePermissions } from '@strapi/helper-plugin';
|
||||
import { CheckPagePermissions, prefixPluginTranslations } from '@strapi/helper-plugin';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginId from './pluginId';
|
||||
import pluginLogo from './assets/images/logo.svg';
|
||||
import pluginPermissions from './permissions';
|
||||
import trads from './translations';
|
||||
import getTrad from './utils/getTrad';
|
||||
import SettingsPage from './pages/Settings';
|
||||
|
||||
@ -53,8 +52,30 @@ export default {
|
||||
isRequired: pluginPkg.strapi.required || false,
|
||||
name,
|
||||
pluginLogo,
|
||||
trads,
|
||||
});
|
||||
},
|
||||
boot() {},
|
||||
async registerTrads({ locales }) {
|
||||
const importedTrads = await Promise.all(
|
||||
locales.map(locale => {
|
||||
return import(
|
||||
/* webpackChunkName: "email-translation-[request]" */ `./translations/${locale}.json`
|
||||
)
|
||||
.then(({ default: data }) => {
|
||||
return {
|
||||
data: prefixPluginTranslations(data, pluginId),
|
||||
locale,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
data: {},
|
||||
locale,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.resolve(importedTrads);
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
// import ar from './ar.json';
|
||||
// import cs from './cs.json';
|
||||
// import de from './de.json';
|
||||
// import dk from './dk.json';
|
||||
import en from './en.json';
|
||||
// import es from './es.json';
|
||||
import fr from './fr.json';
|
||||
// import id from './id.json';
|
||||
// import it from './it.json';
|
||||
// import ja from './ja.json';
|
||||
// import ko from './ko.json';
|
||||
// import ms from './ms.json';
|
||||
// import nl from './nl.json';
|
||||
// import pl from './pl.json';
|
||||
// import ptBR from './pt-BR.json';
|
||||
// import pt from './pt.json';
|
||||
// import ru from './ru.json';
|
||||
// import th from './th.json';
|
||||
// import tr from './tr.json';
|
||||
// import uk from './uk.json';
|
||||
// import vi from './vi.json';
|
||||
// import zhHans from './zh-Hans.json';
|
||||
// import zh from './zh.json';
|
||||
// import sk from './sk.json';
|
||||
|
||||
const trads = {
|
||||
// ar,
|
||||
// cs,
|
||||
// de,
|
||||
// dk,
|
||||
en,
|
||||
// es,
|
||||
fr,
|
||||
// id,
|
||||
// it,
|
||||
// ja,
|
||||
// ko,
|
||||
// ms,
|
||||
// nl,
|
||||
// pl,
|
||||
// 'pt-BR': ptBR,
|
||||
// pt,
|
||||
// ru,
|
||||
// th,
|
||||
// tr,
|
||||
// uk,
|
||||
// vi,
|
||||
// 'zh-Hans': zhHans,
|
||||
// zh,
|
||||
// sk,
|
||||
};
|
||||
|
||||
export default trads;
|
||||
@ -160,6 +160,7 @@ export { default as generateFiltersFromSearch } from './utils/generateFiltersFro
|
||||
export { default as generateSearchFromFilters } from './utils/generateSearchFromFilters';
|
||||
export { default as generateSearchFromObject } from './utils/generateSearchFromObject';
|
||||
export { default as prefixFileUrlWithBackendUrl } from './utils/prefixFileUrlWithBackendUrl';
|
||||
export { default as prefixPluginTranslations } from './utils/prefixPluginTranslations';
|
||||
|
||||
// SVGS
|
||||
export { default as LayoutIcon } from './svgs/Layout';
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
const prefixPluginTranslations = (trad, pluginId) => {
|
||||
return Object.keys(trad).reduce((acc, current) => {
|
||||
acc[`${pluginId}.${current}`] = trad[current];
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
export default prefixPluginTranslations;
|
||||
@ -80,7 +80,7 @@
|
||||
"react": "^16.14.0",
|
||||
"react-dom": "^16.9.0",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-intl": "4.5.0",
|
||||
"react-intl": "5.20.2",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.0.0",
|
||||
"reactstrap": "8.4.1",
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
// Also the strapi-generate-plugins/files/admin/src/index.js needs to be updated
|
||||
// IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
|
||||
import React from 'react';
|
||||
import { CheckPagePermissions } from '@strapi/helper-plugin';
|
||||
import { CheckPagePermissions, prefixPluginTranslations } from '@strapi/helper-plugin';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginLogo from './assets/images/logo.svg';
|
||||
import pluginPermissions from './permissions';
|
||||
@ -14,7 +14,6 @@ import InputMedia from './components/InputMedia';
|
||||
import InputModalStepper from './components/InputModalStepper';
|
||||
import SettingsPage from './pages/SettingsPage';
|
||||
import reducers from './reducers';
|
||||
import trads from './translations';
|
||||
import pluginId from './pluginId';
|
||||
import { getTrad } from './utils';
|
||||
|
||||
@ -41,7 +40,7 @@ export default {
|
||||
isRequired: pluginPkg.strapi.required || false,
|
||||
name,
|
||||
pluginLogo,
|
||||
trads,
|
||||
|
||||
menu: {
|
||||
pluginsSectionLinks: [
|
||||
{
|
||||
@ -73,4 +72,27 @@ export default {
|
||||
permissions: pluginPermissions.settings,
|
||||
});
|
||||
},
|
||||
async registerTrads({ locales }) {
|
||||
const importedTrads = await Promise.all(
|
||||
locales.map(locale => {
|
||||
return import(
|
||||
/* webpackChunkName: "upload-translation-[request]" */ `./translations/${locale}.json`
|
||||
)
|
||||
.then(({ default: data }) => {
|
||||
return {
|
||||
data: prefixPluginTranslations(data, pluginId),
|
||||
locale,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
data: {},
|
||||
locale,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.resolve(importedTrads);
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
// import de from './de.json';
|
||||
// import dk from './dk.json';
|
||||
import en from './en.json';
|
||||
// import es from './es.json';
|
||||
import fr from './fr.json';
|
||||
// import he from './he.json';
|
||||
// import it from './it.json';
|
||||
// import ja from './ja.json';
|
||||
// import ms from './ms.json';
|
||||
// import ru from './ru.json';
|
||||
// import th from './th.json';
|
||||
// import uk from './uk.json';
|
||||
// import ptBR from './pt-BR.json';
|
||||
// import sk from './sk.json';
|
||||
// import zh from './zh.json';
|
||||
// import pl from './pl.json';
|
||||
|
||||
const trads = {
|
||||
// de,
|
||||
// dk,
|
||||
en,
|
||||
// es,
|
||||
fr,
|
||||
// he,
|
||||
// it,
|
||||
// ja,
|
||||
// ms,
|
||||
// ru,
|
||||
// th,
|
||||
// uk,
|
||||
// 'pt-BR': ptBR,
|
||||
// sk,
|
||||
// zh,
|
||||
// pl,
|
||||
};
|
||||
|
||||
export default trads;
|
||||
@ -32,7 +32,7 @@
|
||||
"react": "^16.14.0",
|
||||
"react-copy-to-clipboard": "^5.0.3",
|
||||
"react-dom": "^16.9.0",
|
||||
"react-intl": "4.5.0",
|
||||
"react-intl": "5.20.2",
|
||||
"react-redux": "7.2.3",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.0.0",
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
// TODO move the file in the config folder
|
||||
|
||||
module.exports = {
|
||||
webpack: (config, webpack) => {
|
||||
// Note: we provide webpack above so you should not `require` it
|
||||
// Perform customizations to webpack config
|
||||
// Important: return the modified config
|
||||
return config;
|
||||
},
|
||||
app: config => {
|
||||
config.locales = ['fr'];
|
||||
|
||||
return config;
|
||||
},
|
||||
};
|
||||
@ -1,8 +1,8 @@
|
||||
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginId from './pluginId';
|
||||
import App from './containers/App';
|
||||
import Initializer from './containers/Initializer';
|
||||
import trads from './translations';
|
||||
|
||||
const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
|
||||
const icon = pluginPkg.strapi.icon;
|
||||
@ -39,8 +39,28 @@ export default {
|
||||
},
|
||||
],
|
||||
},
|
||||
trads,
|
||||
});
|
||||
},
|
||||
boot(app) {},
|
||||
async registerTrads({ locales }) {
|
||||
const importedTrads = await Promise.all(
|
||||
locales.map(locale => {
|
||||
return import(`./translations/${locale}.json`)
|
||||
.then(({ default: data }) => {
|
||||
return {
|
||||
data: prefixPluginTranslations(data, pluginId),
|
||||
locale,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
data: {},
|
||||
locale,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.resolve(importedTrads);
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
import en from './en.json';
|
||||
import fr from './fr.json';
|
||||
|
||||
const trads = {
|
||||
en,
|
||||
fr,
|
||||
};
|
||||
|
||||
export default trads;
|
||||
@ -4,12 +4,12 @@
|
||||
// Here's the file: strapi/docs/3.0.0-beta.x/guides/registering-a-field-in-admin.md
|
||||
// Also the strapi-generate-plugins/files/admin/src/index.js needs to be updated
|
||||
// IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
|
||||
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginPermissions from './permissions';
|
||||
import pluginId from './pluginId';
|
||||
import pluginLogo from './assets/images/logo.svg';
|
||||
import App from './pages/App';
|
||||
import trads from './translations';
|
||||
|
||||
const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
|
||||
const icon = pluginPkg.strapi.icon;
|
||||
@ -28,8 +28,6 @@ export default {
|
||||
name,
|
||||
pluginLogo,
|
||||
// TODO
|
||||
trads,
|
||||
// TODO
|
||||
menu: {
|
||||
pluginsSectionLinks: [
|
||||
{
|
||||
@ -46,4 +44,27 @@ export default {
|
||||
});
|
||||
},
|
||||
boot() {},
|
||||
async registerTrads({ locales }) {
|
||||
const importedTrads = await Promise.all(
|
||||
locales.map(locale => {
|
||||
return import(
|
||||
/* webpackChunkName: "documentation-translation-[request]" */ `./translations/${locale}.json`
|
||||
)
|
||||
.then(({ default: data }) => {
|
||||
return {
|
||||
data: prefixPluginTranslations(data, pluginId),
|
||||
locale,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
data: {},
|
||||
locale,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.resolve(importedTrads);
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
// TODO
|
||||
// import ar from './ar.json';
|
||||
// import cs from './cs.json';
|
||||
// import de from './de.json';
|
||||
import en from './en.json';
|
||||
// import es from './es.json';
|
||||
import fr from './fr.json';
|
||||
// import id from './id.json';
|
||||
// import it from './it.json';
|
||||
// import ko from './ko.json';
|
||||
// import ms from './ms.json';
|
||||
// import nl from './nl.json';
|
||||
// import pl from './pl.json';
|
||||
// import ptBR from './pt-BR.json';
|
||||
// import pt from './pt.json';
|
||||
// import ru from './ru.json';
|
||||
// import th from './th.json';
|
||||
// import tr from './tr.json';
|
||||
// import uk from './uk.json';
|
||||
// import vi from './vi.json';
|
||||
// import zhHans from './zh-Hans.json';
|
||||
// import zh from './zh.json';
|
||||
// import sk from './sk.json';
|
||||
|
||||
const trads = {
|
||||
// ar,
|
||||
// cs,
|
||||
// de,
|
||||
en,
|
||||
// es,
|
||||
fr,
|
||||
// id,
|
||||
// it,
|
||||
// ko,
|
||||
// ms,
|
||||
// nl,
|
||||
// pl,
|
||||
// 'pt-BR': ptBR,
|
||||
// pt,
|
||||
// ru,
|
||||
// th,
|
||||
// tr,
|
||||
// uk,
|
||||
// vi,
|
||||
// 'zh-Hans': zhHans,
|
||||
// zh,
|
||||
// sk,
|
||||
};
|
||||
|
||||
export default trads;
|
||||
@ -27,7 +27,7 @@
|
||||
"react": "^16.14.0",
|
||||
"react-copy-to-clipboard": "^5.0.3",
|
||||
"react-dom": "^16.9.0",
|
||||
"react-intl": "4.5.0",
|
||||
"react-intl": "5.20.2",
|
||||
"react-redux": "7.2.3",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.0.0",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginId from './pluginId';
|
||||
import pluginLogo from './assets/images/logo.svg';
|
||||
import trads from './translations';
|
||||
|
||||
const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
|
||||
const icon = pluginPkg.strapi.icon;
|
||||
@ -17,8 +17,30 @@ export default {
|
||||
isRequired: pluginPkg.strapi.required || false,
|
||||
name,
|
||||
pluginLogo,
|
||||
trads,
|
||||
});
|
||||
},
|
||||
boot() {},
|
||||
async registerTrads({ locales }) {
|
||||
const importedTrads = await Promise.all(
|
||||
locales.map(locale => {
|
||||
return import(
|
||||
/* webpackChunkName: "graphql-translation-[request]" */ `./translations/${locale}.json`
|
||||
)
|
||||
.then(({ default: data }) => {
|
||||
return {
|
||||
data: prefixPluginTranslations(data, pluginId),
|
||||
locale,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
data: {},
|
||||
locale,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.resolve(importedTrads);
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
import en from './en.json';
|
||||
import fr from './fr.json';
|
||||
|
||||
const trads = {
|
||||
en,
|
||||
fr,
|
||||
};
|
||||
|
||||
export default trads;
|
||||
@ -1,5 +1,6 @@
|
||||
import get from 'lodash/get';
|
||||
import * as yup from 'yup';
|
||||
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginLogo from './assets/images/logo.svg';
|
||||
import CheckboxConfirmation from './components/CheckboxConfirmation';
|
||||
@ -10,7 +11,6 @@ import LocalePicker from './components/LocalePicker';
|
||||
import middlewares from './middlewares';
|
||||
import pluginPermissions from './permissions';
|
||||
import pluginId from './pluginId';
|
||||
import trads from './translations';
|
||||
import { getTrad } from './utils';
|
||||
import mutateCTBContentTypeSchema from './utils/mutateCTBContentTypeSchema';
|
||||
import LOCALIZED_FIELDS from './utils/localizedFields';
|
||||
@ -37,7 +37,6 @@ export default {
|
||||
mainComponent: null,
|
||||
name,
|
||||
pluginLogo,
|
||||
trads,
|
||||
});
|
||||
},
|
||||
boot(app) {
|
||||
@ -161,4 +160,27 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
async registerTrads({ locales }) {
|
||||
const importedTrads = await Promise.all(
|
||||
locales.map(locale => {
|
||||
return import(
|
||||
/* webpackChunkName: "i18n-translation-[request]" */ `./translations/${locale}.json`
|
||||
)
|
||||
.then(({ default: data }) => {
|
||||
return {
|
||||
data: prefixPluginTranslations(data, pluginId),
|
||||
locale,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
data: {},
|
||||
locale,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.resolve(importedTrads);
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
import en from './en.json';
|
||||
import fr from './fr.json';
|
||||
|
||||
const trads = {
|
||||
en,
|
||||
fr,
|
||||
};
|
||||
|
||||
export default trads;
|
||||
@ -1,7 +1,7 @@
|
||||
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginId from './pluginId';
|
||||
import pluginLogo from './assets/images/logo.svg';
|
||||
import trads from './translations';
|
||||
|
||||
const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
|
||||
const icon = pluginPkg.strapi.icon;
|
||||
@ -17,8 +17,30 @@ export default {
|
||||
isRequired: pluginPkg.strapi.required || false,
|
||||
name,
|
||||
pluginLogo,
|
||||
trads,
|
||||
});
|
||||
},
|
||||
boot() {},
|
||||
async registerTrads({ locales }) {
|
||||
const importedTrads = await Promise.all(
|
||||
locales.map(locale => {
|
||||
return import(
|
||||
/* webpackChunkName: "sentry-translation-[request]" */ `./translations/${locale}.json`
|
||||
)
|
||||
.then(({ default: data }) => {
|
||||
return {
|
||||
data: prefixPluginTranslations(data, pluginId),
|
||||
locale,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
data: {},
|
||||
locale,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.resolve(importedTrads);
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
// import ar from './ar.json';
|
||||
// import cs from './cs.json';
|
||||
// import de from './de.json';
|
||||
import en from './en.json';
|
||||
// import es from './es.json';
|
||||
import fr from './fr.json';
|
||||
// import id from './id.json';
|
||||
// import it from './it.json';
|
||||
// import ko from './ko.json';
|
||||
// import ms from './ms.json';
|
||||
// import nl from './nl.json';
|
||||
// import pl from './pl.json';
|
||||
// import ptBR from './pt-BR.json';
|
||||
// import pt from './pt.json';
|
||||
// import ru from './ru.json';
|
||||
// import th from './th.json';
|
||||
// import tr from './tr.json';
|
||||
// import uk from './uk.json';
|
||||
// import vi from './vi.json';
|
||||
// import zhHans from './zh-Hans.json';
|
||||
// import zh from './zh.json';
|
||||
// import sk from './sk.json';
|
||||
|
||||
const trads = {
|
||||
// ar,
|
||||
// cs,
|
||||
// de,
|
||||
en,
|
||||
// es,
|
||||
fr,
|
||||
// id,
|
||||
// it,
|
||||
// ko,
|
||||
// ms,
|
||||
// nl,
|
||||
// pl,
|
||||
// 'pt-BR': ptBR,
|
||||
// pt,
|
||||
// ru,
|
||||
// th,
|
||||
// tr,
|
||||
// uk,
|
||||
// vi,
|
||||
// 'zh-Hans': zhHans,
|
||||
// zh,
|
||||
// sk,
|
||||
};
|
||||
|
||||
export default trads;
|
||||
@ -5,12 +5,11 @@
|
||||
// Also the strapi-generate-plugins/files/admin/src/index.js needs to be updated
|
||||
// IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
|
||||
import React from 'react';
|
||||
import { CheckPagePermissions } from '@strapi/helper-plugin';
|
||||
import { CheckPagePermissions, prefixPluginTranslations } from '@strapi/helper-plugin';
|
||||
import pluginPkg from '../../package.json';
|
||||
import pluginLogo from './assets/images/logo.svg';
|
||||
import pluginPermissions from './permissions';
|
||||
import pluginId from './pluginId';
|
||||
import trads from './translations';
|
||||
import RolesPage from './pages/Roles';
|
||||
import ProvidersPage from './pages/Providers';
|
||||
import EmailTemplatesPage from './pages/EmailTemplates';
|
||||
@ -100,8 +99,30 @@ export default {
|
||||
isRequired: pluginPkg.strapi.required || false,
|
||||
name,
|
||||
pluginLogo,
|
||||
trads,
|
||||
});
|
||||
},
|
||||
boot() {},
|
||||
async registerTrads({ locales }) {
|
||||
const importedTrads = await Promise.all(
|
||||
locales.map(locale => {
|
||||
return import(
|
||||
/* webpackChunkName: "users-permissions-translation-[request]" */ `./translations/${locale}.json`
|
||||
)
|
||||
.then(({ default: data }) => {
|
||||
return {
|
||||
data: prefixPluginTranslations(data, pluginId),
|
||||
locale,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
data: {},
|
||||
locale,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
return Promise.resolve(importedTrads);
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
// import ar from './ar.json';
|
||||
// import cs from './cs.json';
|
||||
// import de from './de.json';
|
||||
// import dk from './dk.json';
|
||||
import en from './en.json';
|
||||
// import es from './es.json';
|
||||
import fr from './fr.json';
|
||||
// import id from './id.json';
|
||||
// import it from './it.json';
|
||||
// import ja from './ja.json';
|
||||
// import ko from './ko.json';
|
||||
// import ms from './ms.json';
|
||||
// import nl from './nl.json';
|
||||
// import pl from './pl.json';
|
||||
// import ptBR from './pt-BR.json';
|
||||
// import pt from './pt.json';
|
||||
// import ru from './ru.json';
|
||||
// import th from './th.json';
|
||||
// import tr from './tr.json';
|
||||
// import uk from './uk.json';
|
||||
// import vi from './vi.json';
|
||||
// import zhHans from './zh-Hans.json';
|
||||
// import zh from './zh.json';
|
||||
// import sk from './sk.json';
|
||||
// import sv from './sv.json';
|
||||
|
||||
const trads = {
|
||||
// ar,
|
||||
// cs,
|
||||
// de,
|
||||
// dk,
|
||||
en,
|
||||
// es,
|
||||
fr,
|
||||
// id,
|
||||
// it,
|
||||
// ja,
|
||||
// ko,
|
||||
// ms,
|
||||
// nl,
|
||||
// pl,
|
||||
// 'pt-BR': ptBR,
|
||||
// pt,
|
||||
// ru,
|
||||
// th,
|
||||
// tr,
|
||||
// uk,
|
||||
// vi,
|
||||
// 'zh-Hans': zhHans,
|
||||
// zh,
|
||||
// sk,
|
||||
// sv,
|
||||
};
|
||||
|
||||
export default trads;
|
||||
@ -28,7 +28,7 @@
|
||||
"purest": "3.1.0",
|
||||
"react": "^16.14.0",
|
||||
"react-dom": "^16.9.0",
|
||||
"react-intl": "4.5.0",
|
||||
"react-intl": "5.20.2",
|
||||
"react-redux": "7.2.3",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.0.0",
|
||||
|
||||
142
yarn.lock
142
yarn.lock
@ -1390,53 +1390,63 @@
|
||||
dependencies:
|
||||
tslib "^2.0.1"
|
||||
|
||||
"@formatjs/ecma402-abstract@1.4.0":
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.4.0.tgz#ac6c17a8fffac43c6d68c849a7b732626d32654c"
|
||||
integrity sha512-Mv027hcLFjE45K8UJ8PjRpdDGfR0aManEFj1KzoN8zXNveHGEygpZGfFf/FTTMl+QEVSrPAUlyxaCApvmv47AQ==
|
||||
"@formatjs/ecma402-abstract@1.9.3":
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.9.3.tgz#00892014c805935b5b1345d238246e9bf3a2de50"
|
||||
integrity sha512-DBrRUL65m4SVtfq+T4Qltd8+upAzfb9K1MX0UZ0hqQ0wpBY0PSIti9XJe0ZQ/j2v/KxpwQ0Jw5NLumKVezJFQg==
|
||||
dependencies:
|
||||
tslib "^2.0.1"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@formatjs/intl-displaynames@^1.2.5":
|
||||
version "1.2.10"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-1.2.10.tgz#bb9625cca90b099978cd967c6a98aaf4e23fc878"
|
||||
integrity sha512-GROA2RP6+7Ouu0WnHFF78O5XIU7pBfI19WM1qm93l6MFWibUk67nCfVCK3VAYJkLy8L8ZxjkYT11VIAfvSz8wg==
|
||||
"@formatjs/fast-memoize@1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-1.1.1.tgz#3006b58aca1e39a98aca213356b42da5d173f26b"
|
||||
integrity sha512-mIqBr5uigIlx13eZTOPSEh2buDiy3BCdMYUtewICREQjbb4xarDiVWoXSnrERM7NanZ+0TAHNXSqDe6HpEFQUg==
|
||||
|
||||
"@formatjs/icu-messageformat-parser@2.0.6":
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.0.6.tgz#7471c2116982f07b3d9b80e4572a870f20adbaf6"
|
||||
integrity sha512-dgOZ2kq3sbjjC4P0IIghXFUiGY+x9yyypBJF9YFACjw8gPq/OSPmOzdMGvjY9hl4EeeIhhsDd4LIAN/3zHG99A==
|
||||
dependencies:
|
||||
"@formatjs/intl-utils" "^2.3.0"
|
||||
"@formatjs/ecma402-abstract" "1.9.3"
|
||||
"@formatjs/icu-skeleton-parser" "1.2.7"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@formatjs/intl-listformat@^1.4.4":
|
||||
version "1.4.8"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-1.4.8.tgz#70b81005e7dcf74329cb5b314a940ce5fce36cd0"
|
||||
integrity sha512-WNMQlEg0e50VZrGIkgD5n7+DAMGt3boKi1GJALfhFMymslJb5i+5WzWxyj/3a929Z6MAFsmzRIJjKuv+BxKAOQ==
|
||||
"@formatjs/icu-skeleton-parser@1.2.7":
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.2.7.tgz#a74954695c37470efdeff828799654088e567c34"
|
||||
integrity sha512-xm1rJMOz4fwVfWH98VKtbTpZvyQ45plHilkCF16Nm6bAgosYC/IcMmgJisGr6uHqb5TvJRXE07+EvnkIIQjsdA==
|
||||
dependencies:
|
||||
"@formatjs/intl-utils" "^2.3.0"
|
||||
"@formatjs/ecma402-abstract" "1.9.3"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@formatjs/intl-numberformat@^5.5.2":
|
||||
version "5.7.6"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl-numberformat/-/intl-numberformat-5.7.6.tgz#630206bb0acefd2d508ccf4f82367c6875cad611"
|
||||
integrity sha512-ZlZfYtvbVHYZY5OG3RXizoCwxKxEKOrzEe2YOw9wbzoxF3PmFn0SAgojCFGLyNXkkR6xVxlylhbuOPf1dkIVNg==
|
||||
"@formatjs/intl-displaynames@5.1.5":
|
||||
version "5.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-5.1.5.tgz#fb65c09493c3488e11e72b7d9512f0c1cc18b247"
|
||||
integrity sha512-338DoPv8C4BqLqE7Sn5GkJbbkpL0RG8VoMP6qMJywx7bXVgOdWXiXUl3owdCPvq0bpVGGxTl+UNnF+UH8wGdLg==
|
||||
dependencies:
|
||||
"@formatjs/ecma402-abstract" "1.4.0"
|
||||
tslib "^2.0.1"
|
||||
"@formatjs/ecma402-abstract" "1.9.3"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@formatjs/intl-relativetimeformat@^4.5.12":
|
||||
version "4.5.16"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-4.5.16.tgz#7449cef3213dd66d25924ca41f125f87b58df95a"
|
||||
integrity sha512-IQ0haY97oHAH5OYUdykNiepdyEWj3SAT+Fp9ZpR85ov2JNiFx+12WWlxlVS8ehdyncC2ZMt/SwFIy2huK2+6/A==
|
||||
"@formatjs/intl-listformat@6.2.5":
|
||||
version "6.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-6.2.5.tgz#b2534700807e3ca2c2d8180592c15751037c908a"
|
||||
integrity sha512-LRGroM+uLc8dL5J8zwHhNNxWw45nnHQMphW3zEnD9AySKPbFRsrSxzV8LYA93U5mkvMSBf49RdEODpdeyDak/Q==
|
||||
dependencies:
|
||||
"@formatjs/intl-utils" "^2.3.0"
|
||||
"@formatjs/ecma402-abstract" "1.9.3"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@formatjs/intl-unified-numberformat@^3.3.3":
|
||||
version "3.3.7"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl-unified-numberformat/-/intl-unified-numberformat-3.3.7.tgz#9995a24568908188e716d81a1de5b702b2ee00e2"
|
||||
integrity sha512-KnWgLRHzCAgT9eyt3OS34RHoyD7dPDYhRcuKn+/6Kv2knDF8Im43J6vlSW6Hm1w63fNq3ZIT1cFk7RuVO3Psag==
|
||||
"@formatjs/intl@1.13.0":
|
||||
version "1.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-1.13.0.tgz#31f11d88220b6b864e58d3a7c7cb46e3cee62bf3"
|
||||
integrity sha512-Wu8NU+OT9ZmkRSeIfKBY8GRrsCpF/Abc7v6Q8wHzA/VxT7HZblhO8YryALISqc0Vdmq4xUnvbrX4cSNSXdafZg==
|
||||
dependencies:
|
||||
"@formatjs/intl-utils" "^2.3.0"
|
||||
|
||||
"@formatjs/intl-utils@^2.2.2", "@formatjs/intl-utils@^2.3.0":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-2.3.0.tgz#2dc8c57044de0340eb53a7ba602e59abf80dc799"
|
||||
integrity sha512-KWk80UPIzPmUg+P0rKh6TqspRw0G6eux1PuJr+zz47ftMaZ9QDwbGzHZbtzWkl5hgayM/qrKRutllRC7D/vVXQ==
|
||||
"@formatjs/ecma402-abstract" "1.9.3"
|
||||
"@formatjs/fast-memoize" "1.1.1"
|
||||
"@formatjs/icu-messageformat-parser" "2.0.6"
|
||||
"@formatjs/intl-displaynames" "5.1.5"
|
||||
"@formatjs/intl-listformat" "6.2.5"
|
||||
intl-messageformat "9.6.18"
|
||||
tslib "^2.1.0"
|
||||
|
||||
"@fortawesome/fontawesome-common-types@^0.2.35":
|
||||
version "0.2.35"
|
||||
@ -3620,11 +3630,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.0.tgz#682477dbbbd07cd032731cb3b0e7eaee3d026b69"
|
||||
integrity sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==
|
||||
|
||||
"@types/invariant@^2.2.31":
|
||||
version "2.2.34"
|
||||
resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.34.tgz#05e4f79f465c2007884374d4795452f995720bbe"
|
||||
integrity sha512-lYUtmJ9BqUN688fGY1U1HZoWT1/Jrmgigx2loq4ZcJpICECm/Om3V314BxdzypO0u5PORKGMM6x0OXaljV1YFg==
|
||||
|
||||
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
|
||||
@ -10772,25 +10777,14 @@ interpret@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
|
||||
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
|
||||
|
||||
intl-format-cache@^4.2.24, intl-format-cache@^4.2.43:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/intl-format-cache/-/intl-format-cache-4.3.1.tgz#484d31a9872161e6c02139349b259a6229ade377"
|
||||
integrity sha512-OEUYNA7D06agqPOYhbTkl0T8HA3QKSuwWh1HiClEnpd9vw7N+3XsQt5iZ0GUEchp5CW1fQk/tary+NsbF3yQ1Q==
|
||||
|
||||
intl-messageformat-parser@^5.0.0, intl-messageformat-parser@^5.2.1:
|
||||
version "5.5.1"
|
||||
resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-5.5.1.tgz#f09a692755813e6220081e3374df3fb1698bd0c6"
|
||||
integrity sha512-TvB3LqF2VtP6yI6HXlRT5TxX98HKha6hCcrg9dwlPwNaedVNuQA9KgBdtWKgiyakyCTYHQ+KJeFEstNKfZr64w==
|
||||
intl-messageformat@9.6.18:
|
||||
version "9.6.18"
|
||||
resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-9.6.18.tgz#785cc0c44a1a288fbbda63308907c3eab4eebe9f"
|
||||
integrity sha512-phG2EtMS/J6C4pcbErPkTSoqJ+T6qNfPVWTv5cDnI/nuCDKRUHPLDp4QpMdxIWPSUYPj7Lq69vMEIqg91x+H1Q==
|
||||
dependencies:
|
||||
"@formatjs/intl-numberformat" "^5.5.2"
|
||||
|
||||
intl-messageformat@^8.3.7:
|
||||
version "8.4.1"
|
||||
resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-8.4.1.tgz#f31c811efc561700b61ab4ee4716b870787c0fe5"
|
||||
integrity sha512-N4jLt0KebfqXZZZQRwBwZMrqwccHzZnN6KSeUsfidIoHMPIlLIgq08KcYsn7bZS6adh1KKH4/99VODWDDDu85Q==
|
||||
dependencies:
|
||||
intl-format-cache "^4.2.43"
|
||||
intl-messageformat-parser "^5.2.1"
|
||||
"@formatjs/fast-memoize" "1.1.1"
|
||||
"@formatjs/icu-messageformat-parser" "2.0.6"
|
||||
tslib "^2.1.0"
|
||||
|
||||
into-stream@^5.1.0:
|
||||
version "5.1.1"
|
||||
@ -16623,23 +16617,20 @@ react-input-autosize@^3.0.0:
|
||||
dependencies:
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-intl@4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-4.5.0.tgz#f1ea00eb393b1a0e33850819b5ce8947abed187e"
|
||||
integrity sha512-CQuFR9vjUYOjzxsm7KaVRdM4hKOyMNY2ejvniZCbz3Ni3jMbjfTgcXYmxqYBn0lenMaFg3G2ol7HKkoy2YSXlQ==
|
||||
react-intl@5.20.2:
|
||||
version "5.20.2"
|
||||
resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-5.20.2.tgz#e453889e028502b9913e4ed1c35642ec74daba05"
|
||||
integrity sha512-Uv3OydXIjF1wABfUm0mI8SItNQW7zuFaU42W0qXYVRvSoRXMv9rUorC1FLHTiS5zifQCRvWs65VejL8PO5he8w==
|
||||
dependencies:
|
||||
"@formatjs/intl-displaynames" "^1.2.5"
|
||||
"@formatjs/intl-listformat" "^1.4.4"
|
||||
"@formatjs/intl-relativetimeformat" "^4.5.12"
|
||||
"@formatjs/intl-unified-numberformat" "^3.3.3"
|
||||
"@formatjs/intl-utils" "^2.2.2"
|
||||
"@formatjs/ecma402-abstract" "1.9.3"
|
||||
"@formatjs/icu-messageformat-parser" "2.0.6"
|
||||
"@formatjs/intl" "1.13.0"
|
||||
"@formatjs/intl-displaynames" "5.1.5"
|
||||
"@formatjs/intl-listformat" "6.2.5"
|
||||
"@types/hoist-non-react-statics" "^3.3.1"
|
||||
"@types/invariant" "^2.2.31"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
intl-format-cache "^4.2.24"
|
||||
intl-messageformat "^8.3.7"
|
||||
intl-messageformat-parser "^5.0.0"
|
||||
shallow-equal "^1.2.1"
|
||||
intl-messageformat "9.6.18"
|
||||
tslib "^2.1.0"
|
||||
|
||||
react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6:
|
||||
version "16.13.1"
|
||||
@ -18058,11 +18049,6 @@ shallow-clone@^3.0.0:
|
||||
dependencies:
|
||||
kind-of "^6.0.2"
|
||||
|
||||
shallow-equal@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da"
|
||||
integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==
|
||||
|
||||
shallowequal@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user