From 123c3ef8abafb2fe14c3115d76f7db6dc75beb56 Mon Sep 17 00:00:00 2001 From: yuri Date: Thu, 26 Mar 2015 13:14:13 +0200 Subject: [PATCH] grand filters change --- application/Espo/Core/SelectManagers/Base.php | 27 +++- .../Templates/Metadata/Base/clientDefs.json | 2 +- .../Templates/Metadata/Person/clientDefs.json | 2 +- .../metadata/clientDefs/Account.json | 2 +- .../Resources/metadata/clientDefs/Call.json | 28 +--- .../metadata/clientDefs/Campaign.json | 4 +- .../Resources/metadata/clientDefs/Case.json | 20 +-- .../metadata/clientDefs/Contact.json | 2 +- .../metadata/clientDefs/Document.json | 4 +- .../Resources/metadata/clientDefs/Lead.json | 12 +- .../metadata/clientDefs/Meeting.json | 28 +--- .../metadata/clientDefs/Opportunity.json | 20 +-- .../Resources/metadata/clientDefs/Target.json | 2 +- .../metadata/clientDefs/TargetList.json | 2 +- .../Resources/metadata/clientDefs/Task.json | 40 +----- .../Espo/Modules/Crm/SelectManagers/Call.php | 23 +++ .../Modules/Crm/SelectManagers/CaseObj.php | 12 ++ .../Espo/Modules/Crm/SelectManagers/Lead.php | 35 +++++ .../Modules/Crm/SelectManagers/Meeting.php | 23 +++ .../Crm/SelectManagers/Opportunity.php | 42 ++++++ .../Espo/Modules/Crm/SelectManagers/Task.php | 28 +++- .../Resources/metadata/clientDefs/Email.json | 35 +---- .../metadata/clientDefs/EmailTemplate.json | 2 +- .../Resources/metadata/clientDefs/Team.json | 2 +- .../Resources/metadata/clientDefs/User.json | 2 +- application/Espo/SelectManagers/Email.php | 21 +++ .../modules/crm/src/views/dashlets/calls.js | 5 +- .../modules/crm/src/views/dashlets/cases.js | 4 +- .../modules/crm/src/views/dashlets/leads.js | 8 +- .../crm/src/views/dashlets/meetings.js | 5 +- .../crm/src/views/dashlets/opportunities.js | 7 +- .../modules/crm/src/views/dashlets/tasks.js | 8 +- .../client/res/templates/record/search.tpl | 24 ++-- frontend/client/src/search-manager.js | 19 ++- .../client/src/views/fields/assigned-user.js | 4 +- .../client/src/views/fields/link-multiple.js | 7 +- .../client/src/views/fields/link-parent.js | 7 +- frontend/client/src/views/fields/link.js | 7 +- frontend/client/src/views/fields/teams.js | 4 +- .../client/src/views/modals/select-records.js | 11 +- frontend/client/src/views/record/search.js | 132 +++++++++++++----- 41 files changed, 420 insertions(+), 252 deletions(-) create mode 100644 application/Espo/Modules/Crm/SelectManagers/Lead.php create mode 100644 application/Espo/Modules/Crm/SelectManagers/Opportunity.php diff --git a/application/Espo/Core/SelectManagers/Base.php b/application/Espo/Core/SelectManagers/Base.php index e2c0897803..338865a5d8 100644 --- a/application/Espo/Core/SelectManagers/Base.php +++ b/application/Espo/Core/SelectManagers/Base.php @@ -42,6 +42,8 @@ class Base private $seed = null; + private $userTimeZone = null; + const MIN_LENGTH_FOR_CONTENT_SEARCH = 4; public function __construct($entityManager, \Espo\Entities\User $user, Acl $acl, $metadata) @@ -139,7 +141,7 @@ class Base $where = array(); foreach ($params['where'] as $item) { - if ($item['type'] == 'boolFilters' && !empty($item['value']) && is_array($item['value'])) { + if ($item['type'] == 'bool' && !empty($item['value']) && is_array($item['value'])) { foreach ($item['value'] as $filter) { $p = $this->getBoolFilterWhere($filter); if (!empty($p)) { @@ -151,11 +153,13 @@ class Base if (!empty($item['value'])) { $this->textFilter($item['value'], $result); } + } else if ($item['type'] == 'primary' && !empty($item['value'])) { + $this->primaryFilter($item['value'], $result); } } $linkedWith = array(); - $ignoreList = array('linkedWith', 'boolFilters'); + $ignoreList = array('linkedWith', 'bool', 'primary'); foreach ($params['where'] as $item) { if (!in_array($item['type'], $ignoreList)) { $part = $this->getWherePart($item); @@ -301,6 +305,17 @@ class Base return $result; } + protected function getUserTimeZone() + { + if (empty($this->userTimeZone)) { + $preferences = $this->getEntityManager()->getEntity('Preferences', $this->getUser()->id); + $timeZone = $preferences->get('timeZone'); + $this->userTimeZone = $timeZone; + } + + return $this->userTimeZone; + } + protected function convertDateTimeWhere($item) { $format = 'Y-m-d H:i:s'; @@ -541,6 +556,14 @@ class Base } } + protected function primaryFilter($filterName, &$result) + { + $method = 'filter' . ucfirst($filterName); + if (method_exists($this, $method)) { + $this->$method($result); + } + } + protected function getBoolFilterWhere($filterName) { $method = 'getBoolFilterWhere' . ucfirst($filterName); diff --git a/application/Espo/Core/Templates/Metadata/Base/clientDefs.json b/application/Espo/Core/Templates/Metadata/Base/clientDefs.json index e8985c4a52..05a17bfda9 100644 --- a/application/Espo/Core/Templates/Metadata/Base/clientDefs.json +++ b/application/Espo/Core/Templates/Metadata/Base/clientDefs.json @@ -1,4 +1,4 @@ { "controller": "Controllers.Record", - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Core/Templates/Metadata/Person/clientDefs.json b/application/Espo/Core/Templates/Metadata/Person/clientDefs.json index e8985c4a52..05a17bfda9 100644 --- a/application/Espo/Core/Templates/Metadata/Person/clientDefs.json +++ b/application/Espo/Core/Templates/Metadata/Person/clientDefs.json @@ -1,4 +1,4 @@ { "controller": "Controllers.Record", - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Account.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Account.json index 53a3acabc4..b32b4496ff 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Account.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Account.json @@ -35,5 +35,5 @@ "create": false } }, - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Call.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Call.json index efc52a88c5..cc27918c17 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Call.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Call.json @@ -75,37 +75,19 @@ } ] }, - "presetFilters": [ + "filterList": [ { "name":"planned", - "style": "primary", - "data": { - "status": { - "type": "in", - "value": ["Planned"] - } - } + "style": "primary" }, { "name":"held", - "style": "success", - "data": { - "status": { - "type": "in", - "value": ["Held"] - } - } + "style": "success" }, { "name":"todays", - "style": "info", - "data": { - "dateStart": { - "type": "today", - "dateTime": true - } - } + "style": "info" } ], - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Campaign.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Campaign.json index 458c5b2e4b..a281c022c3 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Campaign.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Campaign.json @@ -34,7 +34,7 @@ "create": false } }, - "presetFilters": [ + "filterList": [ { "name":"active", "style": "primary", @@ -46,5 +46,5 @@ } } ], - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Case.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Case.json index 837fe3008a..6377246bec 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Case.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Case.json @@ -23,27 +23,15 @@ } ] }, - "presetFilters": [ + "filterList": [ { "name":"open", - "style": "primary", - "data": { - "status": { - "type": "in", - "value": ["New", "Assigned", "Pending"] - } - } + "style": "primary" }, { "name":"closed", - "style": "success", - "data": { - "status": { - "type": "in", - "value": ["Closed"] - } - } + "style": "success" } ], - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Contact.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Contact.json index 90b25eff0e..998db2970a 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Contact.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Contact.json @@ -29,5 +29,5 @@ "create": false } }, - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Document.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Document.json index 2b39916f83..5c98d6561d 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Document.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Document.json @@ -1,6 +1,6 @@ { "controller": "Controllers.Record", - "presetFilters": [ + "filterList": [ { "name":"active", "style": "primary", @@ -22,5 +22,5 @@ } } ], - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json index 9cd77fce6d..785b304251 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json @@ -32,17 +32,11 @@ "create": false } }, - "presetFilters": [ + "filterList": [ { "name":"active", - "style": "primary", - "data": { - "status": { - "type": "in", - "value": ["New", "Assigned", "In Process"] - } - } + "style": "primary" } ], - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Meeting.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Meeting.json index 17a9bc5d6e..17d4c22541 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Meeting.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Meeting.json @@ -75,37 +75,19 @@ } ] }, - "presetFilters": [ + "filterList": [ { "name":"planned", - "style": "primary", - "data": { - "status": { - "type": "in", - "value": ["Planned"] - } - } + "style": "primary" }, { "name":"held", - "style": "success", - "data": { - "status": { - "type": "in", - "value": ["Held"] - } - } + "style": "success" }, { "name":"todays", - "style": "info", - "data": { - "dateStart": { - "type": "today", - "dateTime": true - } - } + "style": "info" } ], - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Opportunity.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Opportunity.json index 45a950d0ed..b71280e7c3 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Opportunity.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Opportunity.json @@ -22,27 +22,15 @@ } ] }, - "presetFilters": [ + "filterList": [ { "name":"open", - "style": "primary", - "data": { - "stage": { - "type": "in", - "value": ["Prospecting", "Qualification", "Needs Analysis", "Value Proposition", "Id. Decision Makers", "Perception Analysis","Proposal/Price Quote","Negotiation/Review"] - } - } + "style": "primary" }, { "name":"won", - "style": "success", - "data": { - "stage": { - "type": "in", - "value": ["Closed Won"] - } - } + "style": "success" } ], - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Target.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Target.json index 84b6263567..a35b187a63 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Target.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Target.json @@ -14,5 +14,5 @@ ] } }, - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/TargetList.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/TargetList.json index e8985c4a52..05a17bfda9 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/TargetList.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/TargetList.json @@ -1,4 +1,4 @@ { "controller": "Controllers.Record", - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Task.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Task.json index befa6cc815..04ec7483db 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Task.json +++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Task.json @@ -7,51 +7,23 @@ "list": "Crm:Task.List", "detail": "Crm:Task.Detail" }, - "presetFilters": [ + "filterList": [ { "name":"actual", - "style": "primary", - "data": { - "status": { - "type": "in", - "value": ["Not Started", "Started", "Deferred"] - } - } + "style": "primary" }, { "name":"completed", - "style": "success", - "data": { - "status": { - "type": "in", - "value": ["Completed"] - } - } + "style": "success" }, { "name":"todays", - "style": "info", - "data": { - "dateEnd": { - "type": "today", - "dateTime": true - } - } + "style": "info" }, { "name":"overdue", - "style": "danger", - "data": { - "dateEnd": { - "type": "past", - "dateTime": true - }, - "status": { - "type": "in", - "value": ["Not Started", "Started"] - } - } + "style": "danger" } ], - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Modules/Crm/SelectManagers/Call.php b/application/Espo/Modules/Crm/SelectManagers/Call.php index 2abae97a29..478765fc87 100644 --- a/application/Espo/Modules/Crm/SelectManagers/Call.php +++ b/application/Espo/Modules/Crm/SelectManagers/Call.php @@ -33,5 +33,28 @@ class Call extends \Espo\Core\SelectManagers\Base 'user.id' => $this->getUser()->id ); } + + protected function filterPlanned(&$result) + { + $result['whereClause'][] = array( + 'status' => 'Planned' + ); + } + + protected function filterHeld(&$result) + { + $result['whereClause'][] = array( + 'status' => 'Held' + ); + } + + protected function filterTodays(&$result) + { + $result['whereClause'][] = $this->convertDateTimeWhere(array( + 'type' => 'today', + 'field' => 'dateStart', + 'timeZone' => $this->getUserTimeZone() + )); + } } diff --git a/application/Espo/Modules/Crm/SelectManagers/CaseObj.php b/application/Espo/Modules/Crm/SelectManagers/CaseObj.php index 593a8d9823..601cc7e340 100644 --- a/application/Espo/Modules/Crm/SelectManagers/CaseObj.php +++ b/application/Espo/Modules/Crm/SelectManagers/CaseObj.php @@ -25,10 +25,22 @@ namespace Espo\Modules\Crm\SelectManagers; class CaseObj extends \Espo\Core\SelectManagers\Base { protected function boolFilterOpen(&$result) + { + $this->filterOpen($result); + } + + protected function filterOpen(&$result) { $result['whereClause'][] = array( 'status!=' => array('Duplicate', 'Rejected', 'Closed') ); } + + protected function filterClosed(&$result) + { + $result['whereClause'][] = array( + 'status' => array('Closed') + ); + } } diff --git a/application/Espo/Modules/Crm/SelectManagers/Lead.php b/application/Espo/Modules/Crm/SelectManagers/Lead.php new file mode 100644 index 0000000000..641580ffec --- /dev/null +++ b/application/Espo/Modules/Crm/SelectManagers/Lead.php @@ -0,0 +1,35 @@ + ['Converted', 'Recycled', 'Dead'] + ); + } + + } + diff --git a/application/Espo/Modules/Crm/SelectManagers/Meeting.php b/application/Espo/Modules/Crm/SelectManagers/Meeting.php index 447d281850..915a7de45b 100644 --- a/application/Espo/Modules/Crm/SelectManagers/Meeting.php +++ b/application/Espo/Modules/Crm/SelectManagers/Meeting.php @@ -33,5 +33,28 @@ class Meeting extends \Espo\Core\SelectManagers\Base 'user.id' => $this->getUser()->id ); } + + protected function filterPlanned(&$result) + { + $result['whereClause'][] = array( + 'status' => 'Planned' + ); + } + + protected function filterHeld(&$result) + { + $result['whereClause'][] = array( + 'status' => 'Held' + ); + } + + protected function filterTodays(&$result) + { + $result['whereClause'][] = $this->convertDateTimeWhere(array( + 'type' => 'today', + 'field' => 'dateStart', + 'timeZone' => $this->getUserTimeZone() + )); + } } diff --git a/application/Espo/Modules/Crm/SelectManagers/Opportunity.php b/application/Espo/Modules/Crm/SelectManagers/Opportunity.php new file mode 100644 index 0000000000..f289a6cc73 --- /dev/null +++ b/application/Espo/Modules/Crm/SelectManagers/Opportunity.php @@ -0,0 +1,42 @@ + array('Closed Won', 'Closed Lost') + ); + } + + protected function filterWon(&$result) + { + $result['whereClause'][] = array( + 'stage=' => 'Closed Won' + ); + } + + } + diff --git a/application/Espo/Modules/Crm/SelectManagers/Task.php b/application/Espo/Modules/Crm/SelectManagers/Task.php index d060f73a76..d64deabaaf 100644 --- a/application/Espo/Modules/Crm/SelectManagers/Task.php +++ b/application/Espo/Modules/Crm/SelectManagers/Task.php @@ -25,19 +25,45 @@ namespace Espo\Modules\Crm\SelectManagers; class Task extends \Espo\Core\SelectManagers\Base { protected function boolFilterActual(&$result) + { + $this->filterActual($result); + } + + protected function boolFilterCompleted(&$result) + { + $this->filterCompleted($result); + } + + protected function filterActual(&$result) { $result['whereClause'][] = array( 'status!=' => array('Completed', 'Canceled') ); } - protected function boolFilterCompleted(&$result) + protected function filterCompleted(&$result) { $result['whereClause'][] = array( 'status' => array('Completed') ); } + protected function filterOverdue(&$result) + { + $result['whereClause'][] = [ + $this->convertDateTimeWhere(array( + 'type' => 'past', + 'field' => 'dateEnd', + 'timeZone' => $this->getUserTimeZone() + )), + [ + array( + 'status!=' => ['Completed', 'Canceled'] + ) + ] + ]; + } + protected function convertDateTimeWhere($item) { $result = parent::convertDateTimeWhere($item); diff --git a/application/Espo/Resources/metadata/clientDefs/Email.json b/application/Espo/Resources/metadata/clientDefs/Email.json index 9b7558c361..b4092aec30 100644 --- a/application/Espo/Resources/metadata/clientDefs/Email.json +++ b/application/Espo/Resources/metadata/clientDefs/Email.json @@ -53,36 +53,18 @@ ] } }, - "presetFilters": [ + "filterList": [ { "name":"archived", - "style": "primary", - "data": { - "status": { - "type": "in", - "value": ["Archived"] - } - } + "style": "primary" }, { "name":"sent", - "style": "info", - "data": { - "status": { - "type": "in", - "value": ["Sent"] - } - } + "style": "info" }, { "name":"draft", - "style": "default", - "data": { - "status": { - "type": "in", - "value": ["Draft"] - } - } + "style": "default" } ], "defaultFilterData": { @@ -90,12 +72,7 @@ "onlyMy": true }, "presetName": "archived", - "advanced": { - "status": { - "type": "in", - "value": ["Archived"] - } - } + "primary": "archived" }, - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Resources/metadata/clientDefs/EmailTemplate.json b/application/Espo/Resources/metadata/clientDefs/EmailTemplate.json index 76de4c9aee..33da46216f 100644 --- a/application/Espo/Resources/metadata/clientDefs/EmailTemplate.json +++ b/application/Espo/Resources/metadata/clientDefs/EmailTemplate.json @@ -4,5 +4,5 @@ "edit": "EmailTemplate.Record.Edit", "detail": "EmailTemplate.Record.Detail" }, - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Resources/metadata/clientDefs/Team.json b/application/Espo/Resources/metadata/clientDefs/Team.json index 9503f16774..de25fa5d15 100644 --- a/application/Espo/Resources/metadata/clientDefs/Team.json +++ b/application/Espo/Resources/metadata/clientDefs/Team.json @@ -11,5 +11,5 @@ "edit":"Team.Record.Edit", "list":"Team.Record.List" }, - "boolFilters": ["onlyMy"] + "boolFilterList": ["onlyMy"] } diff --git a/application/Espo/Resources/metadata/clientDefs/User.json b/application/Espo/Resources/metadata/clientDefs/User.json index d17d30132d..0045cb9b3d 100644 --- a/application/Espo/Resources/metadata/clientDefs/User.json +++ b/application/Espo/Resources/metadata/clientDefs/User.json @@ -5,5 +5,5 @@ "editQuick":"User.Record.Edit", "list":"User.Record.List" }, - "boolFilters": ["onlyMyTeam"] + "boolFilterList": ["onlyMyTeam"] } diff --git a/application/Espo/SelectManagers/Email.php b/application/Espo/SelectManagers/Email.php index 64003c9b74..31b7ac28e0 100644 --- a/application/Espo/SelectManagers/Email.php +++ b/application/Espo/SelectManagers/Email.php @@ -34,6 +34,27 @@ class Email extends \Espo\Core\SelectManagers\Base ); } + protected function filterArchived(&$result) + { + $result['whereClause'][] = array( + 'status' => 'Archived' + ); + } + + protected function filterSent(&$result) + { + $result['whereClause'][] = array( + 'status' => 'Sent' + ); + } + + protected function filterDraft(&$result) + { + $result['whereClause'][] = array( + 'status' => 'Draft' + ); + } + protected function accessOnlyOwn(&$result) { $this->boolFilterOnlyMy($result); diff --git a/frontend/client/modules/crm/src/views/dashlets/calls.js b/frontend/client/modules/crm/src/views/dashlets/calls.js index a1cc886294..7ab37d76ee 100644 --- a/frontend/client/modules/crm/src/views/dashlets/calls.js +++ b/frontend/client/modules/crm/src/views/dashlets/calls.js @@ -50,11 +50,8 @@ Espo.define('Crm:Views.Dashlets.Calls', 'Views.Dashlets.Abstract.RecordList', fu bool: { onlyMy: true, }, + primary: 'planned', advanced: { - 'status': { - type: 'in', - value: ['Planned'] - }, '1': { type: 'or', value: { diff --git a/frontend/client/modules/crm/src/views/dashlets/cases.js b/frontend/client/modules/crm/src/views/dashlets/cases.js index 3e75a735f6..2a0d105821 100644 --- a/frontend/client/modules/crm/src/views/dashlets/cases.js +++ b/frontend/client/modules/crm/src/views/dashlets/cases.js @@ -59,8 +59,8 @@ Espo.define('Crm:Views.Dashlets.Cases', 'Views.Dashlets.Abstract.RecordList', fu searchData: { bool: { onlyMy: true, - open: true - } + }, + primary: 'open' }, }, diff --git a/frontend/client/modules/crm/src/views/dashlets/leads.js b/frontend/client/modules/crm/src/views/dashlets/leads.js index 887ede210c..7b56ad7f9d 100644 --- a/frontend/client/modules/crm/src/views/dashlets/leads.js +++ b/frontend/client/modules/crm/src/views/dashlets/leads.js @@ -56,13 +56,7 @@ Espo.define('Crm:Views.Dashlets.Leads', 'Views.Dashlets.Abstract.RecordList', fu bool: { onlyMy: true, }, - advanced: { - status: { - type: 'notIn', - value: ['Converted', 'Hoax', 'Dead'] - }, - }, - + primary: 'active' }, }, diff --git a/frontend/client/modules/crm/src/views/dashlets/meetings.js b/frontend/client/modules/crm/src/views/dashlets/meetings.js index 5a9f56401c..86f6bda378 100644 --- a/frontend/client/modules/crm/src/views/dashlets/meetings.js +++ b/frontend/client/modules/crm/src/views/dashlets/meetings.js @@ -50,11 +50,8 @@ Espo.define('Crm:Views.Dashlets.Meetings', 'Views.Dashlets.Abstract.RecordList', bool: { onlyMy: true, }, + primary: 'Planned', advanced: { - 'status': { - type: 'in', - value: ['Planned'] - }, '1': { type: 'or', value: { diff --git a/frontend/client/modules/crm/src/views/dashlets/opportunities.js b/frontend/client/modules/crm/src/views/dashlets/opportunities.js index 890cad0ae5..0dc973fc12 100644 --- a/frontend/client/modules/crm/src/views/dashlets/opportunities.js +++ b/frontend/client/modules/crm/src/views/dashlets/opportunities.js @@ -54,12 +54,7 @@ Espo.define('Crm:Views.Dashlets.Opportunities', 'Views.Dashlets.Abstract.RecordL bool: { onlyMy: true }, - advanced: { - "stage": { - type: 'notIn', - value: ['Closed Won', 'Closed Lost'] - } - } + primary: 'open' }, }, diff --git a/frontend/client/modules/crm/src/views/dashlets/tasks.js b/frontend/client/modules/crm/src/views/dashlets/tasks.js index 1da7f3f119..9eb639a7e4 100644 --- a/frontend/client/modules/crm/src/views/dashlets/tasks.js +++ b/frontend/client/modules/crm/src/views/dashlets/tasks.js @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with EspoCRM. If not, see http://www.gnu.org/licenses/. - ************************************************************************/ + ************************************************************************/ Espo.define('Crm:Views.Dashlets.Tasks', 'Views.Dashlets.Abstract.RecordList', function (Dep) { @@ -51,9 +51,9 @@ Espo.define('Crm:Views.Dashlets.Tasks', 'Views.Dashlets.Abstract.RecordList', fu }, searchData: { bool: { - onlyMy: true, - actual: true - } + onlyMy: true + }, + primary: 'actual' }, }, diff --git a/frontend/client/res/templates/record/search.tpl b/frontend/client/res/templates/record/search.tpl index f5dd29d66f..7ee78572b7 100644 --- a/frontend/client/res/templates/record/search.tpl +++ b/frontend/client/res/templates/record/search.tpl @@ -3,30 +3,32 @@
{{#if leftDropdown}} -
+
-
{{/if}}
+
@@ -39,11 +41,11 @@ {{translate 'Add Filter'}} -
+ diff --git a/frontend/client/src/search-manager.js b/frontend/client/src/search-manager.js index 3e96bd2aac..d0a91633ac 100644 --- a/frontend/client/src/search-manager.js +++ b/frontend/client/src/search-manager.js @@ -32,6 +32,7 @@ textFilter: '', bool: {}, advanced: {}, + primary: null, }; if (defaultData) { @@ -76,7 +77,7 @@ if (this.data.bool) { var o = { - type: 'boolFilters', + type: 'bool', value: [], }; for (var name in this.data.bool) { @@ -89,6 +90,16 @@ } } + if (this.data.primary) { + var o = { + type: 'primary', + value: this.data.primary, + }; + if (o.value.length) { + where.push(o); + } + } + if (this.data.advanced) { for (var name in this.data.advanced) { var defs = this.data.advanced[name]; @@ -99,6 +110,7 @@ where.push(part); } } + return where; }, @@ -163,6 +175,11 @@ this.data.bool = bool; }, + setPrimary: function (primary) { + this.data = Espo.Utils.clone(this.data); + this.data.primary = primary; + }, + set: function (data) { this.data = data; if (this.storage) { diff --git a/frontend/client/src/views/fields/assigned-user.js b/frontend/client/src/views/fields/assigned-user.js index d5eb1a2643..3b513af6d2 100644 --- a/frontend/client/src/views/fields/assigned-user.js +++ b/frontend/client/src/views/fields/assigned-user.js @@ -31,7 +31,7 @@ Espo.define('Views.Fields.AssignedUser', 'Views.Fields.UserWithAvatar', function Dep.prototype.init.call(this); }, - getSelectBoolFilters: function () { + getSelectBoolFilterList: function () { if (this.assignmentPermission == 'team') { return {'onlyMyTeam': true}; } @@ -40,7 +40,7 @@ Espo.define('Views.Fields.AssignedUser', 'Views.Fields.UserWithAvatar', function getAutocompleteUrl: function () { var url = Dep.prototype.getAutocompleteUrl.call(this); if (this.assignmentPermission == 'team') { - url += '&where%5B0%5D%5Btype%5D=boolFilters&where%5B0%5D%5Bvalue%5D%5B%5D=onlyMyTeam'; + url += '&where%5B0%5D%5Btype%5D=bool&where%5B0%5D%5Bvalue%5D%5B%5D=onlyMyTeam'; } return url; diff --git a/frontend/client/src/views/fields/link-multiple.js b/frontend/client/src/views/fields/link-multiple.js index 2799a599f9..6d778c477d 100644 --- a/frontend/client/src/views/fields/link-multiple.js +++ b/frontend/client/src/views/fields/link-multiple.js @@ -56,7 +56,9 @@ Espo.define('Views.Fields.LinkMultiple', 'Views.Fields.Base', function (Dep) { getSelectFilters: function () {}, - getSelectBoolFilters: function () {}, + getSelectBoolFilterList: function () {}, + + getPrimaryFilterName: function () {}, setup: function () { this.nameHashName = this.name + 'Names'; @@ -86,7 +88,8 @@ Espo.define('Views.Fields.LinkMultiple', 'Views.Fields.Base', function (Dep) { scope: this.foreignScope, createButton: this.mode != 'search', filters: this.getSelectFilters(), - boolFilters: this.getSelectBoolFilters(), + boolFilterList: this.getSelectBoolFilterList(), + primaryFilterName: this.getPrimaryFilterName(), multiple: true }, function (dialog) { dialog.render(); diff --git a/frontend/client/src/views/fields/link-parent.js b/frontend/client/src/views/fields/link-parent.js index 6122c649c0..3663c3e8bb 100644 --- a/frontend/client/src/views/fields/link-parent.js +++ b/frontend/client/src/views/fields/link-parent.js @@ -56,7 +56,9 @@ Espo.define('Views.Fields.LinkParent', 'Views.Fields.Base', function (Dep) { getSelectFilters: function () {}, - getSelectBoolFilters: function () {}, + getSelectBoolFilterList: function () {}, + + getPrimaryFilterName: function () {}, setup: function () { this.nameName = this.name + 'Name'; @@ -85,7 +87,8 @@ Espo.define('Views.Fields.LinkParent', 'Views.Fields.Base', function (Dep) { scope: this.foreignScope, createButton: this.mode != 'search', filters: this.getSelectFilters(), - boolFilters: this.getSelectBoolFilters(), + boolFilterList: this.getSelectBoolFilterList(), + primaryFilterName: this.getPrimaryFilterName(), }, function (dialog) { dialog.render(); Espo.Ui.notify(false); diff --git a/frontend/client/src/views/fields/link.js b/frontend/client/src/views/fields/link.js index 9832afeec7..1dee99df12 100644 --- a/frontend/client/src/views/fields/link.js +++ b/frontend/client/src/views/fields/link.js @@ -53,7 +53,9 @@ Espo.define('Views.Fields.Link', 'Views.Fields.Base', function (Dep) { getSelectFilters: function () {}, - getSelectBoolFilters: function () {}, + getSelectBoolFilterList: function () {}, + + getPrimaryFilterName: function () {}, setup: function () { this.nameName = this.name + 'Name'; @@ -72,7 +74,8 @@ Espo.define('Views.Fields.Link', 'Views.Fields.Base', function (Dep) { scope: this.foreignScope, createButton: this.mode != 'search', filters: this.getSelectFilters(), - boolFilters: this.getSelectBoolFilters(), + boolFilterList: this.getSelectBoolFilterList(), + primaryFilterName: this.getPrimaryFilterName(), }, function (dialog) { dialog.render(); self.notify(false); diff --git a/frontend/client/src/views/fields/teams.js b/frontend/client/src/views/fields/teams.js index c19f04f615..1caca04eef 100644 --- a/frontend/client/src/views/fields/teams.js +++ b/frontend/client/src/views/fields/teams.js @@ -28,7 +28,7 @@ Espo.define('Views.Fields.Teams', 'Views.Fields.LinkMultiple', function (Dep) { Dep.prototype.init.call(this); }, - getSelectBoolFilters: function () { + getSelectBoolFilterList: function () { if (this.assignmentPermission == 'team' || this.assignmentPermission == 'no') { return {'onlyMy': true}; } @@ -37,7 +37,7 @@ Espo.define('Views.Fields.Teams', 'Views.Fields.LinkMultiple', function (Dep) { getAutocompleteUrl: function () { var url = Dep.prototype.getAutocompleteUrl.call(this); if (this.assignmentPermission == 'team' || this.assignmentPermission == 'no') { - url += '&where%5B0%5D%5Btype%5D=boolFilters&where%5B0%5D%5Bvalue%5D%5B%5D=onlyMy'; + url += '&where%5B0%5D%5Btype%5D=bool&where%5B0%5D%5Bvalue%5D%5B%5D=onlyMy'; } return url; diff --git a/frontend/client/src/views/modals/select-records.js b/frontend/client/src/views/modals/select-records.js index acb6ded43b..fc83b45d62 100644 --- a/frontend/client/src/views/modals/select-records.js +++ b/frontend/client/src/views/modals/select-records.js @@ -50,7 +50,8 @@ Espo.define('Views.Modals.SelectRecords', 'Views.Modal', function (Dep) { setup: function () { this.filters = this.options.filters || {}; - this.boolFilters = this.options.boolFilters || {}; + this.boolFilterList = this.options.boolFilterList || {}; + this.primaryFilterName = this.options.primaryFilterName || null; if ('multiple' in this.options) { this.multiple = this.options.multiple; @@ -120,9 +121,13 @@ Espo.define('Views.Modals.SelectRecords', 'Views.Modal', function (Dep) { if (this.filters) { searchManager.setAdvanced(this.filters); } - if (this.boolFilters) { - searchManager.setBool(this.boolFilters); + if (this.boolFilterList) { + searchManager.setBool(this.boolFilterList); } + if (this.primaryFilterName) { + searchManager.setPrimary(this.primaryFilterName); + } + collection.where = searchManager.getWhere(); this.createView('search', 'Record.Search', { diff --git a/frontend/client/src/views/record/search.js b/frontend/client/src/views/record/search.js index fba30dbc95..b876801034 100644 --- a/frontend/client/src/views/record/search.js +++ b/frontend/client/src/views/record/search.js @@ -33,6 +33,10 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { textFilter: '', + primary: null, + + presetFilterList: null, + advanced: null, bool: null, @@ -44,12 +48,12 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { scope: this.scope, textFilter: this.textFilter, bool: this.bool || {}, - boolFilters: this.boolFilters, + boolFilterList: this.boolFilterList, advancedFields: this.getAdvancedDefs(), filterList: this.getFilterList(), presetName: this.presetName, - presetFilters: this.presetFilters, - leftDropdown: this.presetFilters.length || this.boolFilters.length + presetFilterList: this.presetFilterList, + leftDropdown: this.presetFilterList.length || this.boolFilterList.length }; }, @@ -65,16 +69,16 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { return this.fields != null && this.moreFields != null; }.bind(this)); - this.boolFilters = Espo.Utils.clone(this.getMetadata().get('clientDefs.' + this.scope + '.boolFilters') || []); + this.boolFilterList = Espo.Utils.clone(this.getMetadata().get('clientDefs.' + this.scope + '.boolFilterList') || []); this._helper.layoutManager.get(this.scope, 'filters', function (list) { this.moreFields = list; this.tryReady(); }.bind(this)); - this.presetFilters = Espo.Utils.clone(this.getMetadata().get('clientDefs.' + this.scope + '.presetFilters') || []); + this.presetFilterList = Espo.Utils.clone(this.getMetadata().get('clientDefs.' + this.scope + '.filterList') || []); ((this.getPreferences().get('presetFilters') || {})[this.scope] || []).forEach(function (item) { - this.presetFilters.push(item); + this.presetFilterList.push(item); }, this); this.loadSearchData(); @@ -123,7 +127,7 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { $target.closest('li').addClass('hide'); - this.presetName = null; + this.presetName = this.primary; this.createFilter(name, {}, function () { this.fetch(); @@ -143,7 +147,8 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { container.remove(); delete this.advanced[name]; - this.presetName = null; + + this.presetName = this.primary; this.updateAddFilterButton(); @@ -171,6 +176,8 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { this.removeFilters(); this.advanced = this.getPresetData(); + this.primary = this.getPrimaryFilterName(); + this.updateSearch(); this.manageLabels(); @@ -250,12 +257,13 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { id: id, name: id, label: name, - data: this.advanced + data: this.advanced, + primary: this.primary }; presetFilters[this.scope].push(data); - this.presetFilters.push(data); + this.presetFilterList.push(data); this.getPreferences().once('sync', function () { this.getPreferences().trigger('update'); @@ -284,7 +292,7 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { } }, this); - list = this.presetFilters; + list = this.presetFilterList; list.forEach(function (item, i) { if (item.id == id) { list.splice(i, 1); @@ -297,7 +305,7 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { this.getPreferences().save({patch: true}); this.getPreferences().trigger('update'); - this.presetName = null; + this.presetName = this.primary; this.advanced = {}; this.removeFilters(); @@ -327,24 +335,49 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { }, manageLabels: function () { + this.$advancedFiltersBar.empty().addClass('hidden'); + this.$advancedFiltersBar + this.managePresetFilters(); this.manageBoolFilters(); }, + addLabelHtml: function (label, style, id, noAction) { + var action = "showFiltersPanel"; + var cursor = 'pointer'; + var tag = 'a'; + if (noAction) { + action = "NO_ACTION"; + tag = 'span'; + cursor = 'default'; + } + + var barContentHtml = '<'+tag+' href="javascript:" style="cursor: '+cursor+';" class="label label-'+style+'" data-action="'+action+'">' + label + ''; + if (id) { + barContentHtml += ' '; + } + barContentHtml = '' + barContentHtml + '' + + this.$advancedFiltersBar.append($(barContentHtml)); + this.$advancedFiltersBar.removeClass('hidden'); + }, + managePresetFilters: function () { - var name = this.presetName || null; + var presetName = this.presetName || null; var data = this.getPresetData(); + var primary = this.primary; this.$el.find('ul.filter-menu a.preset span').remove(); - if (name) { + if (presetName && presetName != primary) { this.$advancedFiltersPanel.addClass('hidden'); var label = null; var style = null; var id = null; - this.presetFilters.forEach(function (item) { - if (item.name == this.presetName) { + + this.presetFilterList.forEach(function (item) { + if (item.name == presetName) { label = item.label || false; style = item.style || 'default'; id = item.id; @@ -352,14 +385,8 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { } }, this); label = label || this.translate(this.presetName, 'presetFilters', this.scope); + this.addLabelHtml(label, style, id); - var barContentHtml = '' + label + ''; - if (id) { - barContentHtml += ' '; - } - barContentHtml = '' + barContentHtml + '' - - this.$advancedFiltersBar.removeClass('hidden').html(barContentHtml); } else { this.$advancedFiltersPanel.removeClass('hidden'); @@ -370,21 +397,25 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { } else { this.$advancedFiltersBar.addClass('hidden').empty(); } - return; - } else { - this.$advancedFiltersBar.addClass('hidden').empty(); + this.$advancedFiltersBar.removeClass('hidden'); } } - name = name || ''; + if (primary) { + var label = this.translate(primary, 'presetFilters', this.scope); + var style = this.getPrimaryFilterStyle(); + this.addLabelHtml(label, style, null, true); + } - this.$el.find('ul.filter-menu a.preset[data-name="'+name+'"]').prepend(''); + presetName = presetName || ''; + + this.$el.find('ul.filter-menu a.preset[data-name="'+presetName+'"]').prepend(''); }, manageBoolFilters: function () { var isEnabled = false; - (this.boolFilters || []).forEach(function (item) { + (this.boolFilterList || []).forEach(function (item) { if (this.bool[item]) { isEnabled = true; var labelHtml = '' + this.translate(item, 'boolFilters', this.scope) + ''; @@ -424,15 +455,41 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { getPresetData: function () { var data = {}; - this.presetFilters.forEach(function (item) { + this.presetFilterList.forEach(function (item) { if (item.name == this.presetName) { - data = _.clone(item.data); + data = Espo.Utils.clone(item.data || {}); return; } }, this); return data; }, + getPrimaryFilterName: function () { + var primaryFilterName = null; + this.presetFilterList.forEach(function (item) { + if (item.name == this.presetName) { + if (!('data' in item)) { + primaryFilterName = item.name; + } else if (item.primary) { + primaryFilterName = item.primary; + } + return; + } + }, this); + return primaryFilterName; + }, + + getPrimaryFilterStyle: function () { + var style = null; + this.presetFilterList.forEach(function (item) { + if (item.name == this.primary) { + style = item.style || 'default'; + return; + } + }, this); + return style; + }, + loadSearchData: function () { var searchData = this.searchManager.get(); this.textFilter = searchData.textFilter; @@ -441,8 +498,14 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { this.presetName = searchData.presetName; } + if ('primary' in searchData) { + this.primary = searchData.primary; + } + if (this.presetName) { - this.advanced = this.getPresetData(); + this.advanced = _.extend(Espo.Utils.clone(this.getPresetData()), searchData.advanced); + + this.primary = this.getPrimaryFilterName(); } else { this.advanced = Espo.Utils.clone(searchData.advanced); } @@ -480,7 +543,7 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { this.bool = {}; - this.boolFilters.forEach(function (name) { + this.boolFilterList.forEach(function (name) { this.bool[name] = this.$el.find('input[name="' + name + '"]').prop('checked'); }, this); @@ -497,7 +560,8 @@ Espo.define('Views.Record.Search', 'View', function (Dep) { textFilter: this.textFilter, advanced: this.advanced, bool: this.bool, - presetName: this.presetName + presetName: this.presetName, + primary: this.primary }); },