mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-29 00:34:35 +02:00
Ivan - Frontend - Add ticket actions styling [skip ci]
This commit is contained in:
parent
a42e00ad9b
commit
831c6ed64e
@ -12,7 +12,7 @@ const codeLanguages = {
|
|||||||
'Indian': 'in'
|
'Indian': 'in'
|
||||||
};
|
};
|
||||||
const languages = Object.keys(codeLanguages);
|
const languages = Object.keys(codeLanguages);
|
||||||
const languageCodes = Object.values(codeLanguages).concat(['en']);
|
const languageCodes = languages.map((key) => { return codeLanguages[key]; }).concat(['en']);
|
||||||
|
|
||||||
class LanguageSelector extends React.Component {
|
class LanguageSelector extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
228
client/src/app-components/ticket-action.js
Normal file
228
client/src/app-components/ticket-action.js
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import i18n from 'lib-app/i18n';
|
||||||
|
import Icon from 'core-components/icon';
|
||||||
|
|
||||||
|
class TicketAction extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
type: React.PropTypes.oneOf([
|
||||||
|
'COMMENT',
|
||||||
|
'ASSIGN',
|
||||||
|
'UN_ASSIGN',
|
||||||
|
'CLOSE',
|
||||||
|
'RE_OPEN',
|
||||||
|
'DEPARTMENT_CHANGED',
|
||||||
|
'PRIORITY_CHANGED'
|
||||||
|
]),
|
||||||
|
author: React.PropTypes.object,
|
||||||
|
content: React.PropTypes.string,
|
||||||
|
date: React.PropTypes.number
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let iconNode = null;
|
||||||
|
|
||||||
|
if (this.props.type === 'COMMENT' && this.props.author && this.props.author.staff) {
|
||||||
|
iconNode = this.renderStaffPic();
|
||||||
|
} else {
|
||||||
|
iconNode = this.renderIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={this.getClass()}>
|
||||||
|
<span className="ticket-action__connector" />
|
||||||
|
<div className="col-md-1">
|
||||||
|
{iconNode}
|
||||||
|
</div>
|
||||||
|
<div className="col-md-11">
|
||||||
|
{this.renderActionDescription()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStaffPic() {
|
||||||
|
return (
|
||||||
|
<div className="ticket-action__staff-pic">
|
||||||
|
<img src={this.props.author.profilePic} className="ticket-action__staff-pic-img" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderIcon() {
|
||||||
|
return (
|
||||||
|
<div className="ticket-action__icon">
|
||||||
|
<Icon {...this.getIconProps()}/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderActionDescription() {
|
||||||
|
const renders = {
|
||||||
|
'COMMENT': this.renderComment.bind(this),
|
||||||
|
'ASSIGN': this.renderAssignment.bind(this),
|
||||||
|
'UN_ASSIGN': this.renderUnAssignment.bind(this),
|
||||||
|
'CLOSE': this.renderClosed.bind(this),
|
||||||
|
'RE_OPEN': this.renderReOpened.bind(this),
|
||||||
|
'DEPARTMENT_CHANGED': this.renderDepartmentChange.bind(this),
|
||||||
|
'PRIORITY_CHANGED': this.renderPriorityChange.bind(this)
|
||||||
|
};
|
||||||
|
|
||||||
|
return renders[this.props.type]();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderComment() {
|
||||||
|
return (
|
||||||
|
<div className="ticket-action__comment">
|
||||||
|
<span className="ticket-action__comment-pointer" />
|
||||||
|
<div className="ticket-action__comment-author">
|
||||||
|
<span className="ticket-action__comment-author-name">{this.props.author.name}</span>
|
||||||
|
<span className="ticket-action__comment-author-type">({i18n((this.props.author.staff) ? 'STAFF' : 'CUSTOMER')})</span>
|
||||||
|
</div>
|
||||||
|
<div className="ticket-action__comment-date">{this.props.date}</div>
|
||||||
|
<div className="ticket-action__comment-content" dangerouslySetInnerHTML={{__html: this.props.content}}></div>
|
||||||
|
{this.renderFileRow(this.props.file)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderAssignment() {
|
||||||
|
return (
|
||||||
|
<div className="ticket-action__circled">
|
||||||
|
<span className="ticket-action__circled-author">{this.props.author.name}</span>
|
||||||
|
<span className="ticket-action__circled-text"> assigned this ticket</span>
|
||||||
|
<span className="ticket-action__circled-date"> on {this.props.date}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderUnAssignment() {
|
||||||
|
return (
|
||||||
|
<div className="ticket-action__circled">
|
||||||
|
<span className="ticket-action__circled-author">{this.props.author.name}</span>
|
||||||
|
<span className="ticket-action__circled-text"> unassigned this ticket</span>
|
||||||
|
<span className="ticket-action__circled-date"> on {this.props.date}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderClosed() {
|
||||||
|
return (
|
||||||
|
<div className="ticket-action__circled">
|
||||||
|
<span className="ticket-action__circled-author">{this.props.author.name}</span>
|
||||||
|
<span className="ticket-action__circled-text"> closed this ticket</span>
|
||||||
|
<span className="ticket-action__circled-date"> on {this.props.date}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderReOpened() {
|
||||||
|
return (
|
||||||
|
<div className="ticket-action__circled">
|
||||||
|
<span className="ticket-action__circled-author">{this.props.author.name}</span>
|
||||||
|
<span className="ticket-action__circled-text"> reopen this ticket</span>
|
||||||
|
<span className="ticket-action__circled-date"> on {this.props.date}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderDepartmentChange() {
|
||||||
|
return (
|
||||||
|
<div className="ticket-action__circled">
|
||||||
|
<span className="ticket-action__circled-author">{this.props.author.name}</span>
|
||||||
|
<span className="ticket-action__circled-text"> change department to</span>
|
||||||
|
<span className="ticket-action__circled-indication"> {this.props.content}</span>
|
||||||
|
<span className="ticket-action__circled-date"> on {this.props.date}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderPriorityChange() {
|
||||||
|
return (
|
||||||
|
<div className="ticket-action__circled">
|
||||||
|
<span className="ticket-action__circled-author">{this.props.author.name}</span>
|
||||||
|
<span className="ticket-action__circled-text"> change priority to</span>
|
||||||
|
<span className="ticket-action__circled-indication"> {this.props.content}</span>
|
||||||
|
<span className="ticket-action__circled-date"> on {this.props.date}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderFileRow(file) {
|
||||||
|
let node = null;
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
node = <span> {this.getFileLink(file)} <Icon name="paperclip" /> </span>;
|
||||||
|
} else {
|
||||||
|
node = i18n('NO_ATTACHMENT');
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="ticket-viewer__file">
|
||||||
|
{node}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
getClass() {
|
||||||
|
const circledTypes = {
|
||||||
|
'COMMENT': false,
|
||||||
|
'ASSIGN': true,
|
||||||
|
'UN_ASSIGN': true,
|
||||||
|
'CLOSE': true,
|
||||||
|
'RE_OPEN': true,
|
||||||
|
'DEPARTMENT_CHANGED': true,
|
||||||
|
'PRIORITY_CHANGED': true
|
||||||
|
};
|
||||||
|
const classes = {
|
||||||
|
'row': true,
|
||||||
|
'ticket-action': true,
|
||||||
|
'ticket-action_staff': this.props.author && this.props.author.staff,
|
||||||
|
'ticket-action_circled': circledTypes[this.props.type],
|
||||||
|
'ticket-action_unassignment': this.props.type === 'UN_ASSIGN',
|
||||||
|
'ticket-action_close': this.props.type === 'CLOSE',
|
||||||
|
'ticket-action_reopen': this.props.type === 'RE_OPEN',
|
||||||
|
'ticket-action_department': this.props.type === 'DEPARTMENT_CHANGED',
|
||||||
|
'ticket-action_priority': this.props.type === 'PRIORITY_CHANGED'
|
||||||
|
};
|
||||||
|
|
||||||
|
return classNames(classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
getIconProps() {
|
||||||
|
const iconName = {
|
||||||
|
'COMMENT': 'comment-o',
|
||||||
|
'ASSIGN': 'user',
|
||||||
|
'UN_ASSIGN': 'user-times',
|
||||||
|
'CLOSE': 'lock',
|
||||||
|
'RE_OPEN': 'unlock-alt',
|
||||||
|
'DEPARTMENT_CHANGED': 'exchange',
|
||||||
|
'PRIORITY_CHANGED': 'exclamation'
|
||||||
|
};
|
||||||
|
const iconSize = {
|
||||||
|
'COMMENT': '2x',
|
||||||
|
'ASSIGN': 'lg',
|
||||||
|
'UN_ASSIGN': 'lg',
|
||||||
|
'CLOSE': 'lg',
|
||||||
|
'RE_OPEN': 'lg',
|
||||||
|
'DEPARTMENT_CHANGED': 'lg',
|
||||||
|
'PRIORITY_CHANGED': 'lg'
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: iconName[this.props.type],
|
||||||
|
size: iconSize[this.props.type]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getFileLink(filePath = '') {
|
||||||
|
const fileName = filePath.replace(/^.*[\\\/]/, '');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a href={filePath} target="_blank">{fileName}</a>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TicketAction;
|
170
client/src/app-components/ticket-action.scss
Normal file
170
client/src/app-components/ticket-action.scss
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
@import "../scss/vars";
|
||||||
|
|
||||||
|
.ticket-action {
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: left;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&__connector {
|
||||||
|
position: absolute;
|
||||||
|
background-color: $light-grey;
|
||||||
|
width: 3px;
|
||||||
|
height: 100%;
|
||||||
|
top: 38px;
|
||||||
|
left: 33px;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__staff-pic {
|
||||||
|
vertical-align: top;
|
||||||
|
background-color: $secondary-blue;
|
||||||
|
color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
border: 2px solid $light-grey;
|
||||||
|
|
||||||
|
&-img {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
vertical-align: top;
|
||||||
|
background-color: $secondary-blue;
|
||||||
|
color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__comment {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&-pointer {
|
||||||
|
right: 100%;
|
||||||
|
border: solid transparent;
|
||||||
|
position: absolute;
|
||||||
|
border-right-color: $light-grey;
|
||||||
|
border-width: 13px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-author {
|
||||||
|
text-align: left;
|
||||||
|
float: left;
|
||||||
|
position: relative;
|
||||||
|
padding: 12px;
|
||||||
|
color: $primary-black;
|
||||||
|
|
||||||
|
&-type {
|
||||||
|
font-size: 10px;
|
||||||
|
padding-left: 10px;
|
||||||
|
color: $secondary-blue;
|
||||||
|
font-variant: small-caps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-date {
|
||||||
|
text-align: right;
|
||||||
|
border: 2px solid $light-grey;
|
||||||
|
border-bottom: none;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: $light-grey;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&-content {
|
||||||
|
background-color: white;
|
||||||
|
border: 2px solid $very-light-grey;
|
||||||
|
border-top: none;
|
||||||
|
padding: 20px 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_staff {
|
||||||
|
.ticket-action__icon {
|
||||||
|
background-color: $primary-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-action__comment-author-type {
|
||||||
|
color: $primary-blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_circled {
|
||||||
|
margin-top: 35px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
.ticket-action__connector {
|
||||||
|
top: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-action__icon {
|
||||||
|
background-color: white;
|
||||||
|
color: $primary-black;
|
||||||
|
border: 3px solid $light-grey;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-top: 4px;
|
||||||
|
margin-left: 2px;
|
||||||
|
margin-top: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-action__circled {
|
||||||
|
color: $primary-black;
|
||||||
|
font-size: $font-size--sm;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-action__circled-author {
|
||||||
|
color: $secondary-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-action__circled-indication {
|
||||||
|
color: $primary-green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_unassignment {
|
||||||
|
.ticket-action__icon {
|
||||||
|
padding-left: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_close {
|
||||||
|
.ticket-action__icon {
|
||||||
|
padding-left: 9px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_reopen {
|
||||||
|
.ticket-action__icon {
|
||||||
|
padding-left: 9px;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_department {
|
||||||
|
.ticket-action__icon {
|
||||||
|
padding-left: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&_priority {
|
||||||
|
.ticket-action__icon {
|
||||||
|
padding-left: 11px;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@ import API from 'lib-app/api-call';
|
|||||||
import store from 'app/store';
|
import store from 'app/store';
|
||||||
import SessionActions from 'actions/session-actions';
|
import SessionActions from 'actions/session-actions';
|
||||||
|
|
||||||
import TicketAction from 'app/main/dashboard/dashboard-ticket/ticket-action';
|
import TicketAction from 'app-components/ticket-action';
|
||||||
import Form from 'core-components/form';
|
import Form from 'core-components/form';
|
||||||
import FormField from 'core-components/form-field';
|
import FormField from 'core-components/form-field';
|
||||||
import SubmitButton from 'core-components/submit-button';
|
import SubmitButton from 'core-components/submit-button';
|
||||||
@ -34,11 +34,13 @@ class TicketViewer extends React.Component {
|
|||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const ticket = this.props.ticket;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ticket-viewer">
|
<div className="ticket-viewer">
|
||||||
<div className="ticket-viewer__header row">
|
<div className="ticket-viewer__header row">
|
||||||
<span className="ticket-viewer__number">#{this.props.ticket.ticketNumber}</span>
|
<span className="ticket-viewer__number">#{ticket.ticketNumber}</span>
|
||||||
<span className="ticket-viewer__title">{this.props.ticket.title}</span>
|
<span className="ticket-viewer__title">{ticket.title}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="ticket-viewer__info-row-header row">
|
<div className="ticket-viewer__info-row-header row">
|
||||||
<div className="ticket-viewer__department col-md-4">{i18n('DEPARTMENT')}</div>
|
<div className="ticket-viewer__department col-md-4">{i18n('DEPARTMENT')}</div>
|
||||||
@ -46,15 +48,15 @@ class TicketViewer extends React.Component {
|
|||||||
<div className="ticket-viewer__date col-md-4">{i18n('DATE')}</div>
|
<div className="ticket-viewer__date col-md-4">{i18n('DATE')}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="ticket-viewer__info-row-values row">
|
<div className="ticket-viewer__info-row-values row">
|
||||||
<div className="ticket-viewer__department col-md-4">{this.props.ticket.department.name}</div>
|
<div className="ticket-viewer__department col-md-4">{ticket.department.name}</div>
|
||||||
<div className="ticket-viewer__author col-md-4">{this.props.ticket.author.name}</div>
|
<div className="ticket-viewer__author col-md-4">{ticket.author.name}</div>
|
||||||
<div className="ticket-viewer__date col-md-4">{this.props.ticket.date}</div>
|
<div className="ticket-viewer__date col-md-4">{ticket.date}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="ticket-viewer__content">
|
<div className="ticket-viewer__content">
|
||||||
<TicketAction type="comment" config={this.props.ticket} />
|
<TicketAction type="COMMENT" author={ticket.author} content={ticket.content} date={ticket.date} file={ticket.file}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="ticket-viewer__comments">
|
<div className="ticket-viewer__comments">
|
||||||
{this.props.ticket.comments.map(this.renderComment.bind(this))}
|
{ticket.actions && ticket.actions.map(this.renderAction.bind(this))}
|
||||||
</div>
|
</div>
|
||||||
<div className="ticket-viewer__response">
|
<div className="ticket-viewer__response">
|
||||||
<div className="ticket-viewer__response-title row">{i18n('RESPOND')}</div>
|
<div className="ticket-viewer__response-title row">{i18n('RESPOND')}</div>
|
||||||
@ -69,9 +71,9 @@ class TicketViewer extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderComment(comment, index) {
|
renderAction(action, index) {
|
||||||
return (
|
return (
|
||||||
<TicketAction type="comment" config={comment} key={index} />
|
<TicketAction {...action} key={index} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
@import "../../../../scss/vars";
|
@import "../scss/vars";
|
||||||
|
|
||||||
.ticket-viewer {
|
.ticket-viewer {
|
||||||
&__header {
|
&__header {
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
|
|
||||||
import TicketViewer from 'app/main/dashboard/dashboard-ticket/ticket-viewer';
|
import TicketViewer from 'app-components/ticket-viewer';
|
||||||
|
|
||||||
class DashboardTicketPage extends React.Component {
|
class DashboardTicketPage extends React.Component {
|
||||||
|
|
||||||
|
@ -1,105 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
|
|
||||||
import i18n from 'lib-app/i18n';
|
|
||||||
import Icon from 'core-components/icon';
|
|
||||||
|
|
||||||
class TicketAction extends React.Component {
|
|
||||||
static propTypes = {
|
|
||||||
type: React.PropTypes.oneOf(['comment', 'assign']),
|
|
||||||
config: React.PropTypes.object
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
type: 'comment'
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className={this.getClass()}>
|
|
||||||
<span className="ticket-action__connector" />
|
|
||||||
<div className="col-md-1">
|
|
||||||
<div className="ticket-action__icon">
|
|
||||||
<Icon name="comment-o" size="2x" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-11">
|
|
||||||
{this.renderActionDescription()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderActionDescription() {
|
|
||||||
const renders = {
|
|
||||||
'comment': this.renderComment.bind(this),
|
|
||||||
'assign': this.renderAssignment.bind(this)
|
|
||||||
};
|
|
||||||
|
|
||||||
return renders[this.props.type]();
|
|
||||||
}
|
|
||||||
|
|
||||||
renderComment() {
|
|
||||||
const {config} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="ticket-action__comment">
|
|
||||||
<span className="ticket-action__comment-pointer" />
|
|
||||||
<div className="ticket-action__comment-author">
|
|
||||||
<span className="ticket-action__comment-author-name">{config.author.name}</span>
|
|
||||||
<span className="ticket-action__comment-author-type">({i18n((config.author.staff) ? 'STAFF' : 'CUSTOMER')})</span>
|
|
||||||
</div>
|
|
||||||
<div className="ticket-action__comment-date">{config.date}</div>
|
|
||||||
<div className="ticket-action__comment-content" dangerouslySetInnerHTML={{__html: config.content}}></div>
|
|
||||||
{this.renderFileRow(config.file)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderAssignment() {
|
|
||||||
// TODO: Add actions architecture instead of just comments
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="ticket-action__assignment">
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
renderFileRow(file) {
|
|
||||||
let node = null;
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
node = <span> {this.getFileLink(file)} <Icon name="paperclip" /> </span>;
|
|
||||||
} else {
|
|
||||||
node = i18n('NO_ATTACHMENT');
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="ticket-viewer__file">
|
|
||||||
{node}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
getClass() {
|
|
||||||
const {config} = this.props;
|
|
||||||
|
|
||||||
let classes = {
|
|
||||||
'row': true,
|
|
||||||
'ticket-action': true,
|
|
||||||
'ticket-action_staff': config.author && config.author.staff
|
|
||||||
};
|
|
||||||
|
|
||||||
return classNames(classes);
|
|
||||||
}
|
|
||||||
|
|
||||||
getFileLink(filePath = '') {
|
|
||||||
const fileName = filePath.replace(/^.*[\\\/]/, '');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<a href={filePath} target="_blank">{fileName}</a>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TicketAction;
|
|
@ -1,83 +0,0 @@
|
|||||||
@import "../../../../scss/vars";
|
|
||||||
|
|
||||||
.ticket-action {
|
|
||||||
margin-top: 20px;
|
|
||||||
text-align: left;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&__connector {
|
|
||||||
position: absolute;
|
|
||||||
background-color: $light-grey;
|
|
||||||
width: 3px;
|
|
||||||
height: 100%;
|
|
||||||
top: 38px;
|
|
||||||
left: 33px;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon {
|
|
||||||
vertical-align: top;
|
|
||||||
background-color: $secondary-blue;
|
|
||||||
color: white;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 42px;
|
|
||||||
height: 42px;
|
|
||||||
padding-left: 8px;
|
|
||||||
padding-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__comment {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&-pointer {
|
|
||||||
right: 100%;
|
|
||||||
border: solid transparent;
|
|
||||||
position: absolute;
|
|
||||||
border-right-color: $light-grey;
|
|
||||||
border-width: 13px;
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-author {
|
|
||||||
text-align: left;
|
|
||||||
float: left;
|
|
||||||
position: relative;
|
|
||||||
padding: 12px;
|
|
||||||
color: $primary-black;
|
|
||||||
|
|
||||||
&-type {
|
|
||||||
font-size: 10px;
|
|
||||||
padding-left: 10px;
|
|
||||||
color: $secondary-blue;
|
|
||||||
font-variant: small-caps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-date {
|
|
||||||
text-align: right;
|
|
||||||
border: 2px solid $light-grey;
|
|
||||||
border-bottom: none;
|
|
||||||
padding: 12px;
|
|
||||||
background-color: $light-grey;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
&-content {
|
|
||||||
background-color: white;
|
|
||||||
border: 2px solid $very-light-grey;
|
|
||||||
border-top: none;
|
|
||||||
padding: 20px 10px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&_staff {
|
|
||||||
.ticket-action__icon {
|
|
||||||
background-color: $primary-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ticket-action__comment-author-type {
|
|
||||||
color: $primary-blue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -159,28 +159,98 @@ module.exports = [
|
|||||||
name: 'Steve Jobs',
|
name: 'Steve Jobs',
|
||||||
email: 'steve@jobs.com'
|
email: 'steve@jobs.com'
|
||||||
},
|
},
|
||||||
comments: [
|
actions: [
|
||||||
{
|
{
|
||||||
content: 'Do you have apache installed? It generally happens if you dont have apache.',
|
type: 'ASSIGN',
|
||||||
|
date: 20150409,
|
||||||
author: {
|
author: {
|
||||||
id: 15,
|
name: 'Emilia Clarke',
|
||||||
name: 'Steve Jobs',
|
|
||||||
email: 'jobs@steve.com',
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
staff: true
|
staff: true
|
||||||
},
|
}
|
||||||
date: '12 Dec 2016',
|
|
||||||
file: ''
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
type: 'COMMENT',
|
||||||
|
date: 20150409,
|
||||||
|
content: 'Do you have apache installed? It generally happens if you dont have apache.',
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'UN_ASSIGN',
|
||||||
|
date: 20150410,
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'DEPARTMENT_CHANGED',
|
||||||
|
date: 20150411,
|
||||||
|
content: 'System support',
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'COMMENT',
|
||||||
|
date: 20150412,
|
||||||
content: 'I have already installed apache, but the problem persists',
|
content: 'I have already installed apache, but the problem persists',
|
||||||
author: {
|
author: {
|
||||||
id: 12,
|
|
||||||
name: 'Haskell Curry',
|
name: 'Haskell Curry',
|
||||||
steve: 'haskell@lambda.com',
|
steve: 'haskell@lambda.com',
|
||||||
staff: false
|
staff: false
|
||||||
},
|
}
|
||||||
date: '12 Dec 2016',
|
},
|
||||||
file: ''
|
{
|
||||||
|
type: 'PRIORITY_CHANGED',
|
||||||
|
date: 20150413,
|
||||||
|
content: 'MEDIUM',
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'COMMENT',
|
||||||
|
date: 20150511,
|
||||||
|
content: 'Thanks!, I soved it by myself',
|
||||||
|
author: {
|
||||||
|
name: 'Haskell Curry',
|
||||||
|
steve: 'haskell@lambda.com',
|
||||||
|
staff: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'CLOSE',
|
||||||
|
date: 20150513,
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'RE_OPEN',
|
||||||
|
date: 20151018,
|
||||||
|
author: {
|
||||||
|
name: 'Haskell Curry',
|
||||||
|
email: 'haskell@lambda.com',
|
||||||
|
staff: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -205,34 +275,110 @@ module.exports = [
|
|||||||
owner: {
|
owner: {
|
||||||
name: 'Steve Jobs'
|
name: 'Steve Jobs'
|
||||||
},
|
},
|
||||||
comments: [
|
actions: [
|
||||||
{
|
{
|
||||||
content: 'Do you have apache installed? It generally happens if you dont have apache.',
|
type: 'ASSIGN',
|
||||||
|
date: 20150409,
|
||||||
author: {
|
author: {
|
||||||
name: 'Steve Jobs',
|
name: 'Emilia Clarke',
|
||||||
email: 'jobs@steve.com',
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
staff: true
|
staff: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
type: 'COMMENT',
|
||||||
|
date: 20150409,
|
||||||
|
content: 'Do you have apache installed? It generally happens if you dont have apache.',
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'UN_ASSIGN',
|
||||||
|
date: 20150410,
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'DEPARTMENT_CHANGED',
|
||||||
|
date: 20150411,
|
||||||
|
content: 'System support',
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'COMMENT',
|
||||||
|
date: 20150412,
|
||||||
content: 'I have already installed apache, but the problem persists',
|
content: 'I have already installed apache, but the problem persists',
|
||||||
author: {
|
author: {
|
||||||
name: 'Haskell Curry',
|
name: 'Haskell Curry',
|
||||||
steve: 'haskell@lambda.com',
|
steve: 'haskell@lambda.com',
|
||||||
staff: false
|
staff: false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'PRIORITY_CHANGED',
|
||||||
|
date: 20150413,
|
||||||
|
content: 'MEDIUM',
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'COMMENT',
|
||||||
|
date: 20150511,
|
||||||
|
content: 'Thanks!, I soved it by myself',
|
||||||
|
author: {
|
||||||
|
name: 'Haskell Curry',
|
||||||
|
steve: 'haskell@lambda.com',
|
||||||
|
staff: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'CLOSE',
|
||||||
|
date: 20150513,
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'RE_OPEN',
|
||||||
|
date: 20151018,
|
||||||
|
author: {
|
||||||
|
name: 'Haskell Curry',
|
||||||
|
email: 'haskell@lambda.com',
|
||||||
|
staff: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ticketNumber: '878552',
|
ticketNumber: '118551',
|
||||||
title: 'Lorem ipsum door',
|
title: 'Lorem ipsum door',
|
||||||
content: 'I had a problem with the installation of the php server',
|
content: 'I had a problem with the installation of the php server',
|
||||||
department: {
|
department: {
|
||||||
id: 2,
|
id: 2,
|
||||||
name: 'Environment Setup'
|
name: 'Environment Setup'
|
||||||
},
|
},
|
||||||
date: '15 Apr 2016',
|
date: 20150409,
|
||||||
file: 'http://www.opensupports.com/some_file.zip',
|
file: 'http://www.opensupports.com/some_file.zip',
|
||||||
language: 'en',
|
language: 'en',
|
||||||
unread: false,
|
unread: false,
|
||||||
@ -245,22 +391,98 @@ module.exports = [
|
|||||||
owner: {
|
owner: {
|
||||||
name: 'Steve Jobs'
|
name: 'Steve Jobs'
|
||||||
},
|
},
|
||||||
comments: [
|
actions: [
|
||||||
{
|
{
|
||||||
content: 'Do you have apache installed? It generally happens if you dont have apache.',
|
type: 'ASSIGN',
|
||||||
|
date: 20150409,
|
||||||
author: {
|
author: {
|
||||||
name: 'Steve Jobs',
|
name: 'Emilia Clarke',
|
||||||
email: 'jobs@steve.com',
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
staff: true
|
staff: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
type: 'COMMENT',
|
||||||
|
date: 20150409,
|
||||||
|
content: 'Do you have apache installed? It generally happens if you dont have apache.',
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'UN_ASSIGN',
|
||||||
|
date: 20150410,
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'DEPARTMENT_CHANGED',
|
||||||
|
date: 20150411,
|
||||||
|
content: 'System support',
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'COMMENT',
|
||||||
|
date: 20150412,
|
||||||
content: 'I have already installed apache, but the problem persists',
|
content: 'I have already installed apache, but the problem persists',
|
||||||
author: {
|
author: {
|
||||||
name: 'Haskell Curry',
|
name: 'Haskell Curry',
|
||||||
steve: 'haskell@lambda.com',
|
steve: 'haskell@lambda.com',
|
||||||
staff: false
|
staff: false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'PRIORITY_CHANGED',
|
||||||
|
date: 20150413,
|
||||||
|
content: 'MEDIUM',
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'COMMENT',
|
||||||
|
date: 20150511,
|
||||||
|
content: 'Thanks!, I soved it by myself',
|
||||||
|
author: {
|
||||||
|
name: 'Haskell Curry',
|
||||||
|
steve: 'haskell@lambda.com',
|
||||||
|
staff: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'CLOSE',
|
||||||
|
date: 20150513,
|
||||||
|
author: {
|
||||||
|
name: 'Emilia Clarke',
|
||||||
|
email: 'jobs@steve.com',
|
||||||
|
profilePic: 'http://i65.tinypic.com/9bep95.jpg',
|
||||||
|
staff: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'RE_OPEN',
|
||||||
|
date: 20151018,
|
||||||
|
author: {
|
||||||
|
name: 'Haskell Curry',
|
||||||
|
email: 'haskell@lambda.com',
|
||||||
|
staff: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user