diff --git a/client/src/app-components/ticket-list.js b/client/src/app-components/ticket-list.js index 10caf79b..1ce96238 100644 --- a/client/src/app-components/ticket-list.js +++ b/client/src/app-components/ticket-list.js @@ -1,5 +1,6 @@ import React from 'react'; import _ from 'lodash'; +import {connect} from "react-redux"; import i18n from 'lib-app/i18n'; import DateTransformer from 'lib-core/date-transformer'; @@ -11,6 +12,7 @@ import Button from 'core-components/button'; import Tooltip from 'core-components/tooltip'; import Icon from 'core-components/icon'; import Checkbox from 'core-components/checkbox'; +import Tag from 'core-components/tag'; class TicketList extends React.Component { static propTypes = { @@ -182,9 +184,16 @@ class TicketList extends React.Component { ), title: ( - +
+ + {ticket.tags.map((tagName,index) => { + let tag = _.find(this.props.tags, {name:tagName}); + return + })} +
+ ), priority: this.getTicketPriority(ticket.priority), department: ticket.department.name, @@ -257,5 +266,8 @@ class TicketList extends React.Component { } } - -export default TicketList; +export default connect((store) => { + return { + tags: store.config['tags'] + }; +})(TicketList); \ No newline at end of file diff --git a/client/src/app-components/ticket-viewer.js b/client/src/app-components/ticket-viewer.js index 90933a12..87012c71 100644 --- a/client/src/app-components/ticket-viewer.js +++ b/client/src/app-components/ticket-viewer.js @@ -22,6 +22,8 @@ import Icon from 'core-components/icon'; import TextEditor from 'core-components/text-editor'; import InfoTooltip from 'core-components/info-tooltip'; import DepartmentDropdown from 'app-components/department-dropdown'; +import TagSelector from 'core-components/tag-selector'; +import Tag from 'core-components/tag'; class TicketViewer extends React.Component { static propTypes = { @@ -36,10 +38,12 @@ class TicketViewer extends React.Component { userId: React.PropTypes.number, userStaff: React.PropTypes.bool, userDepartments: React.PropTypes.array, - userLevel: React.PropTypes.number + userLevel: React.PropTypes.number, + tags: React.PropTypes.array }; static defaultProps = { + tags: [], editable: false, ticket: { author: {}, @@ -63,6 +67,7 @@ class TicketViewer extends React.Component { render() { const ticket = this.props.ticket; + console.log('tickett',ticket) return (
@@ -105,7 +110,7 @@ class TicketViewer extends React.Component {
{i18n('DEPARTMENT')}
{i18n('AUTHOR')}
-
{i18n('DATE')}
+
{i18n('TAGS')}
@@ -115,7 +120,7 @@ class TicketViewer extends React.Component { onChange={this.onDepartmentDropdownChanged.bind(this)} />
{ticket.author.name}
-
{DateTransformer.transformToString(ticket.date)}
+
{i18n('PRIORITY')}
@@ -153,12 +158,15 @@ class TicketViewer extends React.Component {
{i18n('DEPARTMENT')}
{i18n('AUTHOR')}
-
{i18n('DATE')}
+
{i18n('TAGS')}
{ticket.department.name}
{ticket.author.name}
-
{DateTransformer.transformToString(ticket.date, false)}
+
{ticket.tags.length ? ticket.tags.map((tagName,index) => { + let tag = _.find(this.props.tags, {name:tagName}); + return + }) : i18n('NONE')}
{i18n('PRIORITY')}
@@ -412,7 +420,25 @@ class TicketViewer extends React.Component { } }).then(this.onTicketModification.bind(this)); } + addTag(tag) { + API.call({ + path: '/ticket/add-tag', + data: { + ticketNumber: this.props.ticket.ticketNumber, + tagId: tag + } + }).then(this.onTicketModification.bind(this)) + } + removeTag(tag) { + API.call({ + path: '/ticket/remove-tag', + data: { + ticketNumber: this.props.ticket.ticketNumber, + tagId: tag + } + }).then(this.onTicketModification.bind(this)) + } onCustomResponsesChanged({index}) { let replaceContentWithCustomResponse = () => { this.setState({ @@ -515,6 +541,7 @@ export default connect((store) => { staffMembersLoaded: store.adminData.staffMembersLoaded, allowAttachments: store.config['allow-attachments'], userSystemEnabled: store.config['user-system-enabled'], - userLevel: store.session.userLevel + userLevel: store.session.userLevel, + tags: store.config['tags'] }; })(TicketViewer); diff --git a/client/src/core-components/tag-selector.js b/client/src/core-components/tag-selector.js index 6af1469d..3de95502 100644 --- a/client/src/core-components/tag-selector.js +++ b/client/src/core-components/tag-selector.js @@ -2,6 +2,7 @@ import React from 'react'; import _ from 'lodash'; import Icon from 'core-components/icon'; import DropDown from 'core-components/drop-down'; +import Tag from 'core-components/tag'; class TagSelector extends React.Component { @@ -32,14 +33,8 @@ class TagSelector extends React.Component { renderSelectedTag(item,index) { - return ( -
event.stopPropagation()} key={index}> - {item.name} - - - -
- ); + return ; + } renderTagOptions() { @@ -50,24 +45,23 @@ class TagSelector extends React.Component { renderTagOption(item,index) { return ( -
+
{item.name}
); } - onRemoveClick(tag) { - + onRemoveClick(tagId) { if(this.props.onRemoveClick){ - this.props.onRemoveClick(tag); - } - } - onTagSelected(tag) { - if(this.props.onTagSelected){ - this.props.onTagSelected(tag); + this.props.onRemoveClick(tagId); } } + onTagSelected(tagId) { + if(this.props.onTagSelected){ + this.props.onTagSelected(tagId); + } + } } export default TagSelector; diff --git a/client/src/core-components/tag-selector.scss b/client/src/core-components/tag-selector.scss index 2cb298af..d03e4712 100644 --- a/client/src/core-components/tag-selector.scss +++ b/client/src/core-components/tag-selector.scss @@ -9,6 +9,7 @@ cursor: text; background-color: white; border: 1px solid $grey; + min-height: 38px; &:focus { outline: none; @@ -17,34 +18,6 @@ } } - &__selected-tags { - border-radius: 3px; - background-color: white; - padding: 3px 1px; - } - - &__selected-tag { - color: white; - display: inline-block; - border-radius: 3px; - margin-left: 5px; - padding: 3px; - font-size: 13px; - } - - &__selected-tag { - cursor: default; - - &-remove { - cursor: pointer; - margin-left: 10px; - - &:hover { - color: $light-grey; - } - } - } - &__tag-options { font-size: 13px; color: $dark-grey; diff --git a/client/src/core-components/tag.js b/client/src/core-components/tag.js new file mode 100644 index 00000000..9974cab1 --- /dev/null +++ b/client/src/core-components/tag.js @@ -0,0 +1,42 @@ +import React from 'react'; +import Icon from 'core-components/icon'; +import classNames from 'classnames'; + +class Tag extends React.Component { + + static propTypes = { + name: React.PropTypes.string, + color: React.PropTypes.string, + showDeleteButton: React.PropTypes.bool, + onRemoveClick: React.PropTypes.func, + size: React.PropTypes.oneOf(['small','medium']) + }; + + render() { + return ( +
event.stopPropagation()} > + {this.props.name} + {this.props.showDeleteButton ? this.renderRemoveButton() : null} +
+ ); + } + + renderRemoveButton() { + return ( + + + + ); + } + + getClass() { + let classes = { + 'tag': true, + 'tag_small': this.props.size === 'small', + 'tag_medium': this.props.size === 'medium' + }; + + return classNames(classes); + } +} +export default Tag; diff --git a/client/src/core-components/tag.scss b/client/src/core-components/tag.scss new file mode 100644 index 00000000..81c2fcc3 --- /dev/null +++ b/client/src/core-components/tag.scss @@ -0,0 +1,24 @@ +@import '../scss/vars'; + +.tag{ + color: white; + display: inline-block; + border-radius: 3px; + margin-left: 5px; + padding: 3px; + font-size: 13px; + cursor: default; + + &__remove { + cursor: pointer; + margin-left: 10px; + + &:hover { + color: $light-grey; + } + } + + &_small { + font-size: 11px; + } +} \ No newline at end of file diff --git a/client/src/lib-app/session-store.js b/client/src/lib-app/session-store.js index 540c994b..33a31246 100644 --- a/client/src/lib-app/session-store.js +++ b/client/src/lib-app/session-store.js @@ -62,6 +62,8 @@ class SessionStore { this.setItem('allow-attachments', configs['allow-attachments']); this.setItem('maintenance-mode', configs['maintenance-mode']); this.setItem('max-size', configs['max-size']); + this.setItem('tags', configs['tags']); + } getConfigs() { @@ -78,6 +80,7 @@ class SessionStore { 'allow-attachments': (this.getItem('allow-attachments') * 1), 'maintenance-mode': (this.getItem('maintenance-mode') * 1), 'max-size': this.getItem('max-size'), + 'tags': this.getItem('tags') }; }