diff --git a/client/components/Events/EventItem.tsx b/client/components/Events/EventItem.tsx index d338bc4de..7371a3c13 100644 --- a/client/components/Events/EventItem.tsx +++ b/client/components/Events/EventItem.tsx @@ -44,7 +44,8 @@ class EventItemComponent extends React.Component { return isItemDifferent(this.props, nextProps) || this.state.hover !== nextState.hover || this.props.minTimeWidth !== nextProps.minTimeWidth || - this.props.lockedItems != nextProps.lockedItems; + this.props.lockedItems != nextProps.lockedItems || + this.props.filterLanguage !== nextProps.filterLanguage; } onItemHoverOn() { @@ -216,7 +217,7 @@ class EventItemComponent extends React.Component { {renderFields(get(listFields, 'event.primary_fields', - EVENTS.LIST.PRIMARY_FIELDS), item)} + EVENTS.LIST.PRIMARY_FIELDS), item, this.props)} diff --git a/client/components/Main/ListGroupItem.tsx b/client/components/Main/ListGroupItem.tsx index 821d628c9..fd1956f88 100644 --- a/client/components/Main/ListGroupItem.tsx +++ b/client/components/Main/ListGroupItem.tsx @@ -1,11 +1,11 @@ import React from 'react'; import {debounce, indexOf} from 'lodash'; - +import {connect} from 'react-redux'; import { IEventListItemProps, IPlanningListItemProps, IEventOrPlanningItem, - IEventItem, IPlanningItem, IBaseListItemProps + IEventItem, IPlanningItem, IBaseListItemProps, ISearchAPIParams } from '../../interfaces'; import {EventItem, EventItemWithPlanning} from '../Events'; @@ -13,6 +13,7 @@ import {PlanningItem} from '../Planning'; import {ITEM_TYPE, EVENTS, PLANNING, MAIN, CLICK_DELAY} from '../../constants'; import {getItemType, eventUtils} from '../../utils'; +import {currentSearchParams} from '../../selectors/search'; interface IProps extends Omit< IEventListItemProps & IPlanningListItemProps, @@ -33,13 +34,18 @@ interface IProps extends Omit< navigateList(increment?: boolean): void; onItemActivate(item: IEventItem, forceActivate?: boolean): void; onItemClick(index: number, item: IEventOrPlanningItem): void; + currentParams:ISearchAPIParams } interface IState { clickedOnce?: boolean; } -export class ListGroupItem extends React.Component { +const mapStateToProps = (state) => ({ + currentParams: currentSearchParams(state), +}); + +class ListGroupComponent extends React.Component { dom: {item: HTMLElement}; _delayedClick: any | undefined; @@ -122,6 +128,7 @@ export class ListGroupItem extends React.Component { listViewType, sortField, minTimeWidth, + currentParams } = this.props; const itemType = getItemType(item); @@ -151,6 +158,7 @@ export class ListGroupItem extends React.Component { ...itemProps, item: item as IEventItem, calendars: calendars, + filterLanguage: currentParams?.language, multiSelected: indexOf(selectedEventIds, item._id) !== -1, [EVENTS.ITEM_ACTIONS.EDIT_EVENT.actionName]: itemActions[EVENTS.ITEM_ACTIONS.EDIT_EVENT.actionName], @@ -193,6 +201,7 @@ export class ListGroupItem extends React.Component { contentTypes: contentTypes, agendas: agendas, date: date, + filterLanguage: currentParams?.language, onAddCoverageClick: onAddCoverageClick, multiSelected: indexOf(selectedPlanningIds, item._id) !== -1, showAddCoverage: showAddCoverage, @@ -265,3 +274,5 @@ export class ListGroupItem extends React.Component { return null; } } + +export const ListGroupItem = connect(mapStateToProps)(ListGroupComponent); \ No newline at end of file diff --git a/client/components/Planning/PlanningItem.tsx b/client/components/Planning/PlanningItem.tsx index 1f78be4be..cb34c22e0 100644 --- a/client/components/Planning/PlanningItem.tsx +++ b/client/components/Planning/PlanningItem.tsx @@ -64,7 +64,8 @@ class PlanningItemComponent extends React.Component { planningUtils.getAgendaNames(this.props.item, this.props.agendas), planningUtils.getAgendaNames(nextProps.item, nextProps.agendas) ) || - this.props.minTimeWidth !== nextProps.minTimeWidth; + this.props.minTimeWidth !== nextProps.minTimeWidth || + this.props.filterLanguage !== nextProps.filterLanguage; } onItemHoverOn() { @@ -235,7 +236,7 @@ class PlanningItemComponent extends React.Component { {renderFields(get(listFields, 'planning.primary_fields', - PLANNING.LIST.PRIMARY_FIELDS), item)} + PLANNING.LIST.PRIMARY_FIELDS), item, this.props)} {event && ( diff --git a/client/components/fields/headline.tsx b/client/components/fields/headline.tsx index 248f1d716..2b80db1f3 100644 --- a/client/components/fields/headline.tsx +++ b/client/components/fields/headline.tsx @@ -1,9 +1,12 @@ import PropTypes from 'prop-types'; +import {getTranslatedValue} from '.'; -export const headline = ({item}) => item.headline || null; +export const headline = ({item, filterLanguage}) => getTranslatedValue(filterLanguage, item, 'headline') || +item.headline || null; headline.propTypes = { item: PropTypes.shape({ headline: PropTypes.string, }).isRequired, + filterLanguage: PropTypes.string, }; \ No newline at end of file diff --git a/client/components/fields/index.tsx b/client/components/fields/index.tsx index 96fdbd8ab..f97cc5ae5 100644 --- a/client/components/fields/index.tsx +++ b/client/components/fields/index.tsx @@ -45,7 +45,7 @@ export function registerField(id, component) { * @param {Object} item * @param {Object} props */ -export function renderFields(fields, item, props = {}) { +export function renderFields(fields, item, props = {filterLanguage: ''}) { const language = getUserInterfaceLanguageFromCV(); return (Array.isArray(fields) ? fields : [fields]).map((id) => { @@ -66,6 +66,23 @@ export function renderFields(fields, item, props = {}) { }); } +/** + * Get translated field value based on languagei + * @param {String} language + * @param {Object} item + * @param {String} fieldName + */ +export function getTranslatedValue(language, item, fieldName) { + if (item.translations) { + const matchingTranslation = item.translations.find( + (translation) => translation.field === fieldName && translation.language === language + ); + + return matchingTranslation ? matchingTranslation.value : null; + } + return null; +} + function getFieldsForPanel(panelType: IRenderPanelType) { switch (panelType) { case 'editor': diff --git a/client/components/fields/name.tsx b/client/components/fields/name.tsx index cbd92e50b..7e4161ba8 100644 --- a/client/components/fields/name.tsx +++ b/client/components/fields/name.tsx @@ -1,9 +1,11 @@ import PropTypes from 'prop-types'; +import {getTranslatedValue} from '.'; -export const name = ({item}) => item.name || null; +export const name = ({item, filterLanguage}) => getTranslatedValue(filterLanguage, item, 'name') || item.name || null; name.propTypes = { item: PropTypes.shape({ name: PropTypes.string, }).isRequired, + filterLanguage: PropTypes.string, }; \ No newline at end of file diff --git a/client/components/fields/slugline.tsx b/client/components/fields/slugline.tsx index afb63a53a..14563dc53 100644 --- a/client/components/fields/slugline.tsx +++ b/client/components/fields/slugline.tsx @@ -2,17 +2,22 @@ import React from 'react'; import PropTypes from 'prop-types'; import {get} from 'lodash'; +import {getTranslatedValue} from '.'; -export const slugline = ({item}) => { +export const slugline = ({item, filterLanguage}) => { if (!get(item, 'slugline', '')) { return null; } - return ({item.slugline}); + return ( + {getTranslatedValue(filterLanguage, item, 'slugline') || + item.slugline} + ); }; slugline.propTypes = { item: PropTypes.shape({ slugline: PropTypes.string, }).isRequired, + filterLanguage: PropTypes.string, }; diff --git a/client/interfaces.ts b/client/interfaces.ts index d07679a52..96c544046 100644 --- a/client/interfaces.ts +++ b/client/interfaces.ts @@ -855,6 +855,7 @@ export interface IBaseListItemProps { export interface IEventListItemProps extends IBaseListItemProps { relatedPlanningText?: string; calendars: Array; + filterLanguage?: string; toggleRelatedPlanning?(event: React.MouseEvent): void; } @@ -863,6 +864,7 @@ export interface IPlanningListItemProps extends IBaseListItemProps; users: Array; desks: Array; + filterLanguage?: string; // showUnlock?: boolean; // Is this used anymore? hideItemActions: boolean; showAddCoverage: boolean;