Commit 37b37b76 authored by Khac Chien LANG's avatar Khac Chien LANG

Merge branch 'add-expert' into 'master'

Add expert

See merge request !14
parents 9b71a518 e4eddbf2
@import './sidebar/most-sidebar';
@import './proposal/most-proposal';
@import './components/expert-auto-complete/most-expert-auto-complete';
@media (min-width: @screen-md-min) {
.most-root {
......
(function(angular) {
'use strict';
angular.module('linagora.esn.most')
.component('mostExpertAutoComplete', {
templateUrl: '/linagora.esn.most/app/components/expert-auto-complete/most-expert-auto-complete.html',
controller: 'MostExpertAutoCompleteController',
bindings: {
experts: '='
}
});
})(angular);
(function(angular) {
'use strict';
angular.module('linagora.esn.most')
.controller('MostExpertAutoCompleteController', MostExpertAutoCompleteController);
function MostExpertAutoCompleteController(
$element,
$q,
_,
elementScrollService,
emailService,
groupAttendeeProvider
) {
var self = this;
self.search = search;
function search(query) {
return groupAttendeeProvider.searchAttendee(query);
}
self.onTagAdding = function($tag) {
var isValidTag = emailService.isValidEmail($tag.email) && !_isDuplicatedMember($tag, self.experts);
return isValidTag;
};
self.onTagAdded = function() {
elementScrollService.autoScrollDown($element.find('div.tags'));
};
function _isDuplicatedMember(newMember, members) {
return !!_.find(members, { email: newMember.email });
}
}
})(angular);
most-expert-auto-complete {
.input-group {
.flex-row;
.input-group-addon {
margin: 15px;
.mdi {
font-size: 2em;
}
}
.most-experts-input {
.flex-column;
width: 100%;
}
}
}
.form-group
.input-group
span.input-group-addon
i.mdi.mdi-account-multiple-plus
.most-experts-input
.fg-line
tags-input.form-control(
ng-model='$ctrl.experts',
placeholder=__("Type a name or email..."),
display-property='email',
key-property='email',
replace-spaces-with-dashes='false',
on-tag-adding='$ctrl.onTagAdding($tag)',
on-tag-added='$ctrl.onTagAdded($tag)'
)
auto-complete(
source='$ctrl.search($query)',
min-length='1', debounce-delay='200',
max-results-to-show= '20',
template='/group/app/attendee/group-attendee-template.html'
)
......@@ -7,12 +7,14 @@
function MostProposalDetailController(
$state,
$stateParams,
$modal,
mostProposalApiClient
) {
var self = this;
self.$onInit = $onInit;
self.onRejectBtnClick = onRejectBtnClick;
self.onReviewBtnClick = onReviewBtnClick;
self.onAcceptBtnClick = onAcceptBtnClick;
function $onInit() {
......@@ -29,6 +31,19 @@
});
}
function onReviewBtnClick() {
$modal({
templateUrl: '/linagora.esn.most/app/proposal/detail/review/modal.html',
backdrop: 'static',
placement: 'center',
controllerAs: '$ctrl',
controller: 'MostProposalDetailReviewController',
locals: {
proposal: self.proposal
}
});
}
function onAcceptBtnClick() {
return mostProposalApiClient.updateProposal($stateParams.proposalId, { status: 'ACCEPTED' })
.then(function() {
......
sub-header
most-proposal-detail-subheader(
title="$ctrl.proposal.formJson.title",
data-title="$ctrl.proposal.formJson.title",
on-reject-btn-click="$ctrl.onRejectBtnClick()",
on-review-btn-click="$ctrl.onReviewBtnClick()",
on-accept-btn-click="$ctrl.onAcceptBtnClick()"
)
.card
......
.modal.most-modal.full-screen
form(name="form", ng-submit="$ctrl.send(); $hide()")
.modal-dialog
.modal-content
.modal-header
button.close(type="button", data-dismiss="modal", aria-label="Close", ng-click="$hide()")
span(aria-hidden="true") ×
h4.modal-title #{__('Lấy ý kiến chuyên gia')}
.modal-body
p
| #{__('Chọn một nhóm chuyên gia:')}
most-expert-auto-complete(experts="$ctrl.experts")
ng-form(name="form")
.form-group
span.p-r-25
| #{__('Đặt lịch họp:')}
toggle-switch(ng-model='$ctrl.invite', color='blue', form="form")
.modal-footer.flex
.flex-vertical-centered.flex-end
button.btn.btn-link(type="button", ng-click="$hide()")
| #{__('Cancel')}
button.btn.btn-primary(type="submit", ng-disabled="form.$invalid || form.$pending")
| #{__('Send')}
(function(angular) {
'use strict';
angular.module('linagora.esn.most')
.controller('MostProposalDetailReviewController', MostProposalDetailReviewController);
function MostProposalDetailReviewController(
$state,
$stateParams,
$modal,
$q,
proposal,
mostProposalApiClient,
mostService
) {
var self = this;
self.$onInit = $onInit;
self.send = send;
function $onInit() {
self.experts = [];
}
function send() {
var userIds = _getUserIdsFromGroups(self.experts || []);
mostProposalApiClient
.updateProposal($stateParams.proposalId, { reviewers: userIds, status: 'REVIEWING' })
.then(_inviteExperts)
.finally(function() {
$state.go('most.proposal');
});
}
function _getUserIdsFromGroups(groups) {
var userIds = [];
groups.forEach(function(group) {
group.members.forEach(function(item) {
if (item.member.objectType === 'user') {
userIds.push(item.member.id);
}
});
});
return userIds;
}
function _inviteExperts() {
if (self.invite) {
return mostService.inviteExperts(proposal.formJson.title, self.experts);
}
return $q.when();
}
}
})(angular);
......@@ -8,6 +8,7 @@
bindings: {
title: '<',
onRejectBtnClick: '&',
onReviewBtnClick: '&',
onAcceptBtnClick: '&'
}
});
......
......@@ -12,6 +12,8 @@ block right
ul.dropdown-menu.dropdown-menu-right
li
a(href='', ng-click='$ctrl.onRejectBtnClick()') Từ chối
li
a(href='', ng-click='$ctrl.onReviewBtnClick()') Xem xét
li
a(href='', ng-click='$ctrl.onAcceptBtnClick()') Duyệt
(function(angular) {
'use strict';
angular.module('linagora.esn.most')
.factory('mostService', mostService);
function mostService(
uuid4,
session,
CalendarShell,
calEventAPI,
calMoment,
calAttendeesDenormalizerService,
esnMemberResolverRegistry,
calAttendeeService,
ICAL
) {
return {
inviteExperts: inviteExperts
};
function inviteExperts(title, experts) {
var vcalendar = new ICAL.Component('vcalendar');
var vevent = new ICAL.Component('vevent');
var uuid = uuid4.generate();
vcalendar.addSubcomponent(vevent);
vevent.addPropertyWithValue('uid', uuid);
var shell = new CalendarShell(vcalendar);
var eventPath = '/calendars/' + session.user._id + '/events/' + uuid + '.ics';
shell.title = 'V/v: ' + title;
shell.start = calMoment().add(2, 'hour');
shell.end = calMoment().add(5, 'hour');
shell.organizer = session.user;
shell.path = eventPath;
groupMemberResolver(experts[0]).then(function(attendees) {
shell.attendees = attendees;
return calEventAPI.create(eventPath, shell.vcalendar, {});
});
}
function groupMemberResolver(group) {
var resolver = esnMemberResolverRegistry.getResolver('group');
if (!resolver) {
return group;
}
return resolver.resolve(group.email).then(function(members) {
return members.map(function(member) {
return calAttendeeService.userAsAttendee(member.member);
});
});
}
}
})(angular);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment