Merge pull request #923 from okriuchykhin/ok_SCI_1869

Add project/task path with tooltips to activities [SCI-1869]
This commit is contained in:
okriuchykhin 2018-01-04 16:44:35 +01:00 committed by GitHub
commit 4cdbecc3bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 12 deletions

View file

@ -1,7 +1,10 @@
// @flow
import React from "react";
import PropTypes from "prop-types";
import Moment from "react-moment";
import { Tooltip, OverlayTrigger } from "react-bootstrap";
import styled from "styled-components";
import { FormattedMessage } from "react-intl";
import {
WHITE_COLOR,
@ -9,6 +12,8 @@ import {
BORDER_GRAY_COLOR
} from "../../../config/constants/colors";
import { NAME_TRUNCATION_LENGTH } from "../../../config/constants/numeric";
const StyledLi = styled.li`
border-radius: .25em;
margin-bottom: 1em;
@ -33,6 +38,39 @@ const TextSpan = styled.span`
padding: 3px 10px;
text-align: justify;
`
function truncatedTooltip(id, text) {
return (
<OverlayTrigger overlay={(
<Tooltip id={id}>
{text}
</Tooltip>
)} placement="bottom">
<span>
{text.substring(0, NAME_TRUNCATION_LENGTH)}...
</span>
</OverlayTrigger>
);
}
function taskPath(activity) {
return (
<span>&nbsp;
[&nbsp;<FormattedMessage id="general.project" />:&nbsp;
{activity.project.length > NAME_TRUNCATION_LENGTH ? (
truncatedTooltip('activity_modal.long_project_tooltip', activity.project)
):(
<span>{activity.project}</span>
)},&nbsp;
<FormattedMessage id="general.task" />:&nbsp;
{activity.task.length > NAME_TRUNCATION_LENGTH ? (
truncatedTooltip('activity_modal.long_task_tooltip', activity.task)
):(
<span>{activity.task}</span>
)}&nbsp;]
</span>
);
}
const ActivityElement = ({ activity }) =>
<StyledLi>
@ -41,14 +79,10 @@ const ActivityElement = ({ activity }) =>
{activity.created_at}
</Moment>
</TimeSpan>
<TextSpan dangerouslySetInnerHTML={{ __html: activity.message }} />
<TextSpan>
<span dangerouslySetInnerHTML={{ __html: activity.message }} />
{activity.task && taskPath(activity)}
</TextSpan>
</StyledLi>;
ActivityElement.propTypes = {
activity: PropTypes.shape({
message: PropTypes.string.isRequired,
created_at: PropTypes.string.isRequired
}).isRequired
};
export default ActivityElement;

View file

@ -6,4 +6,5 @@ export const PASSWORD_MAX_LENGTH = 72;
export const NAME_MAX_LENGTH = 255;
export const TEXT_MAX_LENGTH = 10000;
export const INVITE_USERS_LIMIT = 20;
export const AVATAR_MAX_SIZE_MB = 0.2;
export const AVATAR_MAX_SIZE_MB = 0.2;
export const NAME_TRUNCATION_LENGTH = 25;

View file

@ -9,7 +9,9 @@ export default {
upload: "Upload",
about_scinote: "About sciNote",
core_version: "sciNote core version",
addon_versions: "Addon versions"
addon_versions: "Addon versions",
project: "Project",
task: "Task"
},
page_title: {
root: "SciNote",

View file

@ -8,3 +8,5 @@ export function getActivities(
const path = `${ACTIVITIES_PATH}?from=${lastId}`;
return axiosInstance.get(path).then(({ data }) => data.global_activities);
}
export default 'getActivities';

View file

@ -3,6 +3,10 @@ json.global_activities do
json.activities activities do |activity|
json.id activity.id
json.message activity.message
if activity.my_module
json.project activity.my_module.experiment.project.name
json.task activity.my_module.name
end
json.created_at activity.created_at
end
end

4
flow-typed/types.js vendored
View file

@ -33,7 +33,9 @@ export type ValidationErrors = string | Array<string> | Array<ValidationError>;
export type Activity = {
id: number,
message: string,
created_at: string
created_at: string,
project?: string,
task?: string
};
export type Notification = {