diff --git a/app/livechat/client/views/app/tabbar/visitorEdit.html b/app/livechat/client/views/app/tabbar/visitorEdit.html index 9f8510b53bf..0d3afb3118b 100644 --- a/app/livechat/client/views/app/tabbar/visitorEdit.html +++ b/app/livechat/client/views/app/tabbar/visitorEdit.html @@ -30,6 +30,17 @@ + + {{#each visitorCustomFields}} +
+ +
+ {{/each}} {{/with}} {{#with room}} @@ -77,7 +88,19 @@ {{/each}} + + {{#each roomCustomFields}} +
+ +
+ {{/each}} {{/with}} +
diff --git a/app/livechat/client/views/app/tabbar/visitorEdit.js b/app/livechat/client/views/app/tabbar/visitorEdit.js index 79c9dc1886d..bb8439bb3f6 100644 --- a/app/livechat/client/views/app/tabbar/visitorEdit.js +++ b/app/livechat/client/views/app/tabbar/visitorEdit.js @@ -7,16 +7,61 @@ import { t } from '../../../../../utils'; import { hasRole } from '../../../../../authorization'; import './visitorEdit.html'; import { APIClient } from '../../../../../utils/client'; +import { LivechatCustomField } from '../../../collections/LivechatCustomField'; Template.visitorEdit.helpers({ visitor() { return Template.instance().visitor.get(); }, + visitorCustomFields() { + const fields = []; + const visitor = Template.instance().visitor.get(); + const customFields = Template.instance().customFields.get(); + + if (!customFields) { + return fields; + } + + customFields.forEach((field) => { + if (field.visibility !== 'hidden' && field.scope === 'visitor') { + const value = visitor.hasOwnProperty('livechatData') && visitor.livechatData.hasOwnProperty(field._id) + ? visitor.livechatData[field._id] + : ''; + + fields.push({ name: field._id, label: field.label, value }); + } + }); + + return fields; + }, + room() { return Template.instance().room.get(); }, + roomCustomFields() { + const fields = []; + const room = Template.instance().room.get(); + const customFields = Template.instance().customFields.get(); + + if (!customFields) { + return fields; + } + + customFields.forEach((field) => { + if (field.visibility !== 'hidden' && field.scope === 'room') { + const value = room.hasOwnProperty('livechatData') && room.livechatData.hasOwnProperty(field._id) + ? room.livechatData[field._id] + : ''; + + fields.push({ name: field._id, label: field.label, value }); + } + }); + + return fields; + }, + email() { const visitor = Template.instance().visitor.get(); if (visitor.visitorEmails && visitor.visitorEmails.length > 0) { @@ -61,6 +106,7 @@ Template.visitorEdit.onCreated(async function() { this.availableTags = new ReactiveVar([]); this.agentDepartments = new ReactiveVar([]); this.availableUserTags = new ReactiveVar([]); + this.customFields = new ReactiveVar([]); this.autorun(async () => { const { visitorId } = Template.currentData(); @@ -72,10 +118,13 @@ Template.visitorEdit.onCreated(async function() { const rid = Template.currentData().roomId; + this.subscribe('livechat:customFields'); this.autorun(async () => { const { room } = await APIClient.v1.get(`rooms.info?roomId=${ rid }`); + const customFields = LivechatCustomField.find().fetch(); this.room.set(room); this.tags.set((room && room.tags) || []); + this.customFields.set(customFields || []); }); const uid = Meteor.userId(); @@ -106,9 +155,17 @@ Template.visitorEdit.events({ userData.name = event.currentTarget.elements.name.value; userData.email = event.currentTarget.elements.email.value; userData.phone = event.currentTarget.elements.phone.value; + userData.livechatData = {}; + $('[data-visitorLivechatData=true]').each(function() { + userData.livechatData[this.name] = $(this).val() || ''; + }); roomData.topic = event.currentTarget.elements.topic.value; roomData.tags = instance.tags.get(); + roomData.livechatData = {}; + $('[data-roomLivechatData=true]').each(function() { + roomData.livechatData[this.name] = $(this).val() || ''; + }); if (sms) { delete userData.phone; diff --git a/app/livechat/client/views/app/tabbar/visitorInfo.html b/app/livechat/client/views/app/tabbar/visitorInfo.html index 4e0f029df5d..b9c5cfd4b65 100644 --- a/app/livechat/client/views/app/tabbar/visitorInfo.html +++ b/app/livechat/client/views/app/tabbar/visitorInfo.html @@ -10,42 +10,45 @@ {{#with user}}
{{#if name}} -

{{name}}

+

{{name}}

{{username}}

{{else}} -

{{username}}

+

{{username}}

{{/if}}
{{/with}} - {{#with room}} -
- -
- {{/with}} - - {{#with department}} -
- -
- {{/with}} +
+

{{_ "Conversation"}}

+ +
{{#if canSeeButtons}} @@ -68,20 +71,6 @@ {{/if}} - {{#if customFields}} -
-

{{_ "Custom_Fields"}}

- -
- -
-
- {{/if}} - {{> visitorNavigation .}} diff --git a/app/livechat/client/views/app/tabbar/visitorInfo.js b/app/livechat/client/views/app/tabbar/visitorInfo.js index d52373a34ec..3b67b8719fc 100644 --- a/app/livechat/client/views/app/tabbar/visitorInfo.js +++ b/app/livechat/client/views/app/tabbar/visitorInfo.js @@ -62,14 +62,9 @@ Template.visitorInfo.helpers({ return tags && tags.join(', '); }, - customFields() { + customRoomFields() { const fields = []; let livechatData = {}; - const user = Template.instance().user.get(); - if (user) { - livechatData = _.extend(livechatData, user.livechatData); - } - const data = Template.currentData(); if (data && data.rid) { const room = Template.instance().room.get(); @@ -84,7 +79,31 @@ Template.visitorInfo.helpers({ const customFields = Template.instance().customFields.get(); if (customFields) { const field = _.findWhere(customFields, { _id }); - if (field && field.visibility !== 'hidden') { + if (field && field.visibility !== 'hidden' && field.scope === 'room') { + fields.push({ label: field.label, value: livechatData[_id] }); + } + } + } + } + return fields; + } + }, + + customVisitorFields() { + const fields = []; + let livechatData = {}; + const user = Template.instance().user.get(); + if (user) { + livechatData = _.extend(livechatData, user.livechatData); + } + + if (!_.isEmpty(livechatData)) { + for (const _id in livechatData) { + if (livechatData.hasOwnProperty(_id)) { + const customFields = Template.instance().customFields.get(); + if (customFields) { + const field = _.findWhere(customFields, { _id }); + if (field && field.visibility !== 'hidden' && field.scope === 'visitor') { fields.push({ label: field.label, value: livechatData[_id] }); } } diff --git a/app/livechat/server/lib/Livechat.js b/app/livechat/server/lib/Livechat.js index de05200e2da..252c032fc43 100644 --- a/app/livechat/server/lib/Livechat.js +++ b/app/livechat/server/lib/Livechat.js @@ -276,7 +276,7 @@ export const Livechat = { return false; }, - saveGuest({ _id, name, email, phone }) { + saveGuest({ _id, name, email, phone, livechatData }) { const updateData = {}; if (name) { @@ -288,6 +288,9 @@ export const Livechat = { if (phone) { updateData.phone = phone; } + if (livechatData) { + updateData.livechatData = livechatData; + } const ret = LivechatVisitors.saveGuestById(_id, updateData); Meteor.defer(() => { @@ -414,7 +417,7 @@ export const Livechat = { }, saveRoomInfo(roomData, guestData) { - if ((roomData.topic != null || roomData.tags != null) && !LivechatRooms.setTopicAndTagsById(roomData._id, roomData.topic, roomData.tags)) { + if (!LivechatRooms.saveRoomById(roomData)) { return false; } diff --git a/app/livechat/server/methods/saveInfo.js b/app/livechat/server/methods/saveInfo.js index 8829b90e48b..6cfe1150fca 100644 --- a/app/livechat/server/methods/saveInfo.js +++ b/app/livechat/server/methods/saveInfo.js @@ -17,12 +17,14 @@ Meteor.methods({ name: Match.Optional(String), email: Match.Optional(String), phone: Match.Optional(String), + livechatData: Match.Optional(Object), })); check(roomData, Match.ObjectIncluding({ _id: String, topic: Match.Optional(String), tags: Match.Optional([String]), + livechatData: Match.Optional(Object), })); const room = LivechatRooms.findOneById(roomData._id, { t: 1, servedBy: 1 }); diff --git a/app/models/server/models/LivechatRooms.js b/app/models/server/models/LivechatRooms.js index 1a2f7543cc7..134efea887b 100644 --- a/app/models/server/models/LivechatRooms.js +++ b/app/models/server/models/LivechatRooms.js @@ -68,7 +68,7 @@ export class LivechatRooms extends Base { return this.update(query, update); } - setTopicAndTagsById(_id, topic, tags) { + saveRoomById({ _id, topic, tags, livechatData }) { const setData = {}; const unsetData = {}; @@ -86,6 +86,15 @@ export class LivechatRooms extends Base { unsetData.tags = 1; } + if (livechatData) { + setData.livechatData = {}; + for (const field in livechatData) { + if (livechatData.hasOwnProperty(field) && !_.isEmpty(s.trim(livechatData[field]))) { + setData.livechatData[field] = s.trim(livechatData[field]); + } + } + } + const update = {}; if (!_.isEmpty(setData)) { diff --git a/app/models/server/models/LivechatVisitors.js b/app/models/server/models/LivechatVisitors.js index 91e763fac14..843171c5e8f 100644 --- a/app/models/server/models/LivechatVisitors.js +++ b/app/models/server/models/LivechatVisitors.js @@ -160,6 +160,15 @@ export class LivechatVisitors extends Base { } } + if (data.livechatData) { + setData.livechatData = {}; + for (const field in data.livechatData) { + if (data.livechatData.hasOwnProperty(field) && !_.isEmpty(s.trim(data.livechatData[field]))) { + setData.livechatData[field] = s.trim(data.livechatData[field]); + } + } + } + const update = {}; if (!_.isEmpty(setData)) {