"react-dom": "16.13.0",
"react-draggable": "4.2.0",
"react-helmet-async": "1.0.4",
- "react-intl": "2.8.0",
+ "react-intl": "3.12.1",
"react-modal": "3.14.3",
"react-redux": "5.1.1",
"react-router": "3.2.6",
"@types/react": "16.8.23",
"@types/react-dom": "16.8.4",
"@types/react-helmet": "5.0.15",
- "@types/react-intl": "2.3.17",
"@types/react-modal": "3.12.1",
"@types/react-redux": "6.0.6",
"@types/react-router": "3.0.20",
*/
import * as React from 'react';
import { Helmet } from 'react-helmet-async';
-import { InjectedIntlProps, injectIntl } from 'react-intl';
+import { injectIntl, WrappedComponentProps } from 'react-intl';
import { connect } from 'react-redux';
import { Location, Router, withRouter } from '../../../components/hoc/withRouter';
import { getExtensionStart } from '../../../helpers/extensions';
import * as theme from '../../theme';
import getStore from '../../utils/getStore';
-interface Props extends InjectedIntlProps {
+interface Props extends WrappedComponentProps {
currentUser: T.CurrentUser;
extension: T.Extension;
location: Location;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly: extension exists 1`] = `
-<InjectIntl(withRouter(Connect(Extension)))
+<injectIntl(withRouter(Connect(Extension)))
extension={
Object {
"key": "foo/bar",
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `
-<InjectIntl(withRouter(Connect(Extension)))
+<injectIntl(withRouter(Connect(Extension)))
extension={
Object {
"key": "plugin-key/extension-key",
pathname: onBackgroudTaskPage ? '/project/background_tasks' : '/foo/bar'
})
});
- const messageProps = wrapper.find(FormattedMessage).props();
+ const messageProps = wrapper.find<FormattedMessage>(FormattedMessage).props();
// Translation key.
expect(messageProps.defaultMessage).toBe(expectedMessage);
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { InjectedIntlProps, injectIntl } from 'react-intl';
+import { injectIntl, WrappedComponentProps } from 'react-intl';
import DateInput from '../../../components/controls/DateInput';
import FacetBox from '../../../components/facet/FacetBox';
import FacetHeader from '../../../components/facet/FacetHeader';
value?: Date;
}
-class AvailableSinceFacet extends React.PureComponent<Props & InjectedIntlProps> {
+class AvailableSinceFacet extends React.PureComponent<Props & WrappedComponentProps> {
handleHeaderClick = () => {
this.props.onToggle('availableSince');
};
sansTop25Open={false}
sonarsourceSecurityOpen={false}
/>
- <InjectIntl(AvailableSinceFacet)
+ <injectIntl(AvailableSinceFacet)
onChange={[MockFunction]}
onToggle={[MockFunction]}
open={false}
import classNames from 'classnames';
import { differenceInDays } from 'date-fns';
import * as React from 'react';
-import { InjectedIntlProps, injectIntl } from 'react-intl';
+import { injectIntl, WrappedComponentProps } from 'react-intl';
import Tooltip from '../../../components/controls/Tooltip';
import DateFormatter, { longFormatterOption } from '../../../components/intl/DateFormatter';
import DateFromNow from '../../../components/intl/DateFromNow';
period: T.Period;
}
-export class LeakPeriodLegend extends React.PureComponent<Props & InjectedIntlProps> {
+export class LeakPeriodLegend extends React.PureComponent<Props & WrappedComponentProps> {
formatDate = (date: string) => {
return this.props.intl.formatDate(date, longFormatterOption);
};
import { differenceInDays } from 'date-fns';
import { shallow } from 'enzyme';
import * as React from 'react';
-import { InjectedIntlProps } from 'react-intl';
+import { IntlShape } from 'react-intl';
import { LeakPeriodLegend } from '../LeakPeriodLegend';
jest.mock('date-fns', () => {
return shallow(
<LeakPeriodLegend
component={component}
- intl={{ formatDate: (x: any) => x } as InjectedIntlProps['intl']}
+ intl={{ formatDate: (x: any) => x } as IntlShape}
period={period}
/>
);
<div
className="measure-details-primary-actions"
>
- <InjectIntl(LeakPeriodLegend)
+ <injectIntl(LeakPeriodLegend)
className="spacer-left"
component={
Object {
<div
className="measure-details-primary-actions"
>
- <InjectIntl(LeakPeriodLegend)
+ <injectIntl(LeakPeriodLegend)
className="spacer-left"
component={
Object {
<div
className="measure-details-primary-actions"
>
- <InjectIntl(LeakPeriodLegend)
+ <injectIntl(LeakPeriodLegend)
className="spacer-left"
component={
Object {
<div
className="measure-details-primary-actions"
>
- <InjectIntl(LeakPeriodLegend)
+ <injectIntl(LeakPeriodLegend)
className="spacer-left"
component={
Object {
<div
className="clearfix big-spacer-bottom"
>
- <InjectIntl(LeakPeriodLegend)
+ <injectIntl(LeakPeriodLegend)
className="pull-right"
component={
Object {
import { isSameDay } from 'date-fns';
import { max } from 'lodash';
import * as React from 'react';
-import { InjectedIntlProps, injectIntl } from 'react-intl';
+import { injectIntl, WrappedComponentProps } from 'react-intl';
import BarChart from '../../../components/charts/BarChart';
import DateRangeInput from '../../../components/controls/DateRangeInput';
import FacetBox from '../../../components/facet/FacetBox';
stats: T.Dict<number> | undefined;
}
-export class CreationDateFacet extends React.PureComponent<Props & InjectedIntlProps> {
+export class CreationDateFacet extends React.PureComponent<Props & WrappedComponentProps> {
property = 'createdAt';
static defaultProps = {
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { InjectedIntlProps } from 'react-intl';
+import { IntlShape } from 'react-intl';
import { mockComponent } from '../../../../helpers/mocks/component';
import { ComponentQualifier } from '../../../../types/component';
import { CreationDateFacet } from '../CreationDateFacet';
intl={
{
formatDate: (date: string) => 'formatted.' + date
- } as InjectedIntlProps['intl']
+ } as IntlShape
}
onChange={jest.fn()}
onToggle={jest.fn()}
"ResolutionFacet",
"StatusFacet",
"StandardFacet",
- "InjectIntl(CreationDateFacet)",
+ "injectIntl(CreationDateFacet)",
"Connect(LanguageFacet)",
"RuleFacet",
"TagFacet",
"ResolutionFacet",
"StatusFacet",
"StandardFacet",
- "InjectIntl(CreationDateFacet)",
+ "injectIntl(CreationDateFacet)",
"Connect(LanguageFacet)",
"RuleFacet",
"TagFacet",
"ResolutionFacet",
"StatusFacet",
"StandardFacet",
- "InjectIntl(CreationDateFacet)",
+ "injectIntl(CreationDateFacet)",
"Connect(LanguageFacet)",
"RuleFacet",
"TagFacet",
"ResolutionFacet",
"StatusFacet",
"StandardFacet",
- "InjectIntl(CreationDateFacet)",
+ "injectIntl(CreationDateFacet)",
"Connect(LanguageFacet)",
"RuleFacet",
"TagFacet",
"ResolutionFacet",
"StatusFacet",
"StandardFacet",
- "InjectIntl(CreationDateFacet)",
+ "injectIntl(CreationDateFacet)",
"Connect(LanguageFacet)",
"RuleFacet",
"TagFacet",
"ResolutionFacet",
"StatusFacet",
"StandardFacet",
- "InjectIntl(CreationDateFacet)",
+ "injectIntl(CreationDateFacet)",
"Connect(LanguageFacet)",
"RuleFacet",
"TagFacet",
"ResolutionFacet",
"StatusFacet",
"StandardFacet",
- "InjectIntl(CreationDateFacet)",
+ "injectIntl(CreationDateFacet)",
"Connect(LanguageFacet)",
"RuleFacet",
"TagFacet",
"ResolutionFacet",
"StatusFacet",
"StandardFacet",
- "InjectIntl(CreationDateFacet)",
+ "injectIntl(CreationDateFacet)",
"Connect(LanguageFacet)",
"RuleFacet",
"TagFacet",
"ResolutionFacet",
"StatusFacet",
"StandardFacet",
- "InjectIntl(CreationDateFacet)",
+ "injectIntl(CreationDateFacet)",
"Connect(LanguageFacet)",
"RuleFacet",
"TagFacet",
"ResolutionFacet",
"StatusFacet",
"StandardFacet",
- "InjectIntl(CreationDateFacet)",
+ "injectIntl(CreationDateFacet)",
"Connect(LanguageFacet)",
"RuleFacet",
"TagFacet",
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { InjectedIntl, injectIntl } from 'react-intl';
+import { injectIntl, WrappedComponentProps } from 'react-intl';
import { longFormatterOption } from '../../../components/intl/DateFormatter';
import DateFromNow from '../../../components/intl/DateFromNow';
import { formatterOption } from '../../../components/intl/DateTimeFormatter';
import { translateWithParameters } from '../../../helpers/l10n';
import { getPeriodDate, getPeriodLabel } from '../../../helpers/periods';
-export interface ProjectLeakPeriodInfoProps {
- intl: Pick<InjectedIntl, 'formatDate' | 'formatTime'>;
+export interface ProjectLeakPeriodInfoProps extends WrappedComponentProps {
leakPeriod: T.Period;
}
import { differenceInDays } from 'date-fns';
import { shallow } from 'enzyme';
import * as React from 'react';
+import { IntlShape } from 'react-intl';
import { mockPeriod } from '../../../../helpers/testMocks';
import { ProjectLeakPeriodInfo } from '../ProjectLeakPeriodInfo';
function shallowRender(period: Partial<T.Period> = {}) {
return shallow(
<ProjectLeakPeriodInfo
- intl={{
- formatDate: (date: string) => 'formatted.' + date,
- formatTime: (date: string) => 'formattedTime.' + date
- }}
+ intl={
+ {
+ formatDate: (date: string) => 'formatted.' + date,
+ formatTime: (date: string) => 'formattedTime.' + date
+ } as IntlShape
+ }
leakPeriod={mockPeriod({ ...period })}
/>
);
`;
exports[`renders correctly for projects 1`] = `
-<Memo(InjectIntl(ProjectLeakPeriodInfo))
+<Memo(injectIntl(ProjectLeakPeriodInfo))
leakPeriod={
Object {
"date": "2019-04-23T02:12:32+0100",
*/
import { differenceInDays } from 'date-fns';
import * as React from 'react';
-import { InjectedIntlProps, injectIntl } from 'react-intl';
+import { injectIntl, WrappedComponentProps } from 'react-intl';
import Tooltip from '../../../components/controls/Tooltip';
import DateFormatter, { longFormatterOption } from '../../../components/intl/DateFormatter';
import DateFromNow from '../../../components/intl/DateFromNow';
SPECIFIC_ANALYSIS: true
};
-export class LeakPeriodLegend extends React.PureComponent<Props & InjectedIntlProps> {
+export class LeakPeriodLegend extends React.PureComponent<Props & WrappedComponentProps> {
formatDate = (date: string) => {
return this.props.intl.formatDate(date, longFormatterOption);
};
import { differenceInDays } from 'date-fns';
import { shallow } from 'enzyme';
import * as React from 'react';
-import { InjectedIntlProps } from 'react-intl';
+import { IntlShape } from 'react-intl';
import { LeakPeriodLegend } from '../LeakPeriodLegend';
jest.mock('date-fns', () => {
{
formatDate: (date: string) => 'formatted.' + date,
formatTime: (date: string) => 'formattedTime.' + date
- } as InjectedIntlProps['intl']
+ } as IntlShape
}
period={{
date: '2013-09-22T00:00:00+0200',
import { range } from 'lodash';
import * as React from 'react';
import { DayModifiers, Modifier, Modifiers } from 'react-day-picker';
-import { InjectedIntlProps, injectIntl } from 'react-intl';
+import { injectIntl, WrappedComponentProps } from 'react-intl';
import { ButtonIcon, ClearButton } from '../../components/controls/buttons';
import OutsideClickHandler from '../../components/controls/OutsideClickHandler';
import Select from '../../components/controls/Select';
className={classNames('date-input-control-input', this.props.inputClassName, {
'is-filled': this.props.value !== undefined
})}
- innerRef={node => (this.input = node)}
+ innerRef={(node: HTMLInputElement | null) => (this.input = node)}
name={this.props.name}
onFocus={this.openCalendar}
placeholder={this.props.placeholder}
}
type InputWrapperProps = T.Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value'> &
- InjectedIntlProps & {
+ WrappedComponentProps & {
innerRef: React.Ref<HTMLInputElement>;
value: Date | undefined;
};
<span
className="date-input-control"
>
- <InjectIntl(Component)
+ <injectIntl(Component)
className="date-input-control-input"
innerRef={[Function]}
onFocus={[Function]}
<span
className="date-input-control"
>
- <InjectIntl(Component)
+ <injectIntl(Component)
className="date-input-control-input is-filled"
innerRef={[Function]}
onFocus={[Function]}
<span
className="date-input-control"
>
- <InjectIntl(Component)
+ <injectIntl(Component)
className="date-input-control-input is-filled"
innerRef={[Function]}
onFocus={[Function]}
<span
className="date-input-control"
>
- <InjectIntl(Component)
+ <injectIntl(Component)
className="date-input-control-input"
innerRef={[Function]}
onFocus={[Function]}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { DateSource, FormattedDate } from 'react-intl';
+import { FormatDateOptions, FormattedDate } from 'react-intl';
import { parseDate } from '../../helpers/dates';
+import { ParsableDate } from '../../types/dates';
export interface DateFormatterProps {
children?: (formattedDate: string) => React.ReactNode;
- date: DateSource;
+ date: ParsableDate;
long?: boolean;
}
-export const formatterOption = { year: 'numeric', month: 'short', day: '2-digit' };
+export const formatterOption: FormatDateOptions = {
+ year: 'numeric',
+ month: 'short',
+ day: '2-digit'
+};
-export const longFormatterOption = { year: 'numeric', month: 'long', day: 'numeric' };
+export const longFormatterOption: FormatDateOptions = {
+ year: 'numeric',
+ month: 'long',
+ day: 'numeric'
+};
export default function DateFormatter({ children, date, long }: DateFormatterProps) {
return (
*/
import { differenceInHours } from 'date-fns';
import * as React from 'react';
-import { DateSource, FormattedRelative } from 'react-intl';
+import { FormattedRelativeTime } from 'react-intl';
import { parseDate } from '../../helpers/dates';
import { translate } from '../../helpers/l10n';
+import { ParsableDate } from '../../types/dates';
import DateTimeFormatter from './DateTimeFormatter';
+import { getRelativeTimeProps } from './dateUtils';
export interface DateFromNowProps {
children?: (formattedDate: string) => React.ReactNode;
- date?: DateSource;
+ date?: ParsableDate;
hourPrecision?: boolean;
}
return <>{originalChildren(translate('never'))}</>;
}
- if (date && hourPrecision && differenceInHours(Date.now(), date) < 1) {
+ if (hourPrecision && differenceInHours(Date.now(), date) < 1) {
children = () => originalChildren(translate('less_than_1_hour_ago'));
}
const parsedDate = parseDate(date);
+ const relativeTimeProps = getRelativeTimeProps(date);
+
return (
<DateTimeFormatter date={parsedDate}>
{formattedDate => (
<span title={formattedDate}>
- <FormattedRelative value={parsedDate}>{children}</FormattedRelative>
+ <FormattedRelativeTime {...relativeTimeProps}>
+ {children as FormattedRelativeTime['props']['children']}
+ </FormattedRelativeTime>
</span>
)}
</DateTimeFormatter>
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { DateSource, FormattedDate } from 'react-intl';
+import { FormatDateOptions, FormattedDate } from 'react-intl';
import { parseDate } from '../../helpers/dates';
+import { ParsableDate } from '../../types/dates';
interface Props {
children?: (formattedDate: string) => React.ReactNode;
- date: DateSource;
+ date: ParsableDate;
}
-export const formatterOption = {
+export const formatterOption: FormatDateOptions = {
year: 'numeric',
month: 'long',
day: 'numeric',
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { DateSource, FormattedTime } from 'react-intl';
+import { FormatDateOptions, FormattedTime } from 'react-intl';
import { parseDate } from '../../helpers/dates';
+import { ParsableDate } from '../../types/dates';
export interface TimeFormatterProps {
children?: (formattedDate: string) => React.ReactNode;
- date: DateSource;
+ date: ParsableDate;
long?: boolean;
}
-export const formatterOption = { hour: 'numeric', minute: 'numeric' };
+export const formatterOption: FormatDateOptions = { hour: 'numeric', minute: 'numeric' };
-export const longFormatterOption = { hour: 'numeric', minute: 'numeric', second: 'numeric' };
+export const longFormatterOption: FormatDateOptions = {
+ hour: 'numeric',
+ minute: 'numeric',
+ second: 'numeric'
+};
export default function TimeFormatter({ children, date, long }: TimeFormatterProps) {
return (
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { DateSource } from 'react-intl';
+import { ParsableDate } from '../../../types/dates';
interface Props {
children?: (formattedDate: string) => React.ReactNode;
- date: DateSource;
+ date: ParsableDate;
}
export default function DateFromNow({ children, date }: Props) {
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { FormattedRelative, IntlProvider } from 'react-intl';
+import { FormattedRelativeTime, IntlProvider } from 'react-intl';
import DateFromNow, { DateFromNowProps } from '../DateFromNow';
import DateTimeFormatter from '../DateTimeFormatter';
const date = '2020-02-20T20:20:20Z';
+jest.mock('../dateUtils', () => ({
+ getRelativeTimeProps: jest.fn().mockReturnValue({ value: -1, unit: 'year' })
+}));
+
it('should render correctly', () => {
const wrapper = shallowRender();
it('should render correctly when the date is less than one hour in the past', () => {
const veryCloseDate = new Date(date);
veryCloseDate.setMinutes(veryCloseDate.getMinutes() - 10);
- jest.spyOn(Date, 'now').mockImplementation(() => (new Date(date) as unknown) as number);
+ const mockDateNow = jest
+ .spyOn(Date, 'now')
+ .mockImplementation(() => (new Date(date) as unknown) as number);
const children = jest.fn();
shallowRender({ date: veryCloseDate, hourPrecision: true }, children)
- .dive()
- .dive()
- .find(FormattedRelative)
+ .dive() // into DateTimeFormatter
+ .dive() // into DateFormatter
+ .dive() // into rendering function
+ .find(FormattedRelativeTime)
.props().children!(date);
expect(children).toHaveBeenCalledWith('less_than_1_hour_ago');
+ mockDateNow.mockRestore();
});
function shallowRender(overrides: Partial<DateFromNowProps> = {}, children: jest.Mock = jest.fn()) {
- return shallow<DateFromNowProps>(
+ return shallow(
<IntlProvider defaultLocale="en-US" locale="en">
<DateFromNow date={date} {...overrides}>
{formattedDate => children(formattedDate)}
</DateFromNow>
</IntlProvider>
- ).dive();
+ )
+ .dive() // into the ContextProvider generated by IntlProvider
+ .dive(); // into the DateFromNow we actually want to render
}
<span
title="2020-02-20T20:20:20Z"
>
- <FormattedRelative
- updateInterval={10000}
- value={2020-02-20T20:20:20.000Z}
+ <FormattedRelativeTime
+ unit="year"
+ value={-1}
>
[Function]
- </FormattedRelative>
+ </FormattedRelativeTime>
</span>
`;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import { getRelativeTimeProps } from '../../dateUtils';
+
+const mockDateNow = jest.spyOn(Date, 'now');
+
+describe('getRelativeTimeProps', () => {
+ mockDateNow.mockImplementation(() => new Date('2021-02-20T20:20:20Z').getTime());
+
+ it.each([
+ ['year', '2020-02-19T20:20:20Z', -1],
+ ['month', '2020-11-18T20:20:20Z', -3],
+ ['day', '2021-02-18T18:20:20Z', -2]
+ ])('should return the correct props for dates older than a %s', (unit, date, value) => {
+ expect(getRelativeTimeProps(date)).toEqual({ value, unit });
+ });
+
+ it('should return the correct props for dates from less than a day ago', () => {
+ expect(getRelativeTimeProps('2021-02-20T20:19:45Z')).toEqual({
+ value: -35,
+ unit: 'second',
+ updateIntervalInSeconds: 10
+ });
+ });
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import {
+ differenceInDays,
+ differenceInMonths,
+ differenceInSeconds,
+ differenceInYears
+} from 'date-fns';
+import { FormattedRelativeTime } from 'react-intl';
+import { ParsableDate } from '../../types/dates';
+
+const UPDATE_INTERVAL_IN_SECONDS = 10;
+
+export function getRelativeTimeProps(
+ date: ParsableDate
+): Pick<FormattedRelativeTime['props'], 'unit' | 'value' | 'updateIntervalInSeconds'> {
+ const y = differenceInYears(date, Date.now());
+
+ if (Math.abs(y) > 0) {
+ return { value: y, unit: 'year' };
+ }
+
+ const m = differenceInMonths(date, Date.now());
+ if (Math.abs(m) > 0) {
+ return { value: m, unit: 'month' };
+ }
+
+ const d = differenceInDays(date, Date.now());
+ if (Math.abs(d) > 0) {
+ return { value: d, unit: 'day' };
+ }
+
+ return {
+ value: differenceInSeconds(date, Date.now()),
+ unit: 'second',
+ updateIntervalInSeconds: UPDATE_INTERVAL_IN_SECONDS
+ };
+}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { parse } from 'date-fns';
+import { ParsableDate } from '../types/dates';
function pad(number: number) {
if (number < 10) {
return number;
}
-type ParsableDate = string | number | Date;
-
export function parseDate(rawDate: ParsableDate): Date {
return parse(rawDate);
}
resetCurrentLocale(bundle.locale);
resetMessages(bundle.messages);
- // No need to load english (default) bundle, it's coming with react-intl
- if (bundle.locale !== DEFAULT_LOCALE) {
- const [intlBundle, intl] = await Promise.all([
- import(`react-intl/locale-data/${bundle.locale}`),
- import('react-intl')
- ]);
-
- intl.addLocaleData(intlBundle.default);
- }
-
return bundle;
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+export type ParsableDate = string | number | Date;
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { InjectedIntl } from 'react-intl';
+import { IntlShape } from 'react-intl';
import { Store as ReduxStore } from 'redux';
import { Location, Router } from '../components/hoc/withRouter';
import { Store } from '../store/rootReducer';
store: ReduxStore<Store, any>;
el: HTMLElement | undefined | null;
currentUser: T.CurrentUser;
- intl: InjectedIntl;
+ intl: IntlShape;
location: Location;
router: Router;
theme: {
languageName: node
linkType: hard
+"@formatjs/intl-displaynames@npm:^1.2.0":
+ version: 1.2.10
+ resolution: "@formatjs/intl-displaynames@npm:1.2.10"
+ dependencies:
+ "@formatjs/intl-utils": ^2.3.0
+ checksum: 25320e00c383260c1c3c44bd8be017b8ebd1b1b7de4188d05934aa40b65adda02b102eba46bf4e01e06f9db79d2d8663a720afe7f2ee69495a3022055bea4810
+ languageName: node
+ linkType: hard
+
+"@formatjs/intl-listformat@npm:^1.4.1":
+ version: 1.4.8
+ resolution: "@formatjs/intl-listformat@npm:1.4.8"
+ dependencies:
+ "@formatjs/intl-utils": ^2.3.0
+ checksum: 1e5b2ef45b7e0143fb4c809178aed00ad1d1dfbcba25c339bf54bdd5e35acee6c72a25bd30189812a3211103a58a7e0800e49bc3e973f89bc5e80c41da38f6e1
+ languageName: node
+ linkType: hard
+
+"@formatjs/intl-relativetimeformat@npm:^4.5.9":
+ version: 4.5.16
+ resolution: "@formatjs/intl-relativetimeformat@npm:4.5.16"
+ dependencies:
+ "@formatjs/intl-utils": ^2.3.0
+ checksum: 466268cb4f3c326b222cc0f79b176949d4cc79e29d11fe6e8d003b89b3495018728d55ba25189f3856b88c0f5657a57365f039504c32ea78a8fb555ff80e9580
+ languageName: node
+ linkType: hard
+
+"@formatjs/intl-unified-numberformat@npm:^3.2.0":
+ version: 3.3.7
+ resolution: "@formatjs/intl-unified-numberformat@npm:3.3.7"
+ dependencies:
+ "@formatjs/intl-utils": ^2.3.0
+ checksum: dae9c855d8b36b833ee9a71e63b13240dabc9b84ed13192411f06ac903a5c2fb002fd4736d7b71df73c4c776792255c7b2deedb94c5cddc12967fcb7c14f6133
+ languageName: node
+ linkType: hard
+
+"@formatjs/intl-utils@npm:^2.2.0, @formatjs/intl-utils@npm:^2.3.0":
+ version: 2.3.0
+ resolution: "@formatjs/intl-utils@npm:2.3.0"
+ checksum: a7a6339dac796bccd738b3f0425863c79951156c5b61ed804869bd2ba064544badf3ec0bad576eb56fdbaf11585d99b8a089522a9b5829ba0f99a85d33222cfb
+ languageName: node
+ linkType: hard
+
"@gar/promisify@npm:^1.0.1":
version: 1.1.2
resolution: "@gar/promisify@npm:1.1.2"
languageName: node
linkType: hard
+"@types/hoist-non-react-statics@npm:^3.3.1":
+ version: 3.3.1
+ resolution: "@types/hoist-non-react-statics@npm:3.3.1"
+ dependencies:
+ "@types/react": "*"
+ hoist-non-react-statics: ^3.3.0
+ checksum: 2c0778570d9a01d05afabc781b32163f28409bb98f7245c38d5eaf082416fdb73034003f5825eb5e21313044e8d2d9e1f3fe2831e345d3d1b1d20bcd12270719
+ languageName: node
+ linkType: hard
+
"@types/htmlparser2@npm:*":
version: 3.10.0
resolution: "@types/htmlparser2@npm:3.10.0"
languageName: node
linkType: hard
+"@types/invariant@npm:^2.2.31":
+ version: 2.2.35
+ resolution: "@types/invariant@npm:2.2.35"
+ checksum: af1b624057c89789ed0917838fea3d42bb0c101cc22b829a24d8777c678be3bc79d6ae05992a13bdf607b94731262467a2e62a809602ea1f7eea5e8c2242660d
+ languageName: node
+ linkType: hard
+
"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1":
version: 2.0.1
resolution: "@types/istanbul-lib-coverage@npm:2.0.1"
languageName: node
linkType: hard
-"@types/react-intl@npm:2.3.17":
- version: 2.3.17
- resolution: "@types/react-intl@npm:2.3.17"
- checksum: 6d6169a7d41d87552074bfdf0f42ee229b7f48eb9bc1d99205c39693bdc006cbb2a5790954c2087cbe4ca20cf027e992bfe60de8ae9e15d71700e8742541b470
- languageName: node
- linkType: hard
-
"@types/react-modal@npm:3.12.1":
version: 3.12.1
resolution: "@types/react-modal@npm:3.12.1"
"@types/react": 16.8.23
"@types/react-dom": 16.8.4
"@types/react-helmet": 5.0.15
- "@types/react-intl": 2.3.17
"@types/react-modal": 3.12.1
"@types/react-redux": 6.0.6
"@types/react-router": 3.0.20
react-dom: 16.13.0
react-draggable: 4.2.0
react-helmet-async: 1.0.4
- react-intl: 2.8.0
+ react-intl: 3.12.1
react-modal: 3.14.3
react-redux: 5.1.1
react-router: 3.2.6
languageName: node
linkType: hard
-"hoist-non-react-statics@npm:^3.3.2":
+"hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.2":
version: 3.3.2
resolution: "hoist-non-react-statics@npm:3.3.2"
dependencies:
languageName: node
linkType: hard
-"intl-format-cache@npm:^2.0.5":
- version: 2.2.9
- resolution: "intl-format-cache@npm:2.2.9"
- checksum: 70ebb4fe2e3005d718562eff56a9f19d29ace8f51d6e549abe57ac9bd8a6791ace905f7d0d2a870236552746eff24793e782d64a3d29b93d3ff2e9bca0e3d6d8
- languageName: node
- linkType: hard
-
-"intl-messageformat-parser@npm:1.4.0":
- version: 1.4.0
- resolution: "intl-messageformat-parser@npm:1.4.0"
- checksum: 0606b78523a9730b47292dbf1f1835e189120cd91aa742d1c0925ce0925fb067233fc74ec259a20d7810f5a1a0bd801f5884fe04493082596cf578bfeafa34c6
+"intl-format-cache@npm:^4.2.21":
+ version: 4.3.1
+ resolution: "intl-format-cache@npm:4.3.1"
+ checksum: d55581edaba0d083a3ff26a46e2ed953c434420918e61991db78140e3e0a7db14f924f195fcd0c01cf3de65cb18dda0c549d35f683e01dd8f062d27fe0524fae
languageName: node
linkType: hard
-"intl-messageformat@npm:^2.0.0, intl-messageformat@npm:^2.1.0":
- version: 2.2.0
- resolution: "intl-messageformat@npm:2.2.0"
+"intl-messageformat-parser@npm:^3.6.4":
+ version: 3.6.4
+ resolution: "intl-messageformat-parser@npm:3.6.4"
dependencies:
- intl-messageformat-parser: 1.4.0
- checksum: 5562de75dddae69546180403fec196ed6564d41cb82964de8e319bd9fa9edfe5aaa581bc40775815b65fbdab3db96b62bb0757c2a936ac025e705333e4bd82cd
+ "@formatjs/intl-unified-numberformat": ^3.2.0
+ checksum: 69e781b6fec47f1fe5b2dc9abba79ac74b8cb4e9b40da4acc3ef2e9c6140d3d90070fd2c055d16e48c3a8bce626bb1f547ad1e29df772aff468a377658e70e6e
languageName: node
linkType: hard
-"intl-relativeformat@npm:^2.1.0":
- version: 2.2.0
- resolution: "intl-relativeformat@npm:2.2.0"
+"intl-messageformat@npm:^7.8.4":
+ version: 7.8.4
+ resolution: "intl-messageformat@npm:7.8.4"
dependencies:
- intl-messageformat: ^2.0.0
- checksum: 887862279d7ad415f9fefa59b5abb48878f08214b7d4592e4834c956e5317b258d1103ba1c353284c213dcc574a98b5f65075323f50c94632ec79f7c5cb5c2cd
+ intl-format-cache: ^4.2.21
+ intl-messageformat-parser: ^3.6.4
+ checksum: a24fd5763c3aae450d97c4a67d95618d791f7a564996cbf6f1c4c5433c3c6fe0c141d967f94775bf9c0e70ce7791c66854987fa03a99a57f10c96186ddd90658
languageName: node
linkType: hard
-"invariant@npm:^2.1.1, invariant@npm:^2.2.1, invariant@npm:^2.2.2, invariant@npm:^2.2.4":
+"invariant@npm:^2.2.1, invariant@npm:^2.2.2, invariant@npm:^2.2.4":
version: 2.2.4
resolution: "invariant@npm:2.2.4"
dependencies:
languageName: node
linkType: hard
-"react-intl@npm:2.8.0":
- version: 2.8.0
- resolution: "react-intl@npm:2.8.0"
- dependencies:
- hoist-non-react-statics: ^2.5.5
- intl-format-cache: ^2.0.5
- intl-messageformat: ^2.1.0
- intl-relativeformat: ^2.1.0
- invariant: ^2.1.1
+"react-intl@npm:3.12.1":
+ version: 3.12.1
+ resolution: "react-intl@npm:3.12.1"
+ dependencies:
+ "@formatjs/intl-displaynames": ^1.2.0
+ "@formatjs/intl-listformat": ^1.4.1
+ "@formatjs/intl-relativetimeformat": ^4.5.9
+ "@formatjs/intl-unified-numberformat": ^3.2.0
+ "@formatjs/intl-utils": ^2.2.0
+ "@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.21
+ intl-messageformat: ^7.8.4
+ intl-messageformat-parser: ^3.6.4
+ shallow-equal: ^1.2.1
peerDependencies:
- prop-types: ^15.5.4
- react: ^0.14.9 || ^15.0.0 || ^16.0.0
- checksum: c23ff0b895af8c563435ccace81d8eb32c27e078fad9cf10a44f4409b53c9e4eab08ec7ebc25a17a0ff60d8542b745aff8ee3c323aeaf6ed2dae1b27d7d47840
+ react: ^16.3.0
+ checksum: 4a9e9101d8d5bd60c73713b99bdad2deb2b6b21fd953f16165b5c4be64aafd503418e009736ba986ca75756c08ad41b80991090e222d80b2bebfefb027bf11eb
languageName: node
linkType: hard
languageName: node
linkType: hard
+"shallow-equal@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "shallow-equal@npm:1.2.1"
+ checksum: 4f1645cc516e7754c4438db687e1da439a5f29a7dba2ba90c5f88e5708aeb17bc4355ba45cad805b0e95dc898e37d8bf6d77d854919c7512f89939986cff8cd1
+ languageName: node
+ linkType: hard
+
"shallowequal@npm:^1.1.0":
version: 1.1.0
resolution: "shallowequal@npm:1.1.0"