From a918af62008a64586f020beb04ff16861df8b157 Mon Sep 17 00:00:00 2001 From: Simon Leblanc Date: Wed, 28 Apr 2021 15:30:18 +0200 Subject: [PATCH] Translate date and datetime with React Translator (#350) --- .../src/components/propertyValueElement.tsx | 8 +++--- .../viewHeader/viewHeaderActionsMenu.tsx | 2 +- webapp/src/csvExporter.ts | 10 +++++--- webapp/src/octoUtils.tsx | 6 ++--- webapp/src/utils.ts | 25 ++++++++----------- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/webapp/src/components/propertyValueElement.tsx b/webapp/src/components/propertyValueElement.tsx index d0f742b94..2859594b5 100644 --- a/webapp/src/components/propertyValueElement.tsx +++ b/webapp/src/components/propertyValueElement.tsx @@ -2,6 +2,7 @@ // See LICENSE.txt for license information. import React, {useState} from 'react' +import {injectIntl, IntlShape} from 'react-intl' import {IPropertyOption, IPropertyTemplate, PropertyType} from '../blocks/board' import {Card} from '../blocks/card' @@ -19,14 +20,15 @@ type Props = { card: Card propertyTemplate: IPropertyTemplate emptyDisplayValue: string + intl: IntlShape } const PropertyValueElement = (props:Props): JSX.Element => { const [value, setValue] = useState(props.card.properties[props.propertyTemplate.id]) - const {card, propertyTemplate, readOnly, emptyDisplayValue, boardTree} = props + const {card, propertyTemplate, readOnly, emptyDisplayValue, boardTree, intl} = props const propertyValue = card.properties[propertyTemplate.id] - const displayValue = OctoUtils.propertyDisplayValue(card, propertyValue, propertyTemplate) + const displayValue = OctoUtils.propertyDisplayValue(card, propertyValue, propertyTemplate, intl) const finalDisplayValue = displayValue || emptyDisplayValue const validateProp = (propType: string, val: string): boolean => { @@ -122,4 +124,4 @@ const PropertyValueElement = (props:Props): JSX.Element => { return
{finalDisplayValue}
} -export default PropertyValueElement +export default injectIntl(PropertyValueElement) diff --git a/webapp/src/components/viewHeader/viewHeaderActionsMenu.tsx b/webapp/src/components/viewHeader/viewHeaderActionsMenu.tsx index f6f55263d..7693a4915 100644 --- a/webapp/src/components/viewHeader/viewHeaderActionsMenu.tsx +++ b/webapp/src/components/viewHeader/viewHeaderActionsMenu.tsx @@ -74,7 +74,7 @@ type Props = { function onExportCsvTrigger(boardTree: BoardTree, intl: IntlShape) { try { - CsvExporter.exportTableCsv(boardTree) + CsvExporter.exportTableCsv(boardTree, intl) const exportCompleteMessage = intl.formatMessage({ id: 'ViewHeader.export-complete', defaultMessage: 'Export complete!', diff --git a/webapp/src/csvExporter.ts b/webapp/src/csvExporter.ts index 20a82db36..227e94fc6 100644 --- a/webapp/src/csvExporter.ts +++ b/webapp/src/csvExporter.ts @@ -1,12 +1,14 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import {IntlShape} from 'react-intl' + import {BoardView} from './blocks/boardView' import {BoardTree} from './viewModel/boardTree' import {OctoUtils} from './octoUtils' import {Utils} from './utils' class CsvExporter { - static exportTableCsv(boardTree: BoardTree, view?: BoardView): void { + static exportTableCsv(boardTree: BoardTree, intl: IntlShape, view?: BoardView): void { const {activeView} = boardTree const viewToExport = view ?? activeView @@ -14,7 +16,7 @@ class CsvExporter { return } - const rows = CsvExporter.generateTableArray(boardTree, viewToExport) + const rows = CsvExporter.generateTableArray(boardTree, viewToExport, intl) let csvContent = 'data:text/csv;charset=utf-8,' @@ -40,7 +42,7 @@ class CsvExporter { return text.replace(/"/g, '""') } - private static generateTableArray(boardTree: BoardTree, viewToExport: BoardView): string[][] { + private static generateTableArray(boardTree: BoardTree, viewToExport: BoardView, intl: IntlShape): string[][] { const {board, cards} = boardTree const rows: string[][] = [] @@ -60,7 +62,7 @@ class CsvExporter { row.push(`"${this.encodeText(card.title)}"`) visibleProperties.forEach((template) => { const propertyValue = card.properties[template.id] - const displayValue = OctoUtils.propertyDisplayValue(card, propertyValue, template) || '' + const displayValue = OctoUtils.propertyDisplayValue(card, propertyValue, template, intl) || '' if (template.type === 'number') { const numericValue = propertyValue ? Number(propertyValue).toString() : '' row.push(numericValue) diff --git a/webapp/src/octoUtils.tsx b/webapp/src/octoUtils.tsx index dc07ef3d8..6d9e8d964 100644 --- a/webapp/src/octoUtils.tsx +++ b/webapp/src/octoUtils.tsx @@ -16,7 +16,7 @@ import {FilterCondition} from './blocks/filterClause' import {Utils} from './utils' class OctoUtils { - static propertyDisplayValue(block: IBlock, propertyValue: string | undefined, propertyTemplate: IPropertyTemplate): string | undefined { + static propertyDisplayValue(block: IBlock, propertyValue: string | undefined, propertyTemplate: IPropertyTemplate, intl: IntlShape): string | undefined { let displayValue: string | undefined switch (propertyTemplate.type) { case 'select': { @@ -31,11 +31,11 @@ class OctoUtils { break } case 'createdTime': { - displayValue = Utils.displayDateTime(new Date(block.createAt)) + displayValue = Utils.displayDateTime(new Date(block.createAt), intl) break } case 'updatedTime': { - displayValue = Utils.displayDateTime(new Date(block.updateAt)) + displayValue = Utils.displayDateTime(new Date(block.updateAt), intl) break } default: diff --git a/webapp/src/utils.ts b/webapp/src/utils.ts index 86493c4d0..e2421d929 100644 --- a/webapp/src/utils.ts +++ b/webapp/src/utils.ts @@ -1,6 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import marked from 'marked' +import {IntlShape} from 'react-intl' declare global { interface Window { @@ -55,24 +56,20 @@ class Utils { // Date and Time - static displayDate(date: Date): string { - const dateTimeFormat = new Intl.DateTimeFormat('en', {year: 'numeric', month: 'short', day: '2-digit'}) - const text = dateTimeFormat.format(date) + static displayDate(date: Date, intl: IntlShape): string { + const text = intl.formatDate(date, {year: 'numeric', month: 'short', day: '2-digit'}) return text } - static displayDateTime(date: Date): string { - const dateTimeFormat = new Intl.DateTimeFormat( - 'en', - { - year: 'numeric', - month: 'short', - day: '2-digit', - hour: 'numeric', - minute: 'numeric', - }) - const text = dateTimeFormat.format(date) + static displayDateTime(date: Date, intl: IntlShape): string { + const text = intl.formatDate(date, { + year: 'numeric', + month: 'short', + day: '2-digit', + hour: 'numeric', + minute: 'numeric', + }) return text }