diff --git a/application/Espo/Modules/Crm/Controllers/Activities.php b/application/Espo/Modules/Crm/Controllers/Activities.php index 94443ce9b7..9e8a92af3e 100644 --- a/application/Espo/Modules/Crm/Controllers/Activities.php +++ b/application/Espo/Modules/Crm/Controllers/Activities.php @@ -28,7 +28,6 @@ use \Espo\Core\Exceptions\Error, class Activities extends \Espo\Core\Controllers\Base { - public static $defaultAction = 'index'; public function actionListCalendarEvents($params, $data, $request) { @@ -43,9 +42,14 @@ class Activities extends \Espo\Core\Controllers\Base throw new BadRequest(); } - $service = $this->getService('Activities'); - return $service->getEvents($this->getUser()->id, $from, $to); + + $userId = $request->get('userId'); + if (!$userId) { + $userId = $this->getUser()->id; + } + + return $service->getEvents($userId, $from, $to); } public function actionPopupNotifications() diff --git a/application/Espo/Modules/Crm/Resources/metadata/app/jsLibs.json b/application/Espo/Modules/Crm/Resources/metadata/app/jsLibs.json index 9e9bea9a05..07217a86fa 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/app/jsLibs.json +++ b/application/Espo/Modules/Crm/Resources/metadata/app/jsLibs.json @@ -1,7 +1,7 @@ { - "FullCalendar": { + "full-calendar": { "path": "client/modules/crm/lib/fullcalendar.min.js", "exportsTo": "$", - "exportsAs": "fullCalendar" + "exportsAs": "fullCalendar" } } diff --git a/application/Espo/Modules/Crm/Resources/routes.json b/application/Espo/Modules/Crm/Resources/routes.json index 5cf0133fe8..35897869f4 100644 --- a/application/Espo/Modules/Crm/Resources/routes.json +++ b/application/Espo/Modules/Crm/Resources/routes.json @@ -10,7 +10,7 @@ "name":":name" } }, - + { "route":"/Activities", "method":"get", @@ -18,5 +18,5 @@ "controller":"Activities", "action":"listCalendarEvents" } - } + } ] diff --git a/application/Espo/Modules/Crm/Services/Activities.php b/application/Espo/Modules/Crm/Services/Activities.php index 467836d747..e78fff5478 100644 --- a/application/Espo/Modules/Crm/Services/Activities.php +++ b/application/Espo/Modules/Crm/Services/Activities.php @@ -541,6 +541,12 @@ class Activities extends \Espo\Core\Services\Base public function getEvents($userId, $from, $to) { + $user = $this->getEntityManager()->getEntity('User', $userId); + if (!$user) { + throw new NotFound(); + } + $this->accessCheck($user); + $pdo = $this->getPDO(); $sql = " @@ -606,7 +612,6 @@ class Activities extends \Espo\Core\Services\Base task.assigned_user_id = ".$pdo->quote($userId)." "; - $sth = $pdo->prepare($sql); $sth->execute(); $rows = $sth->fetchAll(PDO::FETCH_ASSOC); diff --git a/frontend/client/modules/crm/src/controllers/calendar.js b/frontend/client/modules/crm/src/controllers/calendar.js index ca45727c06..143d60bb5b 100644 --- a/frontend/client/modules/crm/src/controllers/calendar.js +++ b/frontend/client/modules/crm/src/controllers/calendar.js @@ -19,7 +19,7 @@ * along with EspoCRM. If not, see http://www.gnu.org/licenses/. ************************************************************************/ -Espo.define('Crm:Controllers.Calendar', 'Controller', function (Dep) { +Espo.define('crm:controllers/calendar', 'controller', function (Dep) { return Dep.extend({ @@ -37,9 +37,11 @@ Espo.define('Crm:Controllers.Calendar', 'Controller', function (Dep) { index: function (options) { this.handleCheckAccess(); - this.main('Crm:Calendar.CalendarPage', { + this.main('crm:views/calendar/calendar-page', { date: options.date, mode: options.mode, + userId: options.userId, + userName: options.userName }); }, }); diff --git a/frontend/client/modules/crm/src/views/calendar/calendar-page.js b/frontend/client/modules/crm/src/views/calendar/calendar-page.js index 624b673c69..ae10598a3c 100644 --- a/frontend/client/modules/crm/src/views/calendar/calendar-page.js +++ b/frontend/client/modules/crm/src/views/calendar/calendar-page.js @@ -19,11 +19,11 @@ * along with EspoCRM. If not, see http://www.gnu.org/licenses/. ************************************************************************/ -Espo.define('Crm:Views.Calendar.CalendarPage', 'View', function (Dep) { +Espo.define('crm:views/calendar/calendar-page', 'view', function (Dep) { return Dep.extend({ - template: 'crm:calendar.calendar-page', + template: 'crm:calendar/calendar-page', el: '#main', @@ -32,15 +32,24 @@ Espo.define('Crm:Views.Calendar.CalendarPage', 'View', function (Dep) { if (!mode) { var mode = this.getStorage().get('state', 'calendarMode') || null; } - this.createView('calendar', 'Crm:Calendar.Calendar', { + this.createView('calendar', 'crm:views/calendar/calendar', { date: this.options.date, + userId: this.options.userId, + userName: this.options.userName, mode: mode, el: '#main > .calendar-container', }, function (view) { var first = true; this.listenTo(view, 'view', function (date, mode) { + var url = '#Calendar/show/date=' + date + '&mode=' + mode; + if (this.options.userId) { + url += '&userId=' + this.options.userId; + if (this.options.userName) { + url += '&userName=' + this.options.userName; + } + } if (!first) { - this.getRouter().navigate('#Calendar/show/date=' + date + '&mode=' + mode); + this.getRouter().navigate(url); } first = false; }, this); diff --git a/frontend/client/modules/crm/src/views/calendar/calendar.js b/frontend/client/modules/crm/src/views/calendar/calendar.js index 2a87d16886..724c91f461 100644 --- a/frontend/client/modules/crm/src/views/calendar/calendar.js +++ b/frontend/client/modules/crm/src/views/calendar/calendar.js @@ -19,11 +19,11 @@ * along with EspoCRM. If not, see http://www.gnu.org/licenses/. ************************************************************************/ -Espo.define('Crm:Views.Calendar.Calendar', ['View', 'lib!FullCalendar'], function (Dep, FullCalendar) { +Espo.define('crm:views/calendar/calendar', ['view', 'lib!full-calendar'], function (Dep, FullCalendar) { return Dep.extend({ - template: 'crm:calendar.calendar', + template: 'crm:calendar/calendar', eventAttributes: [], @@ -123,6 +123,9 @@ Espo.define('Crm:Views.Calendar.Calendar', ['View', 'lib!FullCalendar'], functio } else { title = view.intervalStart.format(this.titleFormat[viewName]); } + if (this.options.userId && this.options.userName) { + title += ' (' + this.options.userName + ')'; + } this.$el.find('.date-title h4 span').text(title); }, @@ -295,12 +298,19 @@ Espo.define('Crm:Views.Calendar.Calendar', ['View', 'lib!FullCalendar'], functio var dateStart = this.convertTime(start); var dateEnd = this.convertTime(end); + var attributes = { + dateStart: dateStart, + dateEnd: dateEnd + }; + if (this.options.userId) { + attributes.assignedUserId = this.options.userId; + attributes.assignedUserName = this.options.userName || this.options.userId; + } + + this.notify('Loading...'); - this.createView('quickEdit', 'Crm:Calendar.Modals.Edit', { - attributes: { - dateStart: dateStart, - dateEnd: dateEnd, - }, + this.createView('quickEdit', 'crm:views/calendar/modals/edit', { + attributes: attributes }, function (view) { view.render(); view.notify(false); @@ -309,7 +319,7 @@ Espo.define('Crm:Views.Calendar.Calendar', ['View', 'lib!FullCalendar'], functio }.bind(this), eventClick: function (event) { this.notify('Loading...'); - this.createView('quickEdit', 'Crm:Calendar.Modals.Edit', { + this.createView('quickEdit', 'crm:views/calendar/modals/edit', { scope: event.scope, id: event.recordId }, function (view) { @@ -432,8 +442,15 @@ Espo.define('Crm:Views.Calendar.Calendar', ['View', 'lib!FullCalendar'], functio }, fetchEvents: function (from, to, callback) { + var url = 'Activities?from=' + from + '&to=' + to; + if (this.options.userId) { + url += '&userId=' + this.options.userId; + if (this.options.userName) { + url += '&userName=' + this.options.userName; + } + } $.ajax({ - url: 'Activities?from=' + from + '&to=' + to, + url: url, success: function (data) { var events = this.convertToFcEvents(data); callback(events); diff --git a/frontend/client/res/templates/header.tpl b/frontend/client/res/templates/header.tpl index 53eba1e083..4875f5aa04 100644 --- a/frontend/client/res/templates/header.tpl +++ b/frontend/client/res/templates/header.tpl @@ -5,16 +5,9 @@
{{#each items.buttons}} - {{#if link}} - + {{#if html}}{{{html}}}{{else}}{{translate label scope=../../../scope}}{{/if}} - {{else}} - - {{/if}} {{/each}} {{#if items.actions}} @@ -24,7 +17,7 @@
@@ -37,7 +30,7 @@
diff --git a/frontend/client/src/views/main.js b/frontend/client/src/views/main.js index 41cd6cf6e2..dd27ddde64 100644 --- a/frontend/client/src/views/main.js +++ b/frontend/client/src/views/main.js @@ -71,6 +71,7 @@ Espo.define('views/main', 'view', function (Dep) { if (Espo.Utils.checkActionAccess(this.getAcl(), this.model || this.scope, item)) { menu[type].push(item); } + item.name = item.action || item.name; }, this); }, this); } @@ -116,7 +117,7 @@ Espo.define('views/main', 'view', function (Dep) { ['actions', 'dropdown', 'buttons'].forEach(function (t) { this.menu[t].forEach(function (item, i) { - if (item.action == name) { + if (item.name == name) { index = i; type = t; } @@ -139,6 +140,32 @@ Espo.define('views/main', 'view', function (Dep) { }; this.getRouter().dispatch(this.scope, null, options); this.getRouter().navigate('#' + this.scope, {trigger: false}); + }, + + hideHeaderActionItem: function (name) { + ['actions', 'dropdown', 'buttons'].forEach(function (t) { + this.menu[t].forEach(function (item, i) { + if (item.name == name) { + item.hidden = true; + } + }, this); + }, this); + if (!this.isRendered()) return; + this.$el.find('.page-header li > .action[data-action="'+name+'"]').parent().addClass('hidden'); + this.$el.find('.page-header a.action[data-action="'+name+'"]').addClass('hidden'); + }, + + showHeaderActionItem: function (name) { + ['actions', 'dropdown', 'buttons'].forEach(function (t) { + this.menu[t].forEach(function (item, i) { + if (item.name == name) { + item.hidden = false; + } + }, this); + }, this); + if (!this.isRendered()) return; + this.$el.find('.page-header li > .action[data-action="'+name+'"]').parent().removeClass('hidden'); + this.$el.find('.page-header a.action[data-action="'+name+'"]').removeClass('hidden'); } }); diff --git a/frontend/client/src/views/user/detail.js b/frontend/client/src/views/user/detail.js index 293aa4c487..f1ade813b6 100644 --- a/frontend/client/src/views/user/detail.js +++ b/frontend/client/src/views/user/detail.js @@ -19,7 +19,7 @@ * along with EspoCRM. If not, see http://www.gnu.org/licenses/. ************************************************************************/ -Espo.define('Views.User.Detail', 'Views.Detail', function (Dep) { +Espo.define('views/user/detail', 'views/detail', function (Dep) { return Dep.extend({ @@ -52,6 +52,46 @@ Espo.define('Views.User.Detail', 'Views.Detail', function (Dep) { }); } } + + var showActivities = false; + + if (this.getUser().isAdmin()) { + showActivities = true; + } else { + if (this.getAcl().get('userPermission') === 'no') { + if (this.model.id == this.getUser().id) { + showActivities = true; + } + } else if (this.getAcl().get('userPermission') === 'team') { + if (this.model.has('teamsIds')) { + this.model.get('teamsIds').forEach(function (id) { + if (~(this.getUser().get('teamsIds') || []).indexOf(id)) { + showActivities = true; + } + }, this); + } else { + this.listenToOnce(this.model, 'sync', function () { + this.model.get('teamsIds').forEach(function (id) { + if (~(this.getUser().get('teamsIds') || []).indexOf(id)) { + console.log(1); + this.showHeaderActionItem('calendar'); + return; + } + }, this); + }, this); + } + } else { + showActivities = true; + } + } + + this.menu.buttons.push({ + name: 'calendar', + html: this.translate('Calendar', 'scopeNames'), + style: 'default', + link: '#Calendar/show/userId=' + this.model.id + '&userName=' + this.model.get('name'), + hidden: !showActivities + }); }, actionPreferences: function () { diff --git a/frontend/client/src/views/user/record/detail-side.js b/frontend/client/src/views/user/record/detail-side.js index 1202ac3c68..0cbcbd2672 100644 --- a/frontend/client/src/views/user/record/detail-side.js +++ b/frontend/client/src/views/user/record/detail-side.js @@ -62,6 +62,7 @@ Espo.define('Views.User.Record.DetailSide', 'Views.Record.DetailSide', function this.getParentView().showPanel('history'); this.getView('activities').actionRefresh(); this.getView('history').actionRefresh(); + return; } }, this); }, this); @@ -83,8 +84,7 @@ Espo.define('Views.User.Record.DetailSide', 'Views.Record.DetailSide', function "view":"Crm:Record.Panels.History", "hidden": !showActivities }); - - }, + } });