Skip to content

Commit

Permalink
Localized exercise name with other locales shown as a hint created.
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Krulis committed Nov 7, 2017
1 parent 0df5a9a commit d532675
Show file tree
Hide file tree
Showing 17 changed files with 147 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { LinkContainer } from 'react-router-bootstrap';
import DeleteAssignmentButtonContainer from '../../../containers/DeleteAssignmentButtonContainer';

import withLinks from '../../../hoc/withLinks';
import { getLocalizedName } from '../../../helpers/getLocalizedData';
import LocalizedExerciseName from '../../helpers/LocalizedExerciseName';
import {
EditIcon,
MaybePublicIcon,
Expand All @@ -24,7 +24,6 @@ const AdminAssignmentTableRow = ({
firstDeadline,
secondDeadline,
isBonus,
locale,
links: {
ASSIGNMENT_DETAIL_URI_FACTORY: detail,
ASSIGNMENT_EDIT_URI_FACTORY: edit
Expand All @@ -37,7 +36,7 @@ const AdminAssignmentTableRow = ({
<td>
<MaybeBonusAssignmentIcon id={id} isBonus={isBonus} />
<Link to={detail(id)}>
{getLocalizedName({ name, localizedTexts }, locale)}
<LocalizedExerciseName entity={{ name, localizedTexts }} />
</Link>
</td>
<td>
Expand Down Expand Up @@ -80,8 +79,7 @@ AdminAssignmentTableRow.propTypes = {
allowSecondDeadline: PropTypes.bool.isRequired,
secondDeadline: PropTypes.number.isRequired,
groupId: PropTypes.string,
links: PropTypes.object,
locale: PropTypes.string.isRequired
links: PropTypes.object
};

export default withLinks(AdminAssignmentTableRow);
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import AssignmentStatusIcon from '../AssignmentStatusIcon/AssignmentStatusIcon';
import { FormattedDate, FormattedTime } from 'react-intl';

import withLinks from '../../../../hoc/withLinks';
import { getLocalizedName } from '../../../../helpers/getLocalizedData';
import LocalizedExerciseName from '../../../helpers/LocalizedExerciseName';
import { MaybeBonusAssignmentIcon } from '../../../icons';

const AssignmentTableRow = ({
Expand All @@ -23,7 +23,6 @@ const AssignmentTableRow = ({
},
status,
userId,
locale,
links: {
ASSIGNMENT_DETAIL_URI_FACTORY,
ASSIGNMENT_DETAIL_SPECIFIC_USER_URI_FACTORY
Expand All @@ -42,7 +41,7 @@ const AssignmentTableRow = ({
: ASSIGNMENT_DETAIL_URI_FACTORY(id)
}
>
{getLocalizedName({ name, localizedTexts }, locale)}
<LocalizedExerciseName entity={{ name, localizedTexts }} />
</Link>
</td>
{showGroup &&
Expand Down Expand Up @@ -77,8 +76,7 @@ AssignmentTableRow.propTypes = {
}),
status: PropTypes.string,
userId: PropTypes.string,
links: PropTypes.object,
locale: PropTypes.string.isRequired
links: PropTypes.object
};

export default withLinks(AssignmentTableRow);
11 changes: 6 additions & 5 deletions src/components/Exercises/ExerciseDetail/ExerciseDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ import UsersNameContainer from '../../../containers/UsersNameContainer';
import GroupsNameContainer from '../../../containers/GroupsNameContainer';
import styles from './ExerciseDetail.less';
import { MaybeSucceededIcon } from '../../icons';
import {
getLocalizedName,
getLocalizedDescription
} from '../../../helpers/getLocalizedData';
import { getLocalizedDescription } from '../../../helpers/getLocalizedData';
import LocalizedExerciseName from '../../helpers/LocalizedExerciseName';

const ExerciseDetail = ({
id,
Expand All @@ -40,7 +38,10 @@ const ExerciseDetail = ({
locale,
links: { EXERCISE_URI_FACTORY }
}) =>
<Box title={getLocalizedName({ name, localizedTexts }, locale)} noPadding>
<Box
title={<LocalizedExerciseName entity={{ name, localizedTexts }} />}
noPadding
>
<Table>
<tbody>
<tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import GroupsNameContainer from '../../../containers/GroupsNameContainer';
import { Link } from 'react-router';

import withLinks from '../../../hoc/withLinks';
import { getLocalizedName } from '../../../helpers/getLocalizedData';
import LocalizedExerciseName from '../../helpers/LocalizedExerciseName';
import { MaybeLockedExerciseIcon } from '../../icons';

const ExercisesListItem = ({
Expand All @@ -32,7 +32,7 @@ const ExercisesListItem = ({
<MaybeLockedExerciseIcon id={id} isLocked={isLocked} />
<strong>
<Link to={EXERCISE_URI_FACTORY(id)}>
{getLocalizedName({ name, localizedTexts }, locale)}
<LocalizedExerciseName entity={{ name, localizedTexts }} />
</Link>
</strong>
</td>
Expand Down
10 changes: 4 additions & 6 deletions src/components/Exercises/ExercisesName/ExercisesName.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { Link } from 'react-router';

import withLinks from '../../../hoc/withLinks';
import { getLocalizedName } from '../../../helpers/getLocalizedData';
import LocalizedExerciseName from '../../helpers/LocalizedExerciseName';

import { MaybeLockedExerciseIcon } from '../../icons';

Expand All @@ -13,17 +13,16 @@ const ExercisesName = ({
localizedTexts,
isLocked,
noLink,
locale,
links: { EXERCISE_URI_FACTORY }
}) =>
<span>
<MaybeLockedExerciseIcon id={id} isLocked={isLocked} />
{noLink
? <span>
{getLocalizedName({ name, localizedTexts }, locale)}
<LocalizedExerciseName entity={{ name, localizedTexts }} />
</span>
: <Link to={EXERCISE_URI_FACTORY(id)}>
{getLocalizedName({ name, localizedTexts }, locale)}
<LocalizedExerciseName entity={{ name, localizedTexts }} />
</Link>}
</span>;

Expand All @@ -33,8 +32,7 @@ ExercisesName.propTypes = {
localizedTexts: PropTypes.array.isRequired,
isLocked: PropTypes.bool.isRequired,
noLink: PropTypes.bool,
links: PropTypes.object,
locale: PropTypes.string.isRequired
links: PropTypes.object
};

export default withLinks(ExercisesName);
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import UsersNameContainer from '../../../containers/UsersNameContainer';
import { Link } from 'react-router';

import withLinks from '../../../hoc/withLinks';
import { getLocalizedName } from '../../../helpers/getLocalizedData';
import LocalizedExerciseName from '../../helpers/LocalizedExerciseName';
import { MaybeLockedExerciseIcon } from '../../icons';

const ExercisesSimpleListItem = ({
Expand All @@ -24,7 +24,7 @@ const ExercisesSimpleListItem = ({
<MaybeLockedExerciseIcon id={id} isLocked={isLocked} />
<strong>
<Link to={EXERCISE_URI_FACTORY(id)}>
{getLocalizedName({ name, localizedTexts }, locale)}
<LocalizedExerciseName entity={{ name, localizedTexts }} />
</Link>
</strong>
</td>
Expand Down
12 changes: 5 additions & 7 deletions src/components/Groups/ResultsTable/ResultsTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,20 @@ import PropTypes from 'prop-types';
import { List } from 'immutable';
import { Table } from 'react-bootstrap';
import { Link } from 'react-router';
import { FormattedMessage, injectIntl } from 'react-intl';
import { FormattedMessage } from 'react-intl';

import ResultsTableRow from './ResultsTableRow';
import LoadingResultsTableRow from './LoadingResultsTableRow';
import NoResultsAvailableRow from './NoResultsAvailableRow';
import withLinks from '../../../hoc/withLinks';
import { getLocalizedName } from '../../../helpers/getLocalizedData';
import ResourceRenderer from '../../helpers/ResourceRenderer';
import LocalizedExerciseName from '../../helpers/LocalizedExerciseName';
import styles from './ResultsTable.less';

const ResultsTable = ({
assignments = List(),
users = [],
submissions,
intl: { locale },
links: { SUPERVISOR_STATS_URI_FACTORY }
}) => {
const assignmentsArray = assignments.sort(
Expand All @@ -34,7 +33,7 @@ const ResultsTable = ({
<div className={styles.verticalText}>
<div className={styles.verticalTextInner}>
<Link to={SUPERVISOR_STATS_URI_FACTORY(assignment.id)}>
{getLocalizedName(assignment, locale)}
<LocalizedExerciseName entity={assignment} />
</Link>
</div>
</div>
Expand Down Expand Up @@ -79,8 +78,7 @@ ResultsTable.propTypes = {
assignments: PropTypes.array.isRequired,
users: PropTypes.array.isRequired,
submissions: PropTypes.object.isRequired,
links: PropTypes.object,
intl: PropTypes.shape({ locale: PropTypes.string.isRequired }).isRequired
links: PropTypes.object
};

export default injectIntl(withLinks(ResultsTable));
export default withLinks(ResultsTable);
24 changes: 10 additions & 14 deletions src/components/forms/EditAssignmentForm/EditAssignmentForm.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { reduxForm, Field, FieldArray, touch } from 'redux-form';
import { FormattedMessage, injectIntl } from 'react-intl';
import { FormattedMessage } from 'react-intl';
import { Alert, HelpBlock } from 'react-bootstrap';
import isNumeric from 'validator/lib/isNumeric';

Expand All @@ -11,7 +11,7 @@ import LocalizedTextsFormField from '../LocalizedTextsFormField';
import SubmitButton from '../SubmitButton';

import { validateAssignment } from '../../../redux/modules/assignments';
import { getLocalizedName } from '../../../helpers/getLocalizedData';
import LocalizedExerciseName from '../../helpers/LocalizedExerciseName';

const EditAssignmentForm = ({
initialValues: assignment,
Expand All @@ -22,16 +22,15 @@ const EditAssignmentForm = ({
submitSucceeded: hasSucceeded,
asyncValidating,
invalid,
formValues: { firstDeadline, allowSecondDeadline, localizedTexts } = {},
intl: { locale }
formValues: { firstDeadline, allowSecondDeadline, localizedTexts } = {}
}) =>
<div>
<FormBox
title={
<FormattedMessage
id="app.editAssignmentForm.title"
defaultMessage="Edit assignment {name}"
values={{ name: getLocalizedName(assignment, locale) }}
values={{ name: <LocalizedExerciseName entity={assignment} /> }}
/>
}
successful={hasSucceeded}
Expand Down Expand Up @@ -233,8 +232,7 @@ EditAssignmentForm.propTypes = {
PropTypes.string
]),
localizedTexts: PropTypes.array
}),
intl: PropTypes.shape({ locale: PropTypes.string.isRequired }).isRequired
})
};

const isNonNegativeInteger = n =>
Expand Down Expand Up @@ -441,10 +439,8 @@ const asyncValidate = (values, dispatch, { assignment: { id, version } }) =>
.catch(errors => reject(errors))
);

export default injectIntl(
reduxForm({
form: 'editAssignment',
validate,
asyncValidate
})(EditAssignmentForm)
);
export default reduxForm({
form: 'editAssignment',
validate,
asyncValidate
})(EditAssignmentForm);
4 changes: 2 additions & 2 deletions src/components/forms/EditExerciseForm/EditExerciseForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import FormBox from '../../widgets/FormBox';
import SubmitButton from '../SubmitButton';
import Button from '../../widgets/FlatButton';
import LocalizedTextsFormField from '../LocalizedTextsFormField';
import LocalizedExerciseName from '../../helpers/LocalizedExerciseName';
import { validateExercise } from '../../../redux/modules/exercises';
import withLinks from '../../../hoc/withLinks';
import { getLocalizedName } from '../../../helpers/getLocalizedData';

if (canUseDOM) {
require('codemirror/mode/yaml/yaml');
Expand Down Expand Up @@ -59,7 +59,7 @@ const EditExerciseForm = ({
<FormattedMessage
id="app.editExerciseForm.title"
defaultMessage="Edit exercise {name}"
values={{ name: getLocalizedName(exercise, locale) }}
values={{ name: <LocalizedExerciseName entity={exercise} /> }}
/>
}
succeeded={hasSucceeded}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl } from 'react-intl';
import { OverlayTrigger, Tooltip } from 'react-bootstrap';
import Icon from 'react-fontawesome';

import {
getLocalizedName,
getOtherLocalizedNames
} from '../../../helpers/getLocalizedData';

const LocalizedExerciseName = ({ entity, intl: { locale } }) => {
const otherNames = getOtherLocalizedNames(entity, locale);
return (
<span>
{getLocalizedName(entity, locale)}
{otherNames.length > 0 &&
<span>
&nbsp;<OverlayTrigger
placement="right"
overlay={
<Tooltip id={otherNames.map(n => n.name).join(', ')}>
{otherNames.map(name =>
<div key={entity.id + '.nametooltip.' + name.locale}>
<strong>{name.name}</strong>&nbsp;[{name.locale}]
</div>
)}
</Tooltip>
}
>
<Icon name="flag-o" className="text-black" />
</OverlayTrigger>&nbsp;
</span>}
</span>
);
};

LocalizedExerciseName.propTypes = {
entity: PropTypes.object,
intl: PropTypes.shape({ locale: PropTypes.string.isRequired }).isRequired
};

export default injectIntl(LocalizedExerciseName);
1 change: 1 addition & 0 deletions src/components/helpers/LocalizedExerciseName/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default from './LocalizedExerciseName';
7 changes: 7 additions & 0 deletions src/helpers/getLocalizedData.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@ const getLocalizedX = field => (entity, locale) => {

export const getLocalizedName = getLocalizedX('name');
export const getLocalizedDescription = getLocalizedX('description');

export const getOtherLocalizedNames = (entity, locale) => {
const name = getLocalizedName(entity, locale);
return entity.localizedTexts
.filter(text => text.name && text.name !== name)
.map(({ name, locale }) => ({ name, locale }));
};
Loading

0 comments on commit d532675

Please sign in to comment.