1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-28 09:24:24 +01:00

use i18next instead of angular-translate for react components

This commit is contained in:
Sylvain 2020-11-02 11:07:08 +01:00
parent 14091f547e
commit 408531d13a
6 changed files with 120 additions and 11 deletions

View File

@ -2,7 +2,8 @@
* This component is a "card" publicly presenting the details of a plan
*/
import React from 'react';
import React, { Suspense } from 'react';
import { useTranslation } from 'react-i18next';
import { react2angular } from 'react2angular';
import { IFilterService } from 'angular';
import moment from 'moment';
@ -10,6 +11,7 @@ import _ from 'lodash'
import { IApplication } from '../models/application';
import { Plan } from '../models/plan';
import { User, UserRole } from '../models/user';
import '../lib/i18n';
declare var Application: IApplication;
@ -19,11 +21,11 @@ interface PlanCardProps {
operator: User,
isSelected: boolean,
onSelectPlan: (plan: Plan) => void,
_t: (key: string, interpolation?: object) => Promise<string>,
$filter: IFilterService
}
const PlanCard: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan, isSelected, _t, $filter }) => {
const PlanCard: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan, isSelected, $filter }) => {
const { t } = useTranslation('public');
/**
* Return the formatted localized amount of the given plan (eg. 20.5 => "20,50 €")
*/
@ -75,22 +77,35 @@ const PlanCard: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan,
{!hasSubscribedToThisPlan() && <button className={`subscribe-button ${isSelected ? 'selected-card' : ''}`}
onClick={handleSelectPlan}
disabled={!_.isNil(user.subscription)}>
{user && <span>{_t('app.public.plans.i_choose_that_plan')}</span>}
{!user && <span>{_t('app.public.plans.i_subscribe_online')}</span>}
{user && <span>{t('app.public.plans.i_choose_that_plan')}</span>}
{!user && <span>{t('app.public.plans.i_subscribe_online')}</span>}
</button>}
{hasSubscribedToThisPlan() && <button className="subscribe-button" disabled>
{ _t('app.public.plans.i_already_subscribed') }
{ t('app.public.plans.i_already_subscribed') }
</button>}
</div>}
{canSubscribeForOther() && <div className="cta-button">
<button className={`subscribe-button ${isSelected ? 'selected-card' : ''}`}
onClick={handleSelectPlan}
disabled={_.isNil(user)}>
<span>{ _t('app.public.plans.i_choose_that_plan') }</span>
<span>{ t('app.public.plans.i_choose_that_plan') }</span>
</button>
</div>}
</div>
);
}
Application.Components.component('planCard', react2angular(PlanCard, ['plan', 'user', 'operator', 'onSelectPlan', 'isSelected'], ['_t', '$filter']));
const PlanCardWrapper: React.FC<PlanCardProps> = ({ plan, user, operator, onSelectPlan, isSelected, $filter }) => {
const loading = (
<div className="fa-3x">
<i className="fas fa-circle-notch fa-spin"></i>
</div>
);
return (
<Suspense fallback={loading}>
<PlanCard plan={plan} user={user} operator={operator} isSelected={isSelected} onSelectPlan={onSelectPlan} $filter={$filter} />
</Suspense>
);
}
Application.Components.component('planCard', react2angular(PlanCardWrapper, ['plan', 'user', 'operator', 'onSelectPlan', 'isSelected'], ['$filter']));

View File

@ -0,0 +1,22 @@
import i18n from 'i18next';
import ICU from 'i18next-icu';
import HttpApi from 'i18next-http-backend';
import { initReactI18next } from 'react-i18next';
declare var Fablab: any;
i18n
.use(ICU)
.use(HttpApi)
.use(initReactI18next)
.init({
lng: Fablab.locale,
fallbackLng: 'en',
ns: ['admin', 'logged', 'public', 'shared'],
defaultNS: 'shared',
backend: {
loadPath: '/api/translations/{{lng}}/app.{{ns}}'
}
});
export default i18n;

View File

@ -344,6 +344,9 @@
padding-left: 30px;
padding-right: 30px;
}
button.subscribe-button:focus, button.subscribe-button:hover {
outline: 0;
}
}
}

View File

@ -1,4 +1,4 @@
# frozen_string_literal: false
# frozen_string_literal: true
# Stylesheet is a cached CSS file that allows to easily customize the interface of Fab-manager with some configurable colors and
# a picture for the background of the user's profile.
@ -82,8 +82,8 @@ class Stylesheet < ApplicationRecord
scss_files = Dir['app/themes/casemate/**/*.scss']
templates = ''
erb_files.each { |erb_file| templates.concat(ERB.new(File.read(erb_file)).result) }
scss_files.each { |scss_file| templates.concat(File.read(scss_file)) }
erb_files.each { |erb_file| templates += ERB.new(File.read(erb_file)).result }
scss_files.each { |scss_file| templates += File.read(scss_file) }
engine = SassC::Engine.new(templates, style: :compressed)
engine.render.presence

View File

@ -81,6 +81,9 @@
"elasticsearch-browser": "3.1",
"fullcalendar": "3.10.2",
"holderjs": "2.6",
"i18next": "^19.8.3",
"i18next-http-backend": "^1.0.21",
"i18next-icu": "^1.4.2",
"jasny-bootstrap": "3.1",
"jquery": ">=3.5.0",
"jquery-ujs": "^1.2.2",
@ -94,6 +97,7 @@
"prop-types": "^15.7.2",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-i18next": "^11.7.3",
"react-switch": "^5.0.1",
"react2angular": "^4.0.6",
"summernote": "0.8.18",

View File

@ -979,6 +979,13 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.12.0", "@babel/runtime@^7.3.1":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.1.tgz#b4116a6b6711d010b2dad3b7b6e43bf1b9954740"
integrity sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/template@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
@ -4567,6 +4574,13 @@ html-minifier-terser@^5.1.1:
relateurl "^0.2.7"
terser "^4.6.3"
html-parse-stringify2@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz#dc5670b7292ca158b7bc916c9a6735ac8872834a"
integrity sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=
dependencies:
void-elements "^2.0.1"
htmlparser2@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-4.1.0.tgz#9a4ef161f2e4625ebf7dfbe6c0a2f52d18a59e78"
@ -4652,6 +4666,27 @@ https-browserify@^1.0.0:
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
i18next-http-backend@^1.0.21:
version "1.0.21"
resolved "https://registry.yarnpkg.com/i18next-http-backend/-/i18next-http-backend-1.0.21.tgz#cee901b3527dad5165fa91de973b6aa6404c1c37"
integrity sha512-UDeHoV2B+31Gr++0KFAVjM5l+SEwePpF6sfDyaDq5ennM9QNJ78PBEMPStwkreEm4h5C8sT7M1JdNQrLcU1Wdg==
dependencies:
node-fetch "2.6.1"
i18next-icu@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/i18next-icu/-/i18next-icu-1.4.2.tgz#2b79d1ac2c2d542725219beac34a74db15cd2ff9"
integrity sha512-EqHafx/sL8eoEowwqi5P6cXtLrzJXBKI4RmV+UaMXlpIJNfckVsq873F2KkMKkApxiw2ATj46C8MurmhMsHQGw==
dependencies:
intl-messageformat "2.2.0"
i18next@^19.8.3:
version "19.8.3"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-19.8.3.tgz#10df7222db8c23389b13bceb9ba67a5e20a0241e"
integrity sha512-eVrqAw2gGGYYJaJMYw4VM1FNFawLD4b84IsoTZMVXeWHaxAM2gyTa34j2Sip15UkBz/LrSxdFJj0Jhlrz7EvHA==
dependencies:
"@babel/runtime" "^7.12.0"
iconv-lite@0.4.24, iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@ -4825,6 +4860,18 @@ interpret@^1.4.0:
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
intl-messageformat-parser@1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075"
integrity sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU=
intl-messageformat@2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-2.2.0.tgz#345bcd46de630b7683330c2e52177ff5eab484fc"
integrity sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw=
dependencies:
intl-messageformat-parser "1.4.0"
invariant@^2.2.2, invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
@ -6016,6 +6063,11 @@ no-case@^3.0.3:
lower-case "^2.0.1"
tslib "^1.10.0"
node-fetch@2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
node-forge@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
@ -7574,6 +7626,14 @@ react-dom@^17.0.0:
object-assign "^4.1.1"
scheduler "^0.20.0"
react-i18next@^11.7.3:
version "11.7.3"
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.7.3.tgz#256461c46baf5b3208c3c6860ca4e569fc7ed053"
integrity sha512-7sYZqVZgdaS9Z0ZH6nuJFErCD0zz5wK3jR4/xCrWjZcxHHF3GRu7BXdicbSPprZV4ZYz7LJzxxMHO7dg5Qb70A==
dependencies:
"@babel/runtime" "^7.3.1"
html-parse-stringify2 "2.0.1"
react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@ -9245,6 +9305,11 @@ vm-browserify@^1.0.1:
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
void-elements@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
watchpack-chokidar2@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0"