Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Localized groups #136

Merged
merged 4 commits into from
Nov 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 LocalizedExerciseName from '../../helpers/LocalizedExerciseName';
import { LocalizedExerciseName } from '../../helpers/LocalizedNames';
import {
EditIcon,
MaybePublicIcon,
Expand Down
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 LocalizedExerciseName from '../../../helpers/LocalizedExerciseName';
import { LocalizedExerciseName } from '../../../helpers/LocalizedNames';
import { MaybeBonusAssignmentIcon } from '../../../icons';

const AssignmentTableRow = ({
Expand Down
2 changes: 1 addition & 1 deletion src/components/Exercises/ExerciseDetail/ExerciseDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import GroupsNameContainer from '../../../containers/GroupsNameContainer';
import styles from './ExerciseDetail.less';
import { MaybeSucceededIcon } from '../../icons';
import { getLocalizedDescription } from '../../../helpers/getLocalizedData';
import LocalizedExerciseName from '../../helpers/LocalizedExerciseName';
import { LocalizedExerciseName } from '../../helpers/LocalizedNames';

const ExerciseDetail = ({
id,
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 LocalizedExerciseName from '../../helpers/LocalizedExerciseName';
import { LocalizedExerciseName } from '../../helpers/LocalizedNames';
import { MaybeLockedExerciseIcon } from '../../icons';

const ExercisesListItem = ({
Expand Down
2 changes: 1 addition & 1 deletion 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 LocalizedExerciseName from '../../helpers/LocalizedExerciseName';
import { LocalizedExerciseName } from '../../helpers/LocalizedNames';

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

Expand Down
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 LocalizedExerciseName from '../../helpers/LocalizedExerciseName';
import { LocalizedExerciseName } from '../../helpers/LocalizedNames';
import { MaybeLockedExerciseIcon } from '../../icons';

const ExercisesSimpleListItem = ({
Expand Down
41 changes: 24 additions & 17 deletions src/components/Groups/AdminsView/AdminsView.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { FormattedMessage, injectIntl } from 'react-intl';
import { Row, Col } from 'react-bootstrap';
import { getFormValues } from 'redux-form';
import { connect } from 'react-redux';

import Box from '../../widgets/Box';
import AddSupervisor from '../AddSupervisor';
import CreateGroupForm from '../../forms/CreateGroupForm'; // @todo replace with it's' container
import EditGroupForm from '../../forms/EditGroupForm';
import { getLocalizedName } from '../../../helpers/getLocalizedData';

const AdminsView = ({ group, addSubgroup }) => (
const AdminsView = ({ group, addSubgroup, formValues, intl: { locale } }) =>
<div>
<Row>
<Col sm={12}>
<h3>
<FormattedMessage
id="app.group.adminsView.title"
defaultMessage="Administrator controls of {groupName}"
values={{ groupName: group.name }}
values={{ groupName: getLocalizedName(group, locale) }}
/>
</h3>
</Col>
Expand All @@ -34,26 +37,30 @@ const AdminsView = ({ group, addSubgroup }) => (
</Box>
</Col>
<Col md={6}>
<CreateGroupForm
title={
<FormattedMessage
id="app.group.adminsView.addSubgroup"
defaultMessage="Add subgroup"
/>
}
<EditGroupForm
onSubmit={addSubgroup}
instanceId={group.instanceId}
initialValues={{ publicStats: true }}
parentGroupId={group.id}
createNew
collapsable
isOpen={false}
formValues={formValues}
/>
</Col>
</Row>
</div>
);
</div>;

AdminsView.propTypes = {
group: PropTypes.object.isRequired,
addSubgroup: PropTypes.func.isRequired
addSubgroup: PropTypes.func.isRequired,
formValues: PropTypes.object,
intl: PropTypes.shape({ locale: PropTypes.string.isRequired }).isRequired
};

export default AdminsView;
export default connect(
state => {
return {
formValues: getFormValues('editGroup')(state)
};
},
dispatch => ({})
)(injectIntl(AdminsView));
28 changes: 22 additions & 6 deletions src/components/Groups/GroupDetail/GroupDetail.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage, FormattedNumber } from 'react-intl';
import { FormattedMessage, FormattedNumber, injectIntl } from 'react-intl';
import { Row, Col, Table } from 'react-bootstrap';
import ReactMarkdown from 'react-remarkable';

import Box from '../../widgets/Box';
import SupervisorsList from '../../Users/SupervisorsList';
import { MaybeSucceededIcon } from '../../icons';
import GroupTree from '../GroupTree';
import {
getLocalizedName,
getLocalizedDescription
} from '../../../helpers/getLocalizedData';

const GroupDetail = ({
group: {
id,
externalId,
name,
localizedTexts,
description,
threshold,
parentGroupId,
Expand All @@ -26,7 +31,8 @@ const GroupDetail = ({
groups,
publicGroups,
supervisors,
isAdmin
isAdmin,
intl: { locale }
}) =>
<div>
<Row>
Expand All @@ -40,7 +46,14 @@ const GroupDetail = ({
defaultMessage="Group description"
/>
}
description={<ReactMarkdown source={description} />}
description={
<ReactMarkdown
source={getLocalizedDescription(
{ description, localizedTexts },
locale
)}
/>
}
type="primary"
collapsable
noPadding
Expand Down Expand Up @@ -123,7 +136,9 @@ const GroupDetail = ({
<FormattedMessage
id="app.groupDetail.supervisors"
defaultMessage="Supervisors of {groupName}"
values={{ groupName: name }}
values={{
groupName: getLocalizedName({ name, localizedTexts }, locale)
}}
/>
}
>
Expand Down Expand Up @@ -157,7 +172,8 @@ GroupDetail.propTypes = {
groups: PropTypes.object.isRequired,
publicGroups: ImmutablePropTypes.map.isRequired,
supervisors: PropTypes.array.isRequired,
isAdmin: PropTypes.bool
isAdmin: PropTypes.bool,
intl: PropTypes.shape({ locale: PropTypes.string.isRequired }).isRequired
};

export default GroupDetail;
export default injectIntl(GroupDetail);
11 changes: 10 additions & 1 deletion src/components/Groups/GroupTree/GroupTree.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Button from '../../widgets/FlatButton';
import { LinkContainer } from 'react-router-bootstrap';
import { TreeView, TreeViewItem } from '../../widgets/TreeView';
import { isReady, getJsData } from '../../../redux/helpers/resourceManager';
import GroupsName from '../GroupsName';

import withLinks from '../../../hoc/withLinks';

Expand Down Expand Up @@ -59,6 +60,7 @@ class GroupTree extends Component {

const {
name,
localizedTexts,
admins,
childGroups: { all: allChildGroups, public: publicChildGroups },
canView
Expand All @@ -68,7 +70,14 @@ class GroupTree extends Component {
<TreeView>
{level !== 0 &&
<TreeViewItem
title={name}
title={
<GroupsName
id={id}
name={name}
localizedTexts={localizedTexts}
noLink
/>
}
level={level}
admins={admins}
isOpen={currentGroupId === id || isOpen}
Expand Down
22 changes: 12 additions & 10 deletions src/components/Groups/GroupsList/GroupsList.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { Table } from 'react-bootstrap';
import ResourceRenderer from '../../helpers/ResourceRenderer';
import Icon from 'react-fontawesome';

import GroupsName from '../GroupsName';
import withLinks from '../../../hoc/withLinks';

const GroupsList = ({
groups = [],
renderButtons = () => null,
links: { GROUP_URI_FACTORY },
...props
}) => (
}) =>
<ResourceRenderer resource={groups.toArray()}>
{(...groups) => (
{(...groups) =>
<Table hover {...props}>
<tbody>
{groups.map(({ id, name }) => (
{groups.map(({ id, name, localizedTexts }) =>
<tr key={id}>
<td className="text-center">
<Icon name="group" />
</td>
<td>
<Link to={GROUP_URI_FACTORY(id)}>{name}</Link>
<GroupsName
id={id}
name={name}
localizedTexts={localizedTexts}
/>
</td>
<td className="text-right">
{renderButtons(id)}
</td>
</tr>
))}
)}
</tbody>
</Table>
)}
</ResourceRenderer>
);
</Table>}
</ResourceRenderer>;

GroupsList.propTypes = {
groups: ImmutablePropTypes.map.isRequired,
Expand Down
25 changes: 17 additions & 8 deletions src/components/Groups/GroupsName/GroupsName.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,29 @@ import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router';
import withLinks from '../../../hoc/withLinks';
import { LocalizedGroupName } from '../../helpers/LocalizedNames';

const GroupsName = ({ id, name, noLink, links: { GROUP_URI_FACTORY } }) => (
const GroupsName = ({
id,
name,
localizedTexts,
noLink,
links: { GROUP_URI_FACTORY }
}) =>
<span>
{noLink ? (
<span>{name}</span>
) : (
<Link to={GROUP_URI_FACTORY(id)}>{name}</Link>
)}
</span>
);
{noLink
? <span>
<LocalizedGroupName entity={{ name, localizedTexts }} />
</span>
: <Link to={GROUP_URI_FACTORY(id)}>
<LocalizedGroupName entity={{ name, localizedTexts }} />
</Link>}
</span>;

GroupsName.propTypes = {
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
localizedTexts: PropTypes.array.isRequired,
noLink: PropTypes.bool,
links: PropTypes.object
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/Groups/ResultsTable/ResultsTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import LoadingResultsTableRow from './LoadingResultsTableRow';
import NoResultsAvailableRow from './NoResultsAvailableRow';
import withLinks from '../../../hoc/withLinks';
import ResourceRenderer from '../../helpers/ResourceRenderer';
import LocalizedExerciseName from '../../helpers/LocalizedExerciseName';
import { LocalizedExerciseName } from '../../helpers/LocalizedNames';
import styles from './ResultsTable.less';

const ResultsTable = ({
Expand Down
21 changes: 11 additions & 10 deletions src/components/Groups/StudentsView/StudentsView.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage } from 'react-intl';
import { FormattedMessage, injectIntl } from 'react-intl';
import { Row, Col } from 'react-bootstrap';

import Box from '../../widgets/Box';
import AssignmentsTable from '../../Assignments/Assignment/AssignmentsTable';
import StudentsListContainer from '../../../containers/StudentsListContainer';
import LeaveJoinGroupButtonContainer
from '../../../containers/LeaveJoinGroupButtonContainer';
import LeaveJoinGroupButtonContainer from '../../../containers/LeaveJoinGroupButtonContainer';
import { getLocalizedName } from '../../../helpers/getLocalizedData';

const StudentsView = ({
group,
statuses = [],
assignments,
isAdmin = false
}) => (
isAdmin = false,
intl: { locale }
}) =>
<div>
<Row>
<Col sm={12}>
<h3>
<FormattedMessage
id="app.group.studentsView.title"
defaultMessage="Student's dashboard for {groupName}"
values={{ groupName: group.name }}
values={{ groupName: getLocalizedName(group, locale) }}
/>
</h3>
</Col>
Expand Down Expand Up @@ -75,14 +76,14 @@ const StudentsView = ({
</Box>
</Col>
</Row>
</div>
);
</div>;

StudentsView.propTypes = {
group: PropTypes.object.isRequired,
assignments: ImmutablePropTypes.list.isRequired,
statuses: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
isAdmin: PropTypes.bool
isAdmin: PropTypes.bool,
intl: PropTypes.shape({ locale: PropTypes.string.isRequired }).isRequired
};

export default StudentsView;
export default injectIntl(StudentsView);
Loading