Skip to content

Commit

Permalink
Merge 7b30c35 into c380276
Browse files Browse the repository at this point in the history
  • Loading branch information
negreirosleo committed Nov 12, 2018
2 parents c380276 + 7b30c35 commit 2da7b3c
Show file tree
Hide file tree
Showing 15 changed files with 400 additions and 8 deletions.
20 changes: 20 additions & 0 deletions app/assets/javascripts/components/Markdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import Parser from 'html-react-parser';
import memoize from 'memoizee';

const Markdown = ({ source }) => {
const descriptionHTML = window.md.makeHtml(source);
source = Parser(descriptionHTML);

if(source){
return (
<div className='Markdown'>{source}</div>
);
}

return null;
}

const MemoizedMarkdown = memoize(Markdown);
MemoizedMarkdown.displayName = 'Markdown';
export default MemoizedMarkdown;
60 changes: 60 additions & 0 deletions app/assets/javascripts/components/jquery_wrappers/Popover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';

export default class Popover extends Component {
constructor(props) {
super(props);

this.saveChildRef = this.saveChildRef.bind(this);
this.saveContentRef = this.saveContentRef.bind(this);
}

componentDidMount() {
const {
delay,
trigger,
title
} = this.props;

$(this.childRef).popover({
delay,
trigger,
title,
html: true,
content: this.contentRef
});
}

componentWillUnmount() {
$(this.childRef).popover('destroy');
}

saveChildRef(ref) {
this.childRef = ref;
}

saveContentRef(ref) {
this.contentRef = ref;
}

render() {
return (
<div>
{ this.props.children({ ref: this.saveChildRef }) }
<div style={{ display: 'none' }}>
{ this.props.renderContent({ ref: this.saveContentRef })}
</div>
</div>
);
}
};

Popover.propTypes = {
title: PropTypes.string.isRequired,
delay: PropTypes.number,
trigger: PropTypes.string
};

Popover.defaultProps = {
delay: 0
};
19 changes: 19 additions & 0 deletions app/assets/javascripts/components/story/StoryDescriptionIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import PropTypes from 'prop-types';

const StoryDescriptionIcon = ({ description }) => {
if (description) {
return (
<span className='Story__description-icon' >
<i className={`mi md-dark md-16 question_answer`}>question_answer</i>
</span>
)
}
return null
};

StoryDescriptionIcon.propTypes = {
description: PropTypes.string
};

export default StoryDescriptionIcon;
38 changes: 34 additions & 4 deletions app/assets/javascripts/components/story/StoryItem.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';
import classname from 'classnames';
import PropTypes from 'prop-types';
import StoryPopover from './StoryPopover';
import StoryDescriptionIcon from './StoryDescriptionIcon'
import {
classIconRule,
iconRule,
Expand Down Expand Up @@ -53,7 +55,7 @@ StateActions.defaultProp = {
};

export const StateButton = ({ action }) => (
<button type="button" className={`Story__btn Story__btn--${action}`}>{action}</button>
<button type="button" className={`Story__btn Story__btn--${action}`}>{ I18n.translate('story.events.' + action) }</button>
);

StateButton.propTypes = {
Expand Down Expand Up @@ -147,10 +149,35 @@ const classNameStory = (storyType, estimate) => classname (
}
);

const StoryItem = ({ title, storyType, estimate, labels, state, ownedByInitials, ownedByName }) => (
const StoryItem = ({
title,
storyType,
estimate,
labels,
state,
description,
ownedByInitials,
ownedByName,
requestedByName,
createdAt,
notes
}) => (
<div className={classNameStory(storyType, estimate)}>
<StoryIcon storyType={storyType} />
<StoryEstimate estimate={estimate} />
<StoryPopover
description={description}
notes={notes}
createdAt={createdAt}
title={title}
storyType={storyType}
requestedByName={requestedByName}
>
<div className={'Story__icons-block'}>
<StoryIcon storyType={storyType} />
<StoryEstimate estimate={estimate} />
<StoryDescriptionIcon description={description}/>
</div>
</StoryPopover>

<StoryInfo title={title} labels={labels} ownedByInitials={ownedByInitials} ownedByName={ownedByName} />
<StateActions storyType={storyType} estimate={estimate} state={state}/>
</div>
Expand All @@ -165,6 +192,9 @@ StoryItem.propTypes = {
state: PropTypes.string.isRequired,
ownedByInitials: PropTypes.string,
ownedByName: PropTypes.string,
requestedByName: PropTypes.string,
createdAt: PropTypes.string,
notes: PropTypes.array,
};

StoryItem.defaultProps = {
Expand Down
85 changes: 85 additions & 0 deletions app/assets/javascripts/components/story/StoryPopover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import Markdown from '../Markdown';
import Popover from 'components/jquery_wrappers/Popover.js';

export const StoryPopoverContent = ({ description, notes, createdAt, storyType, requestedByName }) => (
<div>
<div className='popover__content__subtitle'>
{
I18n.translate('requested by user on date', {
user: requestedByName,
date: moment(createdAt).format('DD MM YYYY, h:mm a')
})
}

<div className='text-right'>
{ I18n.translate('story.type.' + storyType) }
</div>
</div>

{
Boolean(description) && (
<div>
<h1 className='popover__content__title'>{ I18n.translate('description') }</h1>
<div className='markdown-wrapper'>
<Markdown source={description}/>
</div>
</div>
)}

{
Boolean(notes.length) && (
<div>
<h1 className='popover__content__title'>{ I18n.translate('notes') }</h1>
{ notes.map((note) =>
<div className='markdown-wrapper' key={note.id}>
<Markdown source={note.note}/>
<div className='markdown-wrapper__text-right' data-test-id={note.id}>
{ note.userName + " - " + note.createdAt }
</div>
</div>
)}
</div>
)}
</div>
)

const StoryPopover = ({ description, notes, createdAt, title, storyType, requestedByName , children }) => (
<Popover
delay={200}
trigger="hover"
title={title}
renderContent={({ ref }) => (
<div className='popover__content' ref={ref}>
<StoryPopoverContent
description={description}
notes={notes}
createdAt={createdAt}
storyType={storyType}
requestedByName={requestedByName}
/>
</div>
)}
>
{
({ ref }) => (
<bold ref={ref}>
{ children }
</bold>
)
}
</Popover>
);

StoryPopover.propTypes = {
title: PropTypes.string.isRequired,
description: PropTypes.string,
storyType: PropTypes.string.isRequired,
requestedByName: PropTypes.string,
createdAt: PropTypes.string,
notes: PropTypes.array,
};

export default StoryPopover;
9 changes: 8 additions & 1 deletion app/assets/javascripts/models/beta/projectBoard.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,12 @@ import camelCase from 'camelcase-object-deep';
export function get(projectId) {
return axios
.get(`/beta/project_boards/${projectId}`)
.then(({ data }) => camelCase(data, {deep: true}));
.then(({ data }) => camelCase(data, {deep: true}))
.then(( projectBoard ) => ({
...projectBoard,
stories: projectBoard.stories.map((story) => ({
...story,
notes: story.notes.map((note) => (note.note))
}))
}));
}
38 changes: 38 additions & 0 deletions app/assets/stylesheets/new_board/_screen.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
.full-heigth {
height:100%;
}

.markdown-wrapper{
background: $white;
border-left: 4px solid $lightgrey-17;
margin-top: 5px;
padding: 10px;

&__text-rigth{
float: right;
vertical-align: top;
color: $darkgrey-8;
font-size: 0.75em;
}
}

.popover {
&__content {
padding: 5px 5px 0 5px;
word-wrap: break-word;

&__title {
font-size: 13px;
}

&__subtitle {
color: $darkgrey-8;
font-size: 0.85em;
padding: 0 2px;
margin: 5px 0 5px;

.text-right{
margin-left: 10px;
float: right;
vertical-align: top;
}
}
}
}
23 changes: 21 additions & 2 deletions app/assets/stylesheets/new_board/_story.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
border-top: 1px solid $story-border-top-color;
min-height: 37px;
cursor: move;
align-items: center;
font-size: 12px;

&:hover {
Expand All @@ -32,12 +33,26 @@
}
}

&__description-icon {
display: flex;
justify-content: start;
align-items: center;
margin-left: 5px;
}

&__info {
flex: 1;
display: flex;
justify-content: space-between;
align-items: center;
margin-left: 15px;
align-self: flex-start;
margin-left: 10px;
}

&__icons-block{
display: flex;
justify-content: flex-start;
width: 60px;
}

&__icon {
Expand All @@ -48,7 +63,9 @@
}

&__title {
word-break: break-all;
flex: 1;
margin-right: 10px;

abbr {
border: none;
Expand All @@ -61,6 +78,7 @@
}

&__estimated {
padding: 2px 3px;
display: inline-flex;
align-items: center;
justify-content: center;
Expand All @@ -74,6 +92,7 @@
}

&__estimate {
padding: 2px 3px;
display: inline-flex;
align-items: center;
justify-content: center;
Expand Down Expand Up @@ -130,6 +149,6 @@
&__initials {
color: green;
font-weight: bold;
margin-left: 0.2em;
margin-left: 1em;
}
}
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ en:
velocity: "Velocity"
volatility: "Volatility"
standard_deviation: "Standard Deviation"
description: "Description"
notes: "Notes"
tasks: "Tasks"
close: "Close"
Expand Down
1 change: 1 addition & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ es:
cancel: "Cancelar"
add: "Agregar"
remove: "Eliminar"
description: "Descripción"
add user: "Agregar usuario"
add new member: "Agregar un nuevo miembro"
all users: "Todos los usuarios"
Expand Down

0 comments on commit 2da7b3c

Please sign in to comment.