Upgraded to the newest version of react-intl

This commit is contained in:
Przemek Wiech
2021-04-02 00:40:57 +02:00
parent 44e1954dda
commit df5ae76180
13 changed files with 653 additions and 778 deletions

1280
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -23,7 +23,7 @@
"query-string": "^7.0.0", "query-string": "^7.0.0",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-intl": "^2.8.0", "react-intl": "^5.15.5",
"react-linkify": "^0.2.2", "react-linkify": "^0.2.2",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"semantic-ui-css": "^2.4.1", "semantic-ui-css": "^2.4.1",
@@ -45,7 +45,6 @@
"@types/md5": "^2.3.0", "@types/md5": "^2.3.0",
"@types/react": "^17.0.3", "@types/react": "^17.0.3",
"@types/react-dom": "^17.0.3", "@types/react-dom": "^17.0.3",
"@types/react-intl": "^2.3.15",
"@types/react-router-dom": "^5.1.7", "@types/react-router-dom": "^5.1.7",
"@typescript-eslint/eslint-plugin": "^4.19.0", "@typescript-eslint/eslint-plugin": "^4.19.0",
"@typescript-eslint/parser": "^4.19.0", "@typescript-eslint/parser": "^4.19.0",

View File

@@ -2,13 +2,12 @@ import * as H from 'history';
import * as queryString from 'query-string'; import * as queryString from 'query-string';
import * as React from 'react'; import * as React from 'react';
import {analyticsEvent} from './util/analytics'; import {analyticsEvent} from './util/analytics';
import {Chart, ChartType} from './chart'; import {Chart, ChartComponent, ChartType} from './chart';
import {Details} from './details'; import {Details} from './details';
import {EmbeddedDataSource, EmbeddedSourceSpec} from './datasource/embedded'; import {EmbeddedDataSource, EmbeddedSourceSpec} from './datasource/embedded';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage, WrappedComponentProps} from 'react-intl';
import {TopolaData} from './util/gedcom_util'; import {TopolaData} from './util/gedcom_util';
import {IndiInfo} from 'topola'; import {IndiInfo} from 'topola';
import {intlShape} from 'react-intl';
import {Intro} from './intro'; import {Intro} from './intro';
import {Loader, Message, Portal, Responsive} from 'semantic-ui-react'; import {Loader, Message, Portal, Responsive} from 'semantic-ui-react';
import {Redirect, Route, RouteComponentProps, Switch} from 'react-router-dom'; import {Redirect, Route, RouteComponentProps, Switch} from 'react-router-dom';
@@ -187,19 +186,17 @@ interface State {
freezeAnimation?: boolean; freezeAnimation?: boolean;
} }
export class App extends React.Component<RouteComponentProps, {}> { export class App extends React.Component<
RouteComponentProps & WrappedComponentProps,
{}
> {
state: State = { state: State = {
state: AppState.INITIAL, state: AppState.INITIAL,
standalone: true, standalone: true,
chartType: ChartType.Hourglass, chartType: ChartType.Hourglass,
showErrorPopup: false, showErrorPopup: false,
}; };
chartRef: Chart | null = null; chartRef: ChartComponent | null = null;
/** Make intl appear in this.context. */
static contextTypes = {
intl: intlShape,
};
/** Sets the state with a new individual selection and chart type. */ /** Sets the state with a new individual selection and chart type. */
private updateDisplay( private updateDisplay(
@@ -234,9 +231,7 @@ export class App extends React.Component<RouteComponentProps, {}> {
private readonly uploadedDataSource = new UploadedDataSource(); private readonly uploadedDataSource = new UploadedDataSource();
private readonly gedcomUrlDataSource = new GedcomUrlDataSource(); private readonly gedcomUrlDataSource = new GedcomUrlDataSource();
private readonly wikiTreeDataSource = new WikiTreeDataSource( private readonly wikiTreeDataSource = new WikiTreeDataSource(this.props.intl);
this.context.intl,
);
private readonly embeddedDataSource = new EmbeddedDataSource(); private readonly embeddedDataSource = new EmbeddedDataSource();
private isNewData(sourceSpec: DataSourceSpec, selection?: IndiInfo) { private isNewData(sourceSpec: DataSourceSpec, selection?: IndiInfo) {
@@ -331,7 +326,7 @@ export class App extends React.Component<RouteComponentProps, {}> {
}), }),
); );
} catch (error) { } catch (error) {
this.setError(getI18nMessage(error, this.context.intl)); this.setError(getI18nMessage(error, this.props.intl));
} }
} else if ( } else if (
this.state.state === AppState.SHOWING_CHART || this.state.state === AppState.SHOWING_CHART ||
@@ -353,10 +348,7 @@ export class App extends React.Component<RouteComponentProps, {}> {
}); });
if (loadMoreFromWikitree) { if (loadMoreFromWikitree) {
try { try {
const data = await loadWikiTree( const data = await loadWikiTree(args.selection!.id, this.props.intl);
args.selection!.id,
this.context.intl,
);
const selection = getSelection(data.chartData, args.selection); const selection = getSelection(data.chartData, args.selection);
this.setState( this.setState(
Object.assign({}, this.state, { Object.assign({}, this.state, {
@@ -367,7 +359,7 @@ export class App extends React.Component<RouteComponentProps, {}> {
); );
} catch (error) { } catch (error) {
this.showErrorPopup( this.showErrorPopup(
this.context.intl.formatMessage( this.props.intl.formatMessage(
{ {
id: 'error.failed_wikitree_load_more', id: 'error.failed_wikitree_load_more',
defaultMessage: 'Failed to load data from WikiTree. {error}', defaultMessage: 'Failed to load data from WikiTree. {error}',
@@ -424,7 +416,7 @@ export class App extends React.Component<RouteComponentProps, {}> {
this.chartRef && (await this.chartRef.downloadPdf()); this.chartRef && (await this.chartRef.downloadPdf());
} catch (e) { } catch (e) {
this.showErrorPopup( this.showErrorPopup(
this.context.intl.formatMessage({ this.props.intl.formatMessage({
id: 'error.failed_pdf', id: 'error.failed_pdf',
defaultMessage: defaultMessage:
'Failed to generate PDF file.' + 'Failed to generate PDF file.' +
@@ -440,7 +432,7 @@ export class App extends React.Component<RouteComponentProps, {}> {
this.chartRef && (await this.chartRef.downloadPng()); this.chartRef && (await this.chartRef.downloadPng());
} catch (e) { } catch (e) {
this.showErrorPopup( this.showErrorPopup(
this.context.intl.formatMessage({ this.props.intl.formatMessage({
id: 'error.failed_png', id: 'error.failed_png',
defaultMessage: defaultMessage:
'Failed to generate PNG file.' + 'Failed to generate PNG file.' +

View File

@@ -1,7 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import {select, Selection} from 'd3-selection'; import {select, Selection} from 'd3-selection';
import {interpolateNumber} from 'd3-interpolate'; import {interpolateNumber} from 'd3-interpolate';
import {intlShape} from 'react-intl'; import {injectIntl, WrappedComponentProps} from 'react-intl';
import {max, min} from 'd3-array'; import {max, min} from 'd3-array';
import {Responsive} from 'semantic-ui-react'; import {Responsive} from 'semantic-ui-react';
import {saveAs} from 'file-saver'; import {saveAs} from 'file-saver';
@@ -149,7 +149,10 @@ export interface ChartProps {
} }
/** Component showing the genealogy chart and handling transition animations. */ /** Component showing the genealogy chart and handling transition animations. */
export class Chart extends React.PureComponent<ChartProps, {}> { export class ChartComponent extends React.PureComponent<
ChartProps & WrappedComponentProps,
{}
> {
private chart?: ChartHandle; private chart?: ChartHandle;
/** Animation is in progress. */ /** Animation is in progress. */
private animating = false; private animating = false;
@@ -214,7 +217,7 @@ export class Chart extends React.PureComponent<ChartProps, {}> {
indiCallback: (info) => this.props.onSelection(info), indiCallback: (info) => this.props.onSelection(info),
animate: true, animate: true,
updateSvgSize: false, updateSvgSize: false,
locale: this.context.intl.locale, locale: this.props.intl.locale,
}); });
} else { } else {
this.chart!.setData(this.props.data); this.chart!.setData(this.props.data);
@@ -303,11 +306,6 @@ export class Chart extends React.PureComponent<ChartProps, {}> {
this.renderChart({initialRender}); this.renderChart({initialRender});
} }
/** Make intl appear in this.context. */
static contextTypes = {
intl: intlShape,
};
render() { render() {
return ( return (
<div id="svgContainer"> <div id="svgContainer">
@@ -410,3 +408,4 @@ export class Chart extends React.PureComponent<ChartProps, {}> {
doc.save('topola.pdf'); doc.save('topola.pdf');
} }
} }
export const Chart = injectIntl(ChartComponent, {forwardRef: true});

View File

@@ -4,7 +4,7 @@ import {DataSource, DataSourceEnum, SourceSelection} from './data_source';
import {Date, DateOrRange, JsonFam, JsonIndi} from 'topola'; import {Date, DateOrRange, JsonFam, JsonIndi} from 'topola';
import {GedcomData, normalizeGedcom, TopolaData} from '../util/gedcom_util'; import {GedcomData, normalizeGedcom, TopolaData} from '../util/gedcom_util';
import {GedcomEntry} from 'parse-gedcom'; import {GedcomEntry} from 'parse-gedcom';
import {InjectedIntl} from 'react-intl'; import {IntlShape} from 'react-intl';
import {TopolaError} from '../util/error'; import {TopolaError} from '../util/error';
/** Prefix for IDs of private individuals. */ /** Prefix for IDs of private individuals. */
@@ -223,7 +223,7 @@ export function getLoggedInUserName(): string | undefined {
*/ */
export async function loadWikiTree( export async function loadWikiTree(
key: string, key: string,
intl: InjectedIntl, intl: IntlShape,
authcode?: string, authcode?: string,
): Promise<TopolaData> { ): Promise<TopolaData> {
// Work around CORS if not in apps.wikitree.com domain. // Work around CORS if not in apps.wikitree.com domain.
@@ -419,7 +419,7 @@ function getFamilyId(spouse1: number, spouse2: number) {
return `${spouse2}_${spouse1}`; return `${spouse2}_${spouse1}`;
} }
function convertPerson(person: Person, intl: InjectedIntl): JsonIndi { function convertPerson(person: Person, intl: IntlShape): JsonIndi {
const indi: JsonIndi = { const indi: JsonIndi = {
id: person.Name, id: person.Name,
}; };
@@ -578,7 +578,7 @@ export interface WikiTreeSourceSpec {
/** Loading data from the WikiTree API. */ /** Loading data from the WikiTree API. */
export class WikiTreeDataSource implements DataSource<WikiTreeSourceSpec> { export class WikiTreeDataSource implements DataSource<WikiTreeSourceSpec> {
constructor(private intl: InjectedIntl) {} constructor(private intl: IntlShape) {}
isNewData( isNewData(
newSource: SourceSelection<WikiTreeSourceSpec>, newSource: SourceSelection<WikiTreeSourceSpec>,

View File

@@ -1,10 +1,14 @@
import * as React from 'react'; import * as React from 'react';
import flatMap from 'array.prototype.flatmap'; import flatMap from 'array.prototype.flatmap';
import Linkify from 'react-linkify'; import Linkify from 'react-linkify';
import {FormattedMessage, InjectedIntl} from 'react-intl'; import {
FormattedMessage,
injectIntl,
IntlShape,
WrappedComponentProps,
} from 'react-intl';
import {GedcomData, pointerToId} from './util/gedcom_util'; import {GedcomData, pointerToId} from './util/gedcom_util';
import {GedcomEntry} from 'parse-gedcom'; import {GedcomEntry} from 'parse-gedcom';
import {intlShape} from 'react-intl';
import {translateDate} from './util/date_util'; import {translateDate} from './util/date_util';
interface Props { interface Props {
@@ -76,7 +80,7 @@ function getData(entry: GedcomEntry) {
return result; return result;
} }
function eventDetails(entry: GedcomEntry, intl: InjectedIntl) { function eventDetails(entry: GedcomEntry, intl: IntlShape) {
const lines = []; const lines = [];
if (entry.data && entry.data.length > 1) { if (entry.data && entry.data.length > 1) {
lines.push(<i>{entry.data}</i>); lines.push(<i>{entry.data}</i>);
@@ -205,12 +209,10 @@ function dereference(entry: GedcomEntry, gedcom: GedcomData) {
return entry; return entry;
} }
export class Details extends React.Component<Props, {}> { class DetailsComponent extends React.Component<
/** Make intl appear in this.context. */ Props & WrappedComponentProps,
static contextTypes = { {}
intl: intlShape, > {
};
render() { render() {
const entries = this.props.gedcom.indis[this.props.indi].tree; const entries = this.props.gedcom.indis[this.props.indi].tree;
const entriesWithData = entries const entriesWithData = entries
@@ -221,7 +223,7 @@ export class Details extends React.Component<Props, {}> {
<div className="ui segments" id="details"> <div className="ui segments" id="details">
{getDetails(entries, ['NAME'], nameDetails)} {getDetails(entries, ['NAME'], nameDetails)}
{getDetails(entries, EVENT_TAGS, (entry) => {getDetails(entries, EVENT_TAGS, (entry) =>
eventDetails(entry, this.context.intl as InjectedIntl), eventDetails(entry, this.props.intl),
)} )}
{getOtherDetails(entriesWithData)} {getOtherDetails(entriesWithData)}
{getDetails(entriesWithData, ['NOTE'], noteDetails)} {getDetails(entriesWithData, ['NOTE'], noteDetails)}
@@ -229,3 +231,4 @@ export class Details extends React.Component<Props, {}> {
); );
} }
} }
export const Details = injectIntl(DetailsComponent);

View File

@@ -1,9 +1,3 @@
import * as locale_de from 'react-intl/locale-data/de';
import * as locale_en from 'react-intl/locale-data/en';
import * as locale_fr from 'react-intl/locale-data/fr';
import * as locale_it from 'react-intl/locale-data/it';
import * as locale_pl from 'react-intl/locale-data/pl';
import * as locale_ru from 'react-intl/locale-data/ru';
import * as React from 'react'; import * as React from 'react';
import * as ReactDOM from 'react-dom'; import * as ReactDOM from 'react-dom';
import messages_de from './translations/de.json'; import messages_de from './translations/de.json';
@@ -11,7 +5,6 @@ import messages_fr from './translations/fr.json';
import messages_it from './translations/it.json'; import messages_it from './translations/it.json';
import messages_pl from './translations/pl.json'; import messages_pl from './translations/pl.json';
import messages_ru from './translations/ru.json'; import messages_ru from './translations/ru.json';
import {addLocaleData} from 'react-intl';
import {App} from './app'; import {App} from './app';
import {detect} from 'detect-browser'; import {detect} from 'detect-browser';
import {HashRouter as Router, Route} from 'react-router-dom'; import {HashRouter as Router, Route} from 'react-router-dom';
@@ -20,15 +13,6 @@ import './index.css';
import 'semantic-ui-css/semantic.min.css'; import 'semantic-ui-css/semantic.min.css';
import 'canvas-toBlob'; import 'canvas-toBlob';
addLocaleData([
...locale_de,
...locale_en,
...locale_fr,
...locale_it,
...locale_pl,
...locale_ru,
]);
const messages = { const messages = {
de: messages_de, de: messages_de,
fr: messages_fr, fr: messages_fr,

View File

@@ -4,7 +4,7 @@ import {analyticsEvent} from '../util/analytics';
import {buildSearchIndex, SearchIndex, SearchResult} from './search_index'; import {buildSearchIndex, SearchIndex, SearchResult} from './search_index';
import {formatDateOrRange} from '../util/date_util'; import {formatDateOrRange} from '../util/date_util';
import {IndiInfo, JsonGedcomData} from 'topola'; import {IndiInfo, JsonGedcomData} from 'topola';
import {intlShape} from 'react-intl'; import {injectIntl, WrappedComponentProps} from 'react-intl';
import {JsonIndi} from 'topola'; import {JsonIndi} from 'topola';
import {RouteComponentProps} from 'react-router-dom'; import {RouteComponentProps} from 'react-router-dom';
import {Search, SearchProps, SearchResultProps} from 'semantic-ui-react'; import {Search, SearchProps, SearchResultProps} from 'semantic-ui-react';
@@ -32,24 +32,20 @@ interface State {
} }
/** Displays and handles the search box in the top bar. */ /** Displays and handles the search box in the top bar. */
export class SearchBar extends React.Component< class SearchBarComponent extends React.Component<
RouteComponentProps & Props, RouteComponentProps & WrappedComponentProps & Props,
State State
> { > {
state: State = { state: State = {
searchResults: [], searchResults: [],
}; };
/** Make intl appear in this.context. */
static contextTypes = {
intl: intlShape,
};
searchRef?: {setValue(value: string): void}; searchRef?: {setValue(value: string): void};
searchIndex?: SearchIndex; searchIndex?: SearchIndex;
private getDescriptionLine(indi: JsonIndi) { private getDescriptionLine(indi: JsonIndi) {
const birthDate = formatDateOrRange(indi.birth, this.context.intl); const birthDate = formatDateOrRange(indi.birth, this.props.intl);
const deathDate = formatDateOrRange(indi.death, this.context.intl); const deathDate = formatDateOrRange(indi.death, this.props.intl);
if (!deathDate) { if (!deathDate) {
return birthDate; return birthDate;
} }
@@ -108,11 +104,11 @@ export class SearchBar extends React.Component<
)} )}
onResultSelect={(_, data) => this.handleResultSelect(data.result.id)} onResultSelect={(_, data) => this.handleResultSelect(data.result.id)}
results={this.state.searchResults} results={this.state.searchResults}
noResultsMessage={this.context.intl.formatMessage({ noResultsMessage={this.props.intl.formatMessage({
id: 'menu.search.no_results', id: 'menu.search.no_results',
defaultMessage: 'No results found', defaultMessage: 'No results found',
})} })}
placeholder={this.context.intl.formatMessage({ placeholder={this.props.intl.formatMessage({
id: 'menu.search.placeholder', id: 'menu.search.placeholder',
defaultMessage: 'Search for people', defaultMessage: 'Search for people',
})} })}
@@ -127,3 +123,4 @@ export class SearchBar extends React.Component<
); );
} }
} }
export const SearchBar = injectIntl(SearchBarComponent);

View File

@@ -65,7 +65,7 @@ class LunrSearchIndex implements SearchIndex {
initialize() { initialize() {
const self = this; const self = this;
this.index = lunr(function() { this.index = lunr(function () {
this.use((lunr as any).multiLanguage('de', 'en', 'fr', 'it', 'ru')); this.use((lunr as any).multiLanguage('de', 'en', 'fr', 'it', 'ru'));
this.ref('id'); this.ref('id');
this.field('id'); this.field('id');

View File

@@ -77,7 +77,6 @@ export class UrlMenu extends React.Component<
<FormattedMessage <FormattedMessage
id="load_from_url.title" id="load_from_url.title"
defaultMessage="Load from URL" defaultMessage="Load from URL"
children={(txt) => txt}
/> />
</Header> </Header>
<Modal.Content> <Modal.Content>

View File

@@ -2,7 +2,7 @@ import * as queryString from 'query-string';
import * as React from 'react'; import * as React from 'react';
import wikitreeLogo from './wikitree.png'; import wikitreeLogo from './wikitree.png';
import {analyticsEvent} from '../util/analytics'; import {analyticsEvent} from '../util/analytics';
import {FormattedMessage, intlShape} from 'react-intl'; import {FormattedMessage, injectIntl, WrappedComponentProps} from 'react-intl';
import {getLoggedInUserName} from '../datasource/wikitree'; import {getLoggedInUserName} from '../datasource/wikitree';
import {MenuItem, MenuType} from './menu_item'; import {MenuItem, MenuType} from './menu_item';
import {RouteComponentProps} from 'react-router-dom'; import {RouteComponentProps} from 'react-router-dom';
@@ -106,7 +106,6 @@ export class WikiTreeMenu extends React.Component<
<FormattedMessage <FormattedMessage
id="select_wikitree_id.title" id="select_wikitree_id.title"
defaultMessage="Select WikiTree ID" defaultMessage="Select WikiTree ID"
children={(txt) => txt}
/> />
</Header> </Header>
<Modal.Content> <Modal.Content>
@@ -196,17 +195,13 @@ interface LoginState {
} }
/** Displays and handles the "Log in to WikiTree" menu. */ /** Displays and handles the "Log in to WikiTree" menu. */
export class WikiTreeLoginMenu extends React.Component< class WikiTreeLoginMenuComponent extends React.Component<
RouteComponentProps & Props, RouteComponentProps & WrappedComponentProps & Props,
LoginState LoginState
> { > {
state: LoginState = { state: LoginState = {
wikiTreeLoginState: WikiTreeLoginState.UNKNOWN, wikiTreeLoginState: WikiTreeLoginState.UNKNOWN,
}; };
/** Make intl appear in this.context. */
static contextTypes = {
intl: intlShape,
};
wikiTreeLoginFormRef: React.RefObject<HTMLFormElement> = React.createRef(); wikiTreeLoginFormRef: React.RefObject<HTMLFormElement> = React.createRef();
wikiTreeReturnUrlRef: React.RefObject<HTMLInputElement> = React.createRef(); wikiTreeReturnUrlRef: React.RefObject<HTMLInputElement> = React.createRef();
@@ -285,14 +280,14 @@ export class WikiTreeLoginMenu extends React.Component<
case WikiTreeLoginState.LOGGED_IN: case WikiTreeLoginState.LOGGED_IN:
const tooltip = this.state.wikiTreeLoginUsername const tooltip = this.state.wikiTreeLoginUsername
? this.context.intl.formatMessage( ? this.props.intl.formatMessage(
{ {
id: 'menu.wikitree_popup_username', id: 'menu.wikitree_popup_username',
defaultMessage: 'Logged in to WikiTree as {username}', defaultMessage: 'Logged in to WikiTree as {username}',
}, },
{username: this.state.wikiTreeLoginUsername}, {username: this.state.wikiTreeLoginUsername},
) )
: this.context.intl.formatMessage({ : this.props.intl.formatMessage({
id: 'menu.wikitree_popup', id: 'menu.wikitree_popup',
defaultMessage: 'Logged in to WikiTree', defaultMessage: 'Logged in to WikiTree',
}); });
@@ -309,3 +304,4 @@ export class WikiTreeLoginMenu extends React.Component<
return null; return null;
} }
} }
export const WikiTreeLoginMenu = injectIntl(WikiTreeLoginMenuComponent);

View File

@@ -1,5 +1,5 @@
import {Date as TopolaDate, DateOrRange, DateRange, getDate} from 'topola'; import {Date as TopolaDate, DateOrRange, DateRange, getDate} from 'topola';
import {InjectedIntl} from 'react-intl'; import {IntlShape} from 'react-intl';
const DATE_QUALIFIERS = new Map([ const DATE_QUALIFIERS = new Map([
['abt', 'about'], ['abt', 'about'],
@@ -7,7 +7,7 @@ const DATE_QUALIFIERS = new Map([
['est', 'estimated'], ['est', 'estimated'],
]); ]);
function formatDate(date: TopolaDate, intl: InjectedIntl) { function formatDate(date: TopolaDate, intl: IntlShape) {
const hasDay = date.day !== undefined; const hasDay = date.day !== undefined;
const hasMonth = date.month !== undefined; const hasMonth = date.month !== undefined;
const hasYear = date.year !== undefined; const hasYear = date.year !== undefined;
@@ -41,7 +41,7 @@ function formatDate(date: TopolaDate, intl: InjectedIntl) {
return [translatedQualifier, translatedDate].join(' '); return [translatedQualifier, translatedDate].join(' ');
} }
function formatDateRage(dateRange: DateRange, intl: InjectedIntl) { function formatDateRage(dateRange: DateRange, intl: IntlShape) {
const fromDate = dateRange.from; const fromDate = dateRange.from;
const toDate = dateRange.to; const toDate = dateRange.to;
const translatedFromDate = fromDate && formatDate(fromDate, intl); const translatedFromDate = fromDate && formatDate(fromDate, intl);
@@ -79,7 +79,7 @@ function formatDateRage(dateRange: DateRange, intl: InjectedIntl) {
/** Formats a DateOrRange object. */ /** Formats a DateOrRange object. */
export function formatDateOrRange( export function formatDateOrRange(
dateOrRange: DateOrRange | undefined, dateOrRange: DateOrRange | undefined,
intl: InjectedIntl, intl: IntlShape,
): string { ): string {
if (!dateOrRange) { if (!dateOrRange) {
return ''; return '';
@@ -94,6 +94,6 @@ export function formatDateOrRange(
} }
/** Formats a date given in GEDCOM format. */ /** Formats a date given in GEDCOM format. */
export function translateDate(gedcomDate: string, intl: InjectedIntl): string { export function translateDate(gedcomDate: string, intl: IntlShape): string {
return formatDateOrRange(getDate(gedcomDate), intl); return formatDateOrRange(getDate(gedcomDate), intl);
} }

View File

@@ -1,11 +1,11 @@
import {InjectedIntl} from 'react-intl'; import {IntlShape} from 'react-intl';
import {TopolaError} from './error'; import {TopolaError} from './error';
/** /**
* Returns a translated message for the given error. If the message can't be * Returns a translated message for the given error. If the message can't be
* translated, the original error.message is returned. * translated, the original error.message is returned.
*/ */
export function getI18nMessage(error: Error, intl: InjectedIntl): string { export function getI18nMessage(error: Error, intl: IntlShape): string {
if (!(error instanceof TopolaError)) { if (!(error instanceof TopolaError)) {
return error.message; return error.message;
} }