Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Livechat department improvements and queue #1734

Merged
merged 11 commits into from
Dec 22, 2015
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this.AgentUsers = new Mongo.Collection('agentUsers');
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this.LivechatDepartmentAgents = new Mongo.Collection('rocketchat_livechat_department_agents');
26 changes: 26 additions & 0 deletions packages/rocketchat-livechat/client/stylesheets/livechat.less
Original file line number Diff line number Diff line change
Expand Up @@ -411,3 +411,29 @@
}
}
}

.department-agents {
list-style-type: none;

li {
display: inline-block;
background-color: #DDD;
border-radius: 10px;
padding: 2px 8px 2px 2px;
margin: 1px 0;
cursor: pointer;

.icon-plus-circled {
opacity: 0.5;
font-size: 0.8rem;
}
}
}

.agent-info {
input[type='text'] {
width: auto;
line-height: 24px;
height: 24px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,51 @@
</div>
<hr />
<h2>{{_ "Agents"}}</h2>
<div class="input-line double-col">
<input type="text" name="agent" placeholder="{{_ "Enter_a_username"}}">
<button name="addAgent" type="button" class="button add-agent">{{_ "Add_agent"}}</button>
</div>
<div class="list">
<table>
<thead>
<tr>
<th width="25%">{{_ "Username"}}</th>
<th>{{_ "Delete"}}</th>
</tr>
</thead>
<tbody>
{{#if agents.length}}
{{#each agents}}
<tr class="agent-info" data-id="{{_id}}">
<td>{{username}}</td>
<td><a href="#remove" class="remove-agent"><i class="icon-trash"></i></a></td>
</tr>
{{/each}}
{{else}}

<fieldset>
<legend>{{_ "Available_agents"}}</legend>

<ul class="department-agents available-agents">
{{#each availableAgents}}
<li><i class="icon-plus-circled"></i>{{username}}</li>
{{/each}}
</ul>
</fieldset>

<fieldset>
<legend>{{_ "Selected_agents"}}</legend>

<div class="list">
<table>
<thead>
<tr>
<td colspan="2">{{_ "There_are_no_agents_added_to_this_department_yet"}}</td>
<th width="25%">{{_ "Username"}}</th>
<th>{{_ "Count"}}</th>
<th>{{_ "Order"}}</th>
<th>&nbsp;</th>
</tr>
{{/if}}
</tbody>
</table>
</div>
</thead>
<tbody>
{{#if selectedAgents}}
{{#each selectedAgents}}
<tr class="agent-info">
<td>{{username}}</td>
<td><input type="text" class="count-{{agentId}}" name="count" value="{{count}}" size="3"></td>
<td><input type="text" class="order-{{agentId}}" name="order" value="{{order}}" size="3"></td>
<td><a href="#remove" class="remove-agent"><i class="icon-trash"></i></a></td>
</tr>
{{/each}}
{{else}}
<tr>
<td colspan="4">{{_ "There_are_no_agents_added_to_this_department_yet"}}</td>
</tr>
{{/if}}
</tbody>
</table>
</div>

</fieldset>

</fieldset>
<div class="submit">
<button type="button" class="button secondary back"><i class="icon-left-big"></i><span>{{_ "Back"}}</span></button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
Template.livechatDepartmentForm.helpers({
department() {
// return Template.instance().department && !_.isEmpty(Template.instance().department.get()) ? Template.instance().department.get() : { enabled: true };
return Template.instance().department.get();
},
agents() {
return Template.instance().department && !_.isEmpty(Template.instance().department.get()) ? Template.instance().department.get().agents : []
},
selectedAgents() {
return _.sortBy(Template.instance().selectedAgents.get(), 'username');
},
availableAgents() {
var selected = _.pluck(Template.instance().selectedAgents.get(), 'username');
return AgentUsers.find({ username: { $nin: selected }}, { sort: { username: 1 } });
}
});

Expand All @@ -29,16 +35,22 @@ Template.livechatDepartmentForm.events({
var oldBtnValue = $btn.html();
$btn.html(t('Saving'));

agents = instance.department && !_.isEmpty(instance.department.get()) ? instance.department.get().agents : [];

departmentData = {
var departmentData = {
enabled: enabled === "1" ? true : false,
name: name.trim(),
description: description.trim(),
agents: agents
}
description: description.trim()
};

var departmentAgents = [];

instance.selectedAgents.get().forEach((agent) => {
agent.count = instance.$('.count-' + agent.agentId).val();
agent.order = instance.$('.order-' + agent.agentId).val();

departmentAgents.push(agent);
});

Meteor.call('livechat:saveDepartment', _id, departmentData, function(error, result) {
Meteor.call('livechat:saveDepartment', _id, departmentData, departmentAgents, function(error, result) {
$btn.html(oldBtnValue);
if (error) {
return toastr.error(t(error.reason || error.error));
Expand All @@ -54,59 +66,44 @@ Template.livechatDepartmentForm.events({
FlowRouter.go('livechat-departments');
},

'click button.add-agent' (e, instance) {
'click .remove-agent' (e, instance) {
e.preventDefault();
var $btn = $(e.currentTarget);

var $agent = instance.$('input[name=agent]')

if ($agent.val().trim() === '') {
return toastr.error(t('Please_fill_a_username'));
}

var oldBtnValue = $btn.html();
$btn.html(t('Saving'));

Meteor.call('livechat:searchAgent', $agent.val(), function(error, user) {
$btn.html(oldBtnValue);
if (error) {
return toastr.error(t(error.reason || error.error));
}
department = instance.department.get() || {};
if (department.agents === undefined || !_.isArray(department.agents)) {
department.agents = [];
}
if (!_.findWhere(department.agents, { _id: user._id })) {
department.agents.push(user);
}
instance.department.set(department);
$agent.val('');
});
var selectedAgents = instance.selectedAgents.get();
selectedAgents = _.reject(selectedAgents, (agent) => { return agent._id === this._id });
instance.selectedAgents.set(selectedAgents);
},

'click a.remove-agent' (e, instance) {
e.preventDefault();
department = instance.department.get();
department.agents = _.reject(department.agents, (agent) => { return agent._id === this._id });
instance.department.set(department);
},

'keydown input[name=agent]' (e, instance) {
if (e.keyCode === 13) {
e.preventDefault();
$("button.add-agent").click();
}
'click .available-agents li' (e, instance) {
var selectedAgents = instance.selectedAgents.get();
var agent = _.clone(this);
agent.agentId = this._id;
delete agent._id;
selectedAgents.push(agent);
instance.selectedAgents.set(selectedAgents);
}
});

Template.livechatDepartmentForm.onCreated(function() {
this.department = new ReactiveVar({ enabled: true });
this.selectedAgents = new ReactiveVar([]);

this.subscribe('livechat:agents');

this.autorun(() => {
var sub = this.subscribe('livechat:departments', FlowRouter.getParam('_id'));
if (sub.ready()) {
department = LivechatDepartment.findOne({ _id: FlowRouter.getParam('_id') });
if (department) {
this.department.set(department);

this.subscribe('livechat:departmentAgents', department._id, () => {
var newSelectedAgents = [];
LivechatDepartmentAgents.find({ departmentId: department._id }).forEach((agent) => {
newSelectedAgents.push(agent);
});
this.selectedAgents.set(newSelectedAgents);
});
}
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
Template.livechatDepartments.helpers({
"departments": () => {
return LivechatDepartment.find();
},
"numAgents"() {
if (Array.isArray(this.agents)) {
return this.agents.length;
}
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
var AgentUsers;
var ManagerUsers;

Meteor.startup(function() {
AgentUsers = new Mongo.Collection('agentUsers');
ManagerUsers = new Mongo.Collection('managerUsers');
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ <h4>{{_ "Livechat"}}</h4>
<li>
<!-- <a href="{{pathFor 'livechat-dashboard'}}" class="{{active 'livechat-dashboard'}}">{{_ "Dashboard"}}</a> -->
<a href="{{pathFor 'livechat-users'}}" class="{{active 'livechat-users'}}">{{_ "User_management"}}</a>
<a href="{{pathFor 'livechat-departments'}}" class="{{active 'livechat-departments'}}">{{_ "Departments"}}</a>
<a href="{{pathFor 'livechat-departments'}}" class="{{active 'livechat-departments' 'livechat-department-edit'}}">{{_ "Departments"}}</a>
<a href="{{pathFor 'livechat-triggers'}}" class="{{active 'livechat-triggers'}}">{{_ "Triggers"}}</a>
<a href="{{pathFor 'livechat-installation'}}" class="{{active 'livechat-installation'}}">{{_ "Installation"}}</a>
<a href="{{pathFor 'livechat-appearance'}}" class="{{active 'livechat-appearance'}}">{{_ "Appearance"}}</a>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Template.livechatFlex.helpers({
active (route) {
active (...routes) {
FlowRouter.watchPathChange();
if (FlowRouter.current().route.name === route) {
if (routes.indexOf(FlowRouter.current().route.name) !== -1) {
return 'active';
}
}
Expand Down
6 changes: 5 additions & 1 deletion packages/rocketchat-livechat/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
"Add_manager" : "Add manager",
"Agent_added" : "Agent added",
"Agent_removed" : "Agent removed",
"Available_agents" : "Available agents",
"Back" : "Back",
"Closed" : "Closed",
"Copy_to_clipboard" : "Copy to clipboard",
"Count" : "Count",
"Dashboard" : "Dashboard",
"Department_not_found" : "Department not found",
"Department_removed" : "Department removed",
Expand All @@ -32,10 +34,12 @@
"New_Department" : "New Department",
"Num_Agents" : "# Agents",
"Opened" : "Opened",
"Order" : "Order",
"Please_fill_a_name" : "Please fill a name",
"Please_fill_a_username" : "Please fill a username",
"Please_select_enabled_yes_or_no" : "Please select an option for Enabled",
"Saved" : "Saved",
"Selected_agents" : "Selected agents",
"Send_a_message" : "Send a message",
"Theme" : "Theme",
"There_are_no_agents_added_to_this_department_yet" : "There are no agents added to this department yet.",
Expand All @@ -48,4 +52,4 @@
"Username_not_found" : "Username not found",
"Visitor_page_URL" : "Visitor page URL",
"Visitor_time_on_site" : "Visitor time on site"
}
}
13 changes: 10 additions & 3 deletions packages/rocketchat-livechat/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ Package.onUse(function(api) {

api.addFiles('client/stylesheets/livechat.less', 'client');

// collections
api.addFiles('client/collections/AgentUsers.js', 'client');
api.addFiles('client/collections/LivechatDepartment.js', 'client');
api.addFiles('client/collections/LivechatDepartmentAgents.js', 'client');
api.addFiles('client/collections/LivechatTrigger.js', 'client');

// client views
api.addFiles('client/views/app/livechatAppearance.html', 'client');
api.addFiles('client/views/app/livechatAppearance.js', 'client');
Expand Down Expand Up @@ -80,13 +86,14 @@ Package.onUse(function(api) {
api.addFiles('server/models/Users.js', 'server');
api.addFiles('server/models/Rooms.js', 'server');
api.addFiles('server/models/LivechatDepartment.js', 'server');
api.addFiles('server/models/LivechatDepartmentAgents.js', 'server');
api.addFiles('server/models/LivechatTrigger.js', 'server');

// collections
api.addFiles('client/lib/LivechatDepartment.js', 'client');
api.addFiles('client/lib/LivechatTrigger.js', 'client');
// server lib
api.addFiles('server/lib/getNextAgent.js', 'server');

// publications
api.addFiles('server/publications/departmentAgents.js', 'server');
api.addFiles('server/publications/livechatAgents.js', 'server');
api.addFiles('server/publications/livechatManagers.js', 'server');
api.addFiles('server/publications/livechatDepartments.js', 'server');
Expand Down
21 changes: 1 addition & 20 deletions packages/rocketchat-livechat/server/lib/getNextAgent.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,8 @@
this.getNextAgent = function(department) {
var agentFilter = {};

// find agents from that department
if (department) {
var agents = RocketChat.models.LivechatDepartment.getNextAgent(department);

if (!agents) {
return;
}

// sort = {
// count: 1,
// order: 1,
// 'user.name': 1
// }

// update = {
// $inc: {
// count: 1
// }
// }

// queueUser = findAndModify query, sort, update
return RocketChat.models.LivechatDepartment.getNextAgent(department);
} else {
return RocketChat.models.Users.getNextAgent();
}
Expand Down
4 changes: 2 additions & 2 deletions packages/rocketchat-livechat/server/methods/saveDepartment.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Meteor.methods({
'livechat:saveDepartment' (_id, departmentData) {
'livechat:saveDepartment' (_id, departmentData, departmentAgents) {
if (!Meteor.userId() || !RocketChat.authz.hasPermission(Meteor.userId(), 'view-livechat-manager')) {
throw new Meteor.Error("not-authorized");
}
Expand All @@ -17,6 +17,6 @@ Meteor.methods({
}
}

return RocketChat.models.LivechatDepartment.createOrUpdateDepartment(_id, departmentData.enabled, departmentData.name, departmentData.description, departmentData.agents);
return RocketChat.models.LivechatDepartment.createOrUpdateDepartment(_id, departmentData.enabled, departmentData.name, departmentData.description, departmentAgents);
}
});
Loading