Ivan Diaz c3088406da
Fix ticket date style (#958)
* Fix ticket date style in table componenet

* WIP

* WIP

* Add shortcat date in ticket list

Co-authored-by: LautaroCesso <lautaro_cesso@hotmail.com>
2020-12-26 16:29:30 -03:00

303 lines
9.8 KiB
JavaScript

import React from 'react';
import _ from 'lodash';
import {connect} from 'react-redux';
import queryString from 'query-string';
import i18n from 'lib-app/i18n';
import DateTransformer from 'lib-core/date-transformer';
import TicketInfo from 'app-components/ticket-info';
import DepartmentDropdown from 'app-components/department-dropdown';
import Table from 'core-components/table';
import Button from 'core-components/button';
import Tooltip from 'core-components/tooltip';
import Checkbox from 'core-components/checkbox';
import Tag from 'core-components/tag';
import Icon from 'core-components/icon';
import Message from 'core-components/message';
class TicketList extends React.Component {
static propTypes = {
departments: React.PropTypes.array,
loading: React.PropTypes.bool,
ticketPath: React.PropTypes.string,
showDepartmentDropdown: React.PropTypes.bool,
tickets: React.PropTypes.arrayOf(React.PropTypes.object),
userId: React.PropTypes.number,
type: React.PropTypes.oneOf([
'primary',
'secondary'
]),
closedTicketsShown: React.PropTypes.bool,
onClosedTicketsShownChange: React.PropTypes.func,
onDepartmentChange: React.PropTypes.func
};
static defaultProps = {
showDepartmentDropdown: true,
loading: false,
tickets: [],
departments: [],
ticketPath: '/dashboard/ticket/',
type: 'primary',
closedTicketsShown: false
};
state = {
selectedDepartment: 0
};
render() {
const { type, showDepartmentDropdown, onClosedTicketsShownChange } = this.props;
return (
<div className="ticket-list">
<div className="ticket-list__filters">
{(type === 'primary') ? this.renderMessage() : null}
{
((type === 'secondary') && showDepartmentDropdown) ?
this.renderDepartmentsDropDown() :
null
}
{onClosedTicketsShownChange ? this.renderFilterCheckbox() : null}
</div>
<Table {...this.getTableProps()} />
</div>
);
}
renderFilterCheckbox() {
return (
<Checkbox
className="ticket-list__checkbox"
label={i18n("SHOW_CLOSED_TICKETS")}
value={this.props.closedTicketsShown}
onChange={this.props.onClosedTicketsShownChange}
wrapInLabel
/>
);
}
renderDepartmentsDropDown() {
return (
<div className="ticket-list__department-selector">
<DepartmentDropdown {...this.getDepartmentDropdownProps()} />
</div>
);
}
renderMessage() {
switch (queryString.parse(window.location.search)["message"]) {
case 'success':
return <Message className="create-ticket-form__message" type="success">{i18n('TICKET_SENT')}</Message>
case 'fail':
return <Message className="create-ticket-form__message" type="error">{i18n('TICKET_SENT_ERROR')}</Message>;
default:
return null;
}
}
getDepartmentDropdownProps() {
const { departments, onDepartmentChange } = this.props;
return {
departments: this.getDepartments(),
onChange: (event) => {
const departmentId = event.index && departments[event.index - 1].id;
this.setState({
selectedDepartment: departmentId
});
onDepartmentChange && onDepartmentChange(departmentId || null);
},
size: 'medium'
};
}
getTableProps() {
const { loading, page, pages, onPageChange } = this.props;
return {
loading,
headers: this.getTableHeaders(),
rows: this.getTableRows(),
pageSize: 10,
page,
pages,
onPageChange
};
}
getDepartments() {
let departments = _.clone(this.props.departments);
departments.unshift({
name: i18n('ALL_DEPARTMENTS')
});
return departments;
}
getTableHeaders() {
const { type } = this.props;
if(type == 'primary' ) {
return [
{
key: 'number',
value: i18n('NUMBER'),
className: 'ticket-list__number col-md-1'
},
{
key: 'title',
value: i18n('TITLE'),
className: 'ticket-list__title col-md-6'
},
{
key: 'department',
value: i18n('DEPARTMENT'),
className: 'ticket-list__department col-md-3'
},
{
key: 'date',
value: <div>
{i18n('DATE')}
{this.renderSortArrow('date')}
</div>,
className: 'ticket-list__date col-md-2'
}
];
} else if(type == 'secondary') {
return [
{
key: 'number',
value: i18n('NUMBER'),
className: 'ticket-list__number col-md-1'
},
{
key: 'title',
value: i18n('TITLE'),
className: 'ticket-list__title col-md-4'
},
{
key: 'department',
value: i18n('DEPARTMENT'),
className: 'ticket-list__department col-md-2'
},
{
key: 'author',
value: i18n('AUTHOR'),
className: 'ticket-list__author col-md-2'
},
{
key: 'date',
value: <div>
{i18n('DATE')}
{this.renderSortArrow('date')}
</div>,
className: 'ticket-list__date col-md-2'
}
];
}
}
renderSortArrow(header) {
const { orderBy, showOrderArrows, onChangeOrderBy } = this.props;
return (
showOrderArrows ?
<Icon
name={`arrow-${this.getIconName(header, orderBy)}`}
className="ticket-list__order-icon"
color={this.getIconColor(header, orderBy)}
onClick={() => onChangeOrderBy(header)} /> :
null
);
}
getIconName(header, orderBy) {
return (orderBy && orderBy.value === header && orderBy.asc) ? "up" : "down";
}
getIconColor(header, orderBy) {
return (orderBy && orderBy.value === header) ? "gray" : "white";
}
getTableRows() {
return this.getTickets().map(this.gerTicketTableObject.bind(this));
}
getTickets() {
const { tickets } = this.props;
const { selectedDepartment } = this.state;
return (
(selectedDepartment) ?
_.filter(tickets, (ticket) => { return ticket.department.id == selectedDepartment}) :
tickets
);
}
gerTicketTableObject(ticket) {
const { date, title, ticketNumber, closed, tags, department, author } = ticket;
const dateTodayWithOutHoursAndMinutes = DateTransformer.getDateToday();
const ticketDateWithOutHoursAndMinutes = Math.floor(DateTransformer.UTCDateToLocalNumericDate(JSON.stringify(date*1)) / 10000);
const stringTicketLocalDateFormat = DateTransformer.transformToString(date, false, true);
const ticketDate = (
((dateTodayWithOutHoursAndMinutes - ticketDateWithOutHoursAndMinutes) > 1) ?
stringTicketLocalDateFormat :
`${(dateTodayWithOutHoursAndMinutes - ticketDateWithOutHoursAndMinutes) ? "Yesterday" : "Today"} at ${stringTicketLocalDateFormat.slice(-5)}`
);
let titleText = (this.isTicketUnread(ticket)) ? title + ' (1)' : title;
return {
number: (
<Tooltip content={<TicketInfo ticket={ticket} />} openOnHover>
{'#' + ticketNumber}
</Tooltip>
),
title: (
<div>
{closed ? <Icon size="sm" name="lock" /> : null}
<Button className="ticket-list__title-link" type="clean" route={{to: this.props.ticketPath + ticketNumber}}>
{titleText}
</Button>
{(tags || []).map((tagName,index) => {
let tag = _.find(this.props.tags, {name:tagName});
return <Tag size='small' name={tag && tag.name} color={tag && tag.color} key={index} />
})}
</div>
),
department: department.name,
author: author.name,
date: ticketDate,
unread: this.isTicketUnread(ticket),
highlighted: this.isTicketUnread(ticket)
};
}
isTicketUnread(ticket) {
const { type, userId } = this.props;
const { unread, author, unreadStaff } = ticket;
if(type === 'primary') {
return unread;
} else if(type === 'secondary') {
if(author.id == userId && author.staff) {
return unread;
} else {
return unreadStaff;
}
}
}
}
export default connect((store) => {
return {
tags: store.config['tags']
};
})(TicketList);