From ef19dc3330096bc3581fb8bef45a2c5255cff345 Mon Sep 17 00:00:00 2001 From: yuri Date: Wed, 14 Sep 2016 13:53:11 +0300 Subject: [PATCH 01/13] fix orm 2 --- application/Espo/ORM/DB/Query/Base.php | 4 ++-- application/Espo/ORM/Repositories/RDB.php | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/application/Espo/ORM/DB/Query/Base.php b/application/Espo/ORM/DB/Query/Base.php index aa77acce81..7f923939f0 100644 --- a/application/Espo/ORM/DB/Query/Base.php +++ b/application/Espo/ORM/DB/Query/Base.php @@ -1010,8 +1010,8 @@ abstract class Base 'distantKey' => $distantKey ); case IEntity::BELONGS_TO_PARENT: - $key = $this->toDb($entity->getEntityType()) . 'Id'; - $typeKey = $this->toDb($entity->getEntityType()) . 'Type'; + $key = $relationName . 'Id'; + $typeKey = $relationName . 'Type'; return array( 'key' => $key, 'typeKey' => $typeKey, diff --git a/application/Espo/ORM/Repositories/RDB.php b/application/Espo/ORM/Repositories/RDB.php index fa6de53b21..818f24a758 100644 --- a/application/Espo/ORM/Repositories/RDB.php +++ b/application/Espo/ORM/Repositories/RDB.php @@ -215,8 +215,16 @@ class RDB extends \Espo\ORM\Repository if (!$entity->id) { return []; } - $entityType = $entity->relations[$relationName]['entity']; - $this->getEntityManager()->getRepository($entityType)->handleSelectParams($params); + + if ($entity->getRelationType($relationName) === Entity::BELONGS_TO_PARENT) { + $entityType = $entity->get($relationName . 'Type'); + } else { + $entityType = $entity->relations[$relationName]['entity']; + } + + if ($entityType) { + $this->getEntityManager()->getRepository($entityType)->handleSelectParams($params); + } $result = $this->getMapper()->selectRelated($entity, $relationName, $params); if (is_array($result)) { From da2cebd765f4e58362ae2d024b9427767afed15c Mon Sep 17 00:00:00 2001 From: yuri Date: Wed, 14 Sep 2016 14:03:30 +0300 Subject: [PATCH 02/13] fix orm 3 --- application/Espo/ORM/DB/Mapper.php | 4 ++-- application/Espo/ORM/DB/Query/Base.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/application/Espo/ORM/DB/Mapper.php b/application/Espo/ORM/DB/Mapper.php index cf7a5b01e6..d8c13be2cd 100644 --- a/application/Espo/ORM/DB/Mapper.php +++ b/application/Espo/ORM/DB/Mapper.php @@ -212,8 +212,8 @@ abstract class Mapper implements IMapper $params['whereClause'][$foreignKey] = $entity->get($key); if ($relType == IEntity::HAS_CHILDREN) { - $foreignTypeKey = $keySet['foreignTypeKey']; - $params['whereClause'][$foreignTypeKey] = $entity->getEntityType(); + $foreignType = $keySet['foreignType']; + $params['whereClause'][$foreignType] = $entity->getEntityType(); } if ($relType == IEntity::HAS_ONE) { diff --git a/application/Espo/ORM/DB/Query/Base.php b/application/Espo/ORM/DB/Query/Base.php index 7f923939f0..ea81854066 100644 --- a/application/Espo/ORM/DB/Query/Base.php +++ b/application/Espo/ORM/DB/Query/Base.php @@ -978,14 +978,14 @@ abstract class Base if (isset($relOpt['foreignKey'])) { $foreignKey = $relOpt['foreignKey']; } - $foreignTypeKey = 'parentType'; + $foreignType = 'parentType'; if (isset($relOpt['foreignType'])) { - $foreignTypeKey = $relOpt['foreignType']; + $foreignType = $relOpt['foreignType']; } return array( 'key' => $key, 'foreignKey' => $foreignKey, - 'foreignTypeKey' => $foreignTypeKey, + 'foreignType' => $foreignType, ); case IEntity::MANY_MANY: From 6e8342511f5b079f5accb83a913a690b517459d4 Mon Sep 17 00:00:00 2001 From: yuri Date: Wed, 14 Sep 2016 16:01:29 +0300 Subject: [PATCH 03/13] lang --- .../Espo/Modules/Crm/Resources/i18n/en_US/Global.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json b/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json index 3d7013a87f..1658e79307 100644 --- a/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json +++ b/application/Espo/Modules/Crm/Resources/i18n/en_US/Global.json @@ -19,7 +19,8 @@ "CampaignTrackingUrl": "Tracking URL", "Activities": "Activities", "KnowledgeBaseArticle": "Knowledge Base Article", - "KnowledgeBaseCategory": "Knowledge Base Category" + "KnowledgeBaseCategory": "Knowledge Base Category", + "CampaignLogRecord": "Campaign Log Record" }, "scopeNamesPlural": { "Account": "Accounts", @@ -41,7 +42,8 @@ "CampaignTrackingUrl": "Tracking URLs", "Activities": "Activities", "KnowledgeBaseArticle": "Knowledge Base", - "KnowledgeBaseCategory": "Knowledge Base Categories" + "KnowledgeBaseCategory": "Knowledge Base Categories", + "CampaignLogRecord": "Campaign Log Records" }, "dashlets": { "Leads": "My Leads", From fc9b67672f382f41a7052bb810b648d76f57c65c Mon Sep 17 00:00:00 2001 From: yuri Date: Wed, 14 Sep 2016 16:14:06 +0300 Subject: [PATCH 04/13] date: isEmpty filter --- application/Espo/Resources/i18n/en_US/Global.json | 3 ++- client/src/views/fields/date.js | 7 ++++++- client/src/views/fields/datetime.js | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/application/Espo/Resources/i18n/en_US/Global.json b/application/Espo/Resources/i18n/en_US/Global.json index 600c33f4dc..c1470b2462 100644 --- a/application/Espo/Resources/i18n/en_US/Global.json +++ b/application/Espo/Resources/i18n/en_US/Global.json @@ -473,7 +473,8 @@ "lastSevenDays": "Last 7 Days", "lastXDays": "Last X Days", "nextXDays": "Next X Days", - "ever": "Ever" + "ever": "Ever", + "isEmpty": "Is Empty" }, "searchRanges": { "is": "Is", diff --git a/client/src/views/fields/date.js b/client/src/views/fields/date.js index 7008a05ecf..b042f35921 100644 --- a/client/src/views/fields/date.js +++ b/client/src/views/fields/date.js @@ -38,7 +38,7 @@ Espo.define('views/fields/date', 'views/fields/base', function (Dep) { validations: ['required', 'date', 'after', 'before'], - searchTypeOptions: ['lastSevenDays', 'ever', 'currentMonth', 'lastMonth', 'currentQuarter', 'lastQuarter', 'currentYear', 'lastYear', 'today', 'past', 'future', 'lastXDays', 'nextXDays', 'on', 'after', 'before', 'between'], + searchTypeOptions: ['lastSevenDays', 'ever', 'isEmpty', 'currentMonth', 'lastMonth', 'currentQuarter', 'lastQuarter', 'currentYear', 'lastYear', 'today', 'past', 'future', 'lastXDays', 'nextXDays', 'on', 'after', 'before', 'between'], setup: function () { Dep.prototype.setup.call(this); @@ -246,6 +246,11 @@ Espo.define('views/fields/date', 'views/fields/base', function (Dep) { value: value, dateValue: value }; + } else if (type === 'isEmpty') { + data = { + typeFront: type, + type: 'isNull' + } } else { data = { type: type diff --git a/client/src/views/fields/datetime.js b/client/src/views/fields/datetime.js index 8280a8cfef..a0495166ca 100644 --- a/client/src/views/fields/datetime.js +++ b/client/src/views/fields/datetime.js @@ -36,7 +36,7 @@ Espo.define('views/fields/datetime', 'views/fields/date', function (Dep) { validations: ['required', 'datetime', 'after', 'before'], - searchTypeOptions: ['lastSevenDays', 'ever', 'currentMonth', 'lastMonth', 'currentQuarter', 'lastQuarter', 'currentYear', 'lastYear', 'today', 'past', 'future', 'lastXDays', 'nextXDays', 'on', 'after', 'before', 'between'], + searchTypeOptions: ['lastSevenDays', 'ever', 'isEmpty', 'currentMonth', 'lastMonth', 'currentQuarter', 'lastQuarter', 'currentYear', 'lastYear', 'today', 'past', 'future', 'lastXDays', 'nextXDays', 'on', 'after', 'before', 'between'], timeFormatMap: { 'HH:mm': 'H:i', From bf9799af6669a303bba1d224f98b8616c046b32b Mon Sep 17 00:00:00 2001 From: yuri Date: Wed, 14 Sep 2016 17:09:10 +0300 Subject: [PATCH 05/13] fix markdown link syntax --- application/Espo/Resources/i18n/cs_CZ/Global.json | 2 +- application/Espo/Resources/i18n/de_DE/Global.json | 2 +- application/Espo/Resources/i18n/en_US/Global.json | 2 +- application/Espo/Resources/i18n/es_ES/Global.json | 2 +- application/Espo/Resources/i18n/fr_FR/Global.json | 2 +- application/Espo/Resources/i18n/id_ID/Global.json | 2 +- application/Espo/Resources/i18n/it_IT/Global.json | 2 +- application/Espo/Resources/i18n/nl_NL/Global.json | 2 +- application/Espo/Resources/i18n/pl_PL/Global.json | 2 +- application/Espo/Resources/i18n/pt_BR/Global.json | 2 +- application/Espo/Resources/i18n/ru_RU/Global.json | 2 +- application/Espo/Resources/i18n/uk_UA/Global.json | 2 +- client/src/view-helper.js | 6 +++--- client/src/views/email/detail.js | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/application/Espo/Resources/i18n/cs_CZ/Global.json b/application/Espo/Resources/i18n/cs_CZ/Global.json index aa2c219c1c..84e63bf413 100644 --- a/application/Espo/Resources/i18n/cs_CZ/Global.json +++ b/application/Espo/Resources/i18n/cs_CZ/Global.json @@ -190,7 +190,7 @@ "massRemoveResultSingle": "{count} záznam byl odstraněn", "noRecordsRemoved": "Žádné záznamy nebyly odstraněny", "clickToRefresh": "Kliknout pro obnovení", - "streamPostInfo": "Napište @username pro zmínění uživatelů v příspěvku.\n\nDostupná syntaxe:\n`code`\n**tučný text**\n*kurzíva*\n~smazaný text~\n> citace\n(url)[link]" + "streamPostInfo": "Napište @username pro zmínění uživatelů v příspěvku.\n\nDostupná syntaxe:\n`code`\n**tučný text**\n*kurzíva*\n~smazaný text~\n> citace\n[text](url)" }, "boolFilters": { "onlyMy": "Pouze moje", diff --git a/application/Espo/Resources/i18n/de_DE/Global.json b/application/Espo/Resources/i18n/de_DE/Global.json index ad63d64c5c..edef4ac879 100644 --- a/application/Espo/Resources/i18n/de_DE/Global.json +++ b/application/Espo/Resources/i18n/de_DE/Global.json @@ -215,7 +215,7 @@ "massRemoveResultSingle": "{count} Eintrag wurde gelöscht", "noRecordsRemoved": "Es wurden keine Einträge gelöscht", "clickToRefresh": "Klicken um zu aktualisieren", - "streamPostInfo": "Schreiben Sie @username um Benutzer in der Notiz hervorzuheben.\n\nVerfügbare Syntax:\n`Code`\n**fetter Text**\n*Hervorgehobener Text*\n~Durchgestrichen~\n> blockquote\n(url)[link]", + "streamPostInfo": "Schreiben Sie @username um Benutzer in der Notiz hervorzuheben.\n\nVerfügbare Syntax:\n`Code`\n**fetter Text**\n*Hervorgehobener Text*\n~Durchgestrichen~\n> blockquote\n[text](url)", "writeYourCommentHere": "Notiz hier einfügen", "writeMessageToUser": "Nachricht an {user} schreiben", "writeMessageToSelf": "Nachricht an sich selbst schreiben", diff --git a/application/Espo/Resources/i18n/en_US/Global.json b/application/Espo/Resources/i18n/en_US/Global.json index c1470b2462..43efd3cd72 100644 --- a/application/Espo/Resources/i18n/en_US/Global.json +++ b/application/Espo/Resources/i18n/en_US/Global.json @@ -219,7 +219,7 @@ "massRemoveResultSingle": "{count} record has been removed", "noRecordsRemoved": "No records were removed", "clickToRefresh": "Click to refresh", - "streamPostInfo": "Type @username to mention users in the post.\n\nAvailable markdown syntax:\n`code`\n**strong text**\n*emphasized text*\n~deleted text~\n> blockquote\n(link name)[url]", + "streamPostInfo": "Type @username to mention users in the post.\n\nAvailable markdown syntax:\n`code`\n**strong text**\n*emphasized text*\n~deleted text~\n> blockquote\n[link text](url)", "writeYourCommentHere": "Write your comment here", "writeMessageToUser": "Write a message to {user}", "writeMessageToSelf": "Write a message on your stream", diff --git a/application/Espo/Resources/i18n/es_ES/Global.json b/application/Espo/Resources/i18n/es_ES/Global.json index c02c10431f..2d5041f33b 100644 --- a/application/Espo/Resources/i18n/es_ES/Global.json +++ b/application/Espo/Resources/i18n/es_ES/Global.json @@ -218,7 +218,7 @@ "massRemoveResultSingle": "{count} registro se ha eliminado", "noRecordsRemoved": "No hay registros se eliminaron", "clickToRefresh": "Clic aqui para actualizar", - "streamPostInfo": "Escriba @username para mencionar usuarios en el comentario.\n\nLa sintaxis markdown disponible es:\n\n`código`\n**texto en negritas**\n*un texto con énfasis*\n~el texto eliminado~\n> Citar bloque\n(nombre del enlace)[url]", + "streamPostInfo": "Escriba @username para mencionar usuarios en el comentario.\n\nLa sintaxis markdown disponible es:\n\n`código`\n**texto en negritas**\n*un texto con énfasis*\n~el texto eliminado~\n> Citar bloque\n[nombre del enlace](url)", "writeYourCommentHere": "Escriba su comentario aquí", "writeMessageToUser": "Escribir un mensaje a {user}", "writeMessageToSelf": "Escribir un mensaje a uno mismo", diff --git a/application/Espo/Resources/i18n/fr_FR/Global.json b/application/Espo/Resources/i18n/fr_FR/Global.json index cadddc1559..fe054726a6 100644 --- a/application/Espo/Resources/i18n/fr_FR/Global.json +++ b/application/Espo/Resources/i18n/fr_FR/Global.json @@ -177,7 +177,7 @@ "massRemoveResultSingle": "{count} enregistrement a été supprimé", "noRecordsRemoved": "Aucun enregistrement n'a été trouvé", "clickToRefresh": "Cliquer pour rafraîchir", - "streamPostInfo": "Taper @utilisateur pour mentionner des utilisateurs dans votre message.\n\nSyntaxe disponible:\n`code`\n**gras**\n*italique*\n~texte barré~\n> bloc de citation\n(url)[lien]", + "streamPostInfo": "Taper @utilisateur pour mentionner des utilisateurs dans votre message.\n\nSyntaxe disponible:\n`code`\n**gras**\n*italique*\n~texte barré~\n> bloc de citation\n[url](lien)", "writeYourCommentHere": "Écrivez votre commentaire ici" }, "boolFilters": { diff --git a/application/Espo/Resources/i18n/id_ID/Global.json b/application/Espo/Resources/i18n/id_ID/Global.json index 59ab2a1057..0c247e67d0 100644 --- a/application/Espo/Resources/i18n/id_ID/Global.json +++ b/application/Espo/Resources/i18n/id_ID/Global.json @@ -215,7 +215,7 @@ "massRemoveResultSingle": "{count} record telah dihapus", "noRecordsRemoved": "Tidak ada catatan yang dihapus", "clickToRefresh": "Klik untuk refresh", - "streamPostInfo": "Ketik @nama pengguna untuk menyebutkan pengguna di pos.\n\nSintaks yang tersedia:\n` Kode `\n** teks yang kuat **\n* menekankan teks *\n~ teks yang dihapus ~\n> blockquote\n(D) [url]", + "streamPostInfo": "Ketik @nama pengguna untuk menyebutkan pengguna di pos.\n\nSintaks yang tersedia:\n` Kode `\n** teks yang kuat **\n* menekankan teks *\n~ teks yang dihapus ~\n> blockquote\n[D](url)", "writeYourCommentHere": "Tulis komentar Anda di sini", "writeMessageToUser": "Tulis pesan ke {user}", "writeMessageToSelf": "Tulis pesan ke diri sendiri", diff --git a/application/Espo/Resources/i18n/it_IT/Global.json b/application/Espo/Resources/i18n/it_IT/Global.json index 63d26949ab..9083bc78af 100644 --- a/application/Espo/Resources/i18n/it_IT/Global.json +++ b/application/Espo/Resources/i18n/it_IT/Global.json @@ -216,7 +216,7 @@ "massRemoveResult": "{count} record sono stati rimossi", "noRecordsRemoved": "Nessun record è stato rimosso", "clickToRefresh": "Clicca per aggiornare", - "streamPostInfo": "Type @username to mention users in the post.\n\nAvailable markdown syntax:\n`code`\n**strong text**\n*emphasized text*\n~deleted text~\n> blockquote\n(link name)[url]", + "streamPostInfo": "Type @username to mention users in the post.\n\nAvailable markdown syntax:\n`code`\n**strong text**\n*emphasized text*\n~deleted text~\n> blockquote\n[text](url)", "writeYourCommentHere": "Scrivi il tuo commento qui", "writeMessageToUser": "Scrivi un messaggio a {user}", "writeMessageToSelf": "Scrivi un messaggio sul tuo streame", diff --git a/application/Espo/Resources/i18n/nl_NL/Global.json b/application/Espo/Resources/i18n/nl_NL/Global.json index 50503e4133..06f22677f9 100644 --- a/application/Espo/Resources/i18n/nl_NL/Global.json +++ b/application/Espo/Resources/i18n/nl_NL/Global.json @@ -202,7 +202,7 @@ "massRemoveResultSingle": "{count} bestanden zijn verwijderd", "noRecordsRemoved": "Er werden geen bestanden verwijderd ", "clickToRefresh": "Click to refresh", - "streamPostInfo": "Type @username to mention users in the post.\n\nAvailable markdown syntax:\n`code`\n**strong text**\n*emphasized text*\n~deleted text~\n> blockquote\n(url)[link]", + "streamPostInfo": "Type @username to mention users in the post.\n\nAvailable markdown syntax:\n`code`\n**strong text**\n*emphasized text*\n~deleted text~\n> blockquote\n[text](url)", "writeYourCommentHere": "Schrijf hier uw opmerkingen" }, "boolFilters": { diff --git a/application/Espo/Resources/i18n/pl_PL/Global.json b/application/Espo/Resources/i18n/pl_PL/Global.json index 2701e4582d..f3a13c0ef5 100644 --- a/application/Espo/Resources/i18n/pl_PL/Global.json +++ b/application/Espo/Resources/i18n/pl_PL/Global.json @@ -215,7 +215,7 @@ "massRemoveResultSingle": "Ilość usuniętych rekordów: {count}", "noRecordsRemoved": "Nic nie usunięto", "clickToRefresh": "Kliknij aby odświeżyć", - "streamPostInfo": "Wpisz @użytkownik aby zaznaczyć użytkownika w poście.\n\nDostępne znaczniki:\n`kod`\n**pogrubiony**\n*pochylony*\n~skasowany~\n> blockquote\n(link name)[url]", + "streamPostInfo": "Wpisz @użytkownik aby zaznaczyć użytkownika w poście.\n\nDostępne znaczniki:\n`kod`\n**pogrubiony**\n*pochylony*\n~skasowany~\n> blockquote\n[link text](url)", "writeYourCommentHere": "Dodaj swój komentarz tutaj", "writeMessageToUser": "Napisz wiadomość do {user}", "writeMessageToSelf": "Napisz wiadomość do siebie", diff --git a/application/Espo/Resources/i18n/pt_BR/Global.json b/application/Espo/Resources/i18n/pt_BR/Global.json index d14a1921b3..a87039d9e9 100644 --- a/application/Espo/Resources/i18n/pt_BR/Global.json +++ b/application/Espo/Resources/i18n/pt_BR/Global.json @@ -173,7 +173,7 @@ "massRemoveResultSingle": "{count} registro foi removido", "noRecordsRemoved": "Nenhum registro foi removido", "clickToRefresh": "Clique para atualizar", - "streamPostInfo": "Digite @usuario para mencionar usuários na postagem.\n\nSintaxe markdown disponível::\n`code`\n**strong text**\n*emphasized text*\n~deleted text~\n> blockquote\n(url)[link]", + "streamPostInfo": "Digite @usuario para mencionar usuários na postagem.\n\nSintaxe markdown disponível::\n`code`\n**strong text**\n*emphasized text*\n~deleted text~\n> blockquote\n[link text](url)", "writeYourCommentHere": "Escreva seu comentário aqui" }, "boolFilters": { diff --git a/application/Espo/Resources/i18n/ru_RU/Global.json b/application/Espo/Resources/i18n/ru_RU/Global.json index ebe4c9d30e..2ef16e13e1 100644 --- a/application/Espo/Resources/i18n/ru_RU/Global.json +++ b/application/Espo/Resources/i18n/ru_RU/Global.json @@ -215,7 +215,7 @@ "massRemoveResultSingle": "{count} запись была удалена", "noRecordsRemoved": "Записи не были удалены", "clickToRefresh": "Нажмите для обновления", - "streamPostInfo": "Введите @username чтобы упомянуть пользователей в сообщении.\n\nДоступный синтаксис разметки:\n`код`\n**важный текст**\n*эмоционально выделенный текст*\n~удаленный текст~\n> цитата\n(название ссылки)[URL]", + "streamPostInfo": "Введите @username чтобы упомянуть пользователей в сообщении.\n\nДоступный синтаксис разметки:\n`код`\n**важный текст**\n*эмоционально выделенный текст*\n~удаленный текст~\n> цитата\n[текст ссылки](URL)", "writeYourCommentHere": "Оставьте свою заметку здесь", "writeMessageToUser": "Оставить сообщение для {user}", "writeMessageToSelf": "Оставить сообщение для себя", diff --git a/application/Espo/Resources/i18n/uk_UA/Global.json b/application/Espo/Resources/i18n/uk_UA/Global.json index d177d183a4..47eb9a9ff7 100644 --- a/application/Espo/Resources/i18n/uk_UA/Global.json +++ b/application/Espo/Resources/i18n/uk_UA/Global.json @@ -183,7 +183,7 @@ "massRemoveResultSingle": "{count} запис була видалена", "noRecordsRemoved": "Жодних записів не було видалено", "clickToRefresh": "Натисніть, щоби поновити", - "streamPostInfo": "Тип @username для згадування користувачів у дописі.\nПрипустимий синтаксис розмітки:`code`\n**strong text**\n*emphasized text*\n~deleted text~\n> blockquote\n(url)[link]", + "streamPostInfo": "Тип @username для згадування користувачів у дописі.\nПрипустимий синтаксис розмітки:`code`\n**strong text**\n*emphasized text*\n~deleted text~\n> blockquote\n[текст](url)", "writeYourCommentHere": "Напишіть свій коментар" }, "boolFilters": { diff --git a/client/src/view-helper.js b/client/src/view-helper.js index de138f491d..6d8441f6c3 100644 --- a/client/src/view-helper.js +++ b/client/src/view-helper.js @@ -29,11 +29,11 @@ Espo.define('view-helper', [], function () { var ViewHelper = function (options) { - this.urlRegex = /(^|[^\[])(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; + this.urlRegex = /(^|[^\(])(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; this._registerHandlebarsHelpers(); this.mdSearch = [ - /\("?(.*?)"?\)\[(.*?)\]/g, + /\["?(.*?)"?\]\((.*?)\)/g, /\&\#x60;(([\s\S]*?)\&\#x60;)/g, /(\*\*)(.*?)\1/g, /(\*)(.*?)\1/g, @@ -199,7 +199,7 @@ Espo.define('view-helper', [], function () { Handlebars.registerHelper('complexText', function (text) { text = Handlebars.Utils.escapeExpression(text || ''); - text = text.replace(self.urlRegex, '$1($2)[$2]'); + text = text.replace(self.urlRegex, '$1[$2]($2)'); self.mdSearch.forEach(function (re, i) { text = text.replace(re, self.mdReplace[i]); diff --git a/client/src/views/email/detail.js b/client/src/views/email/detail.js index b767b7943b..acb74e9746 100644 --- a/client/src/views/email/detail.js +++ b/client/src/views/email/detail.js @@ -189,7 +189,7 @@ Espo.define('views/email/detail', ['views/detail', 'email-helper'], function (De attributes.parentName = this.model.get('parentName'); attributes.parentType = this.model.get('parentType'); - attributes.description = '(' + this.model.get('name') + ')[#Email/view/' + this.model.id + ']'; + attributes.description = '[' + this.model.get('name') + '](#Email/view/' + this.model.id + ')'; attributes.name = this.translate('Email', 'scopeNames') + ': ' + this.model.get('name'); From 74d5a737db0bb49f1a55614b9aa2818e20a0c77b Mon Sep 17 00:00:00 2001 From: yuri Date: Thu, 15 Sep 2016 12:07:26 +0300 Subject: [PATCH 06/13] int/float: isEmpty, isNotEmpty filters --- .../Espo/Resources/i18n/en_US/Global.json | 4 +- client/res/templates/fields/date/search.tpl | 2 +- client/res/templates/fields/int/search.tpl | 6 +- client/src/views/fields/currency-converted.js | 6 +- client/src/views/fields/date.js | 4 +- client/src/views/fields/int.js | 61 ++++++++++++++----- 6 files changed, 60 insertions(+), 23 deletions(-) diff --git a/application/Espo/Resources/i18n/en_US/Global.json b/application/Espo/Resources/i18n/en_US/Global.json index 43efd3cd72..2362949bcf 100644 --- a/application/Espo/Resources/i18n/en_US/Global.json +++ b/application/Espo/Resources/i18n/en_US/Global.json @@ -499,7 +499,9 @@ "lessThan": "Less Than", "greaterThanOrEquals": "Greater Than or Equals", "lessThanOrEquals": "Less Than or Equals", - "between": "Between" + "between": "Between", + "isEmpty": "Is Empty", + "isNotEmpty": "Is Not Empty" }, "autorefreshInterval": { "0": "None", diff --git a/client/res/templates/fields/date/search.tpl b/client/res/templates/fields/date/search.tpl index de23e9a7e1..c177d5ba0e 100644 --- a/client/res/templates/fields/date/search.tpl +++ b/client/res/templates/fields/date/search.tpl @@ -1,6 +1,6 @@
diff --git a/client/res/templates/fields/int/search.tpl b/client/res/templates/fields/int/search.tpl index b4a2514b89..bf5e882c77 100644 --- a/client/res/templates/fields/int/search.tpl +++ b/client/res/templates/fields/int/search.tpl @@ -1,9 +1,9 @@ - - + + diff --git a/client/src/views/fields/currency-converted.js b/client/src/views/fields/currency-converted.js index ace2893abf..7fb73545b1 100644 --- a/client/src/views/fields/currency-converted.js +++ b/client/src/views/fields/currency-converted.js @@ -26,13 +26,13 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -Espo.define('Views.Fields.CurrencyConverted', 'Views.Fields.Float', function (Dep) { +Espo.define('views/fields/currency-converted', 'views/fields/float', function (Dep) { return Dep.extend({ - detailTemplate: 'fields.currency.detail', + detailTemplate: 'fields/currency/detail', - listTemplate: 'fields.currency.detail', + listTemplate: 'fields/currency/detail', data: function () { return _.extend({ diff --git a/client/src/views/fields/date.js b/client/src/views/fields/date.js index b042f35921..f1a31ea76d 100644 --- a/client/src/views/fields/date.js +++ b/client/src/views/fields/date.js @@ -45,11 +45,13 @@ Espo.define('views/fields/date', 'views/fields/base', function (Dep) { }, data: function () { + var data = Dep.prototype.data.call(this); if (this.mode === 'search') { this.searchData.dateValue = this.getDateTime().toDisplayDate(this.searchParams.dateValue); this.searchData.dateValueTo = this.getDateTime().toDisplayDate(this.searchParams.dateValueTo); + data.searchType = this.searchParams.typeFront || this.searchParams.type; } - return Dep.prototype.data.call(this); + return data; }, setupSearch: function () { diff --git a/client/src/views/fields/int.js b/client/src/views/fields/int.js index 776704b170..9b36b59e85 100644 --- a/client/src/views/fields/int.js +++ b/client/src/views/fields/int.js @@ -59,12 +59,24 @@ Espo.define('views/fields/int', 'views/fields/base', function (Dep) { } }, + afterRender: function () { + Dep.prototype.afterRender.call(this); + + if (this.mode == 'search') { + var $searchType = this.$el.find('select.search-type'); + this.handleSearchType($searchType.val()); + } + }, + data: function () { var data = Dep.prototype.data.call(this); if (this.model.get(this.name) !== null && typeof this.model.get(this.name) !== 'undefined') { data.isNotEmpty = true; } + if (this.mode === 'search') { + data.searchType = this.searchParams.typeFront || this.searchParams.type; + } return data; }, @@ -86,19 +98,30 @@ Espo.define('views/fields/int', 'views/fields/base', function (Dep) { }, setupSearch: function () { - this.searchData.typeOptions = ['equals', 'notEquals', 'greaterThan', 'lessThan', 'greaterThanOrEquals', 'lessThanOrEquals', 'between']; + this.searchData.typeOptions = [, 'isNotEmpty', 'isEmpty', 'equals', 'notEquals', 'greaterThan', 'lessThan', 'greaterThanOrEquals', 'lessThanOrEquals', 'between']; this.events = _.extend({ 'change select.search-type': function (e) { - var additional = this.$el.find('input.additional'); - if ($(e.currentTarget).val() == 'between') { - additional.removeClass('hide'); - } else { - additional.addClass('hide'); - } + this.handleSearchType($(e.currentTarget).val()); }, }, this.events || {}); }, + handleSearchType: function (type) { + var $additionalInput = this.$el.find('input.additional'); + var $input = this.$el.find('input[name="'+this.name+'"]'); + + if (type === 'between') { + $additionalInput.removeClass('hidden'); + $input.removeClass('hidden'); + } else if (~['isEmpty', 'isNotEmpty'].indexOf(type)) { + $additionalInput.addClass('hidden'); + $input.addClass('hidden'); + } else { + $additionalInput.addClass('hidden'); + $input.removeClass('hidden'); + } + }, + defineMaxLength: function () { var maxValue = this.model.getFieldParam(this.name, 'max'); if (maxValue) { @@ -193,13 +216,7 @@ Espo.define('views/fields/int', 'views/fields/base', function (Dep) { return false; } - if (type != 'between') { - data = { - type: type, - value: value, - value1: value - }; - } else { + if (type === 'between') { var valueTo = this.parse(this.$el.find('[name="' + this.name + '-additional"]').val()); if (isNaN(valueTo)) { return false; @@ -210,6 +227,22 @@ Espo.define('views/fields/int', 'views/fields/base', function (Dep) { value1: value, value2: valueTo }; + } else if (type == 'isEmpty') { + data = { + type: 'isNull', + typeFront: 'isEmpty' + }; + } else if (type == 'isNotEmpty') { + data = { + type: 'isNotNull', + typeFront: 'isNotEmpty' + }; + } else { + data = { + type: type, + value: value, + value1: value + }; } return data; }, From e823ecc1781b04587b82d61cd280536d2dbfc66f Mon Sep 17 00:00:00 2001 From: yuri Date: Thu, 15 Sep 2016 12:59:06 +0300 Subject: [PATCH 07/13] user: create portal user fix --- client/src/views/user/list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/views/user/list.js b/client/src/views/user/list.js index f7623c2b7c..9cf14a4a48 100644 --- a/client/src/views/user/list.js +++ b/client/src/views/user/list.js @@ -57,7 +57,7 @@ Espo.define('views/user/list', 'views/list', function (Dep) { attributes.contactId = model.id; attributes.contactName = model.get('name'); - if (model.has('accountId')) { + if (model.get('accountId')) { var names = {}; names[model.get('accountId')] = model.get('accountName'); From 6592dfc4daee2ca9a3314dbc0d72a5b629efdfd0 Mon Sep 17 00:00:00 2001 From: yuri Date: Fri, 16 Sep 2016 11:00:19 +0300 Subject: [PATCH 08/13] mass retrive from trash --- .../Espo/Resources/i18n/en_US/Email.json | 3 +- client/src/views/email-folder/list-side.js | 2 +- client/src/views/email/record/list.js | 42 +++++++++++++++---- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/application/Espo/Resources/i18n/en_US/Email.json b/application/Espo/Resources/i18n/en_US/Email.json index 21c399a5b0..8315849391 100644 --- a/application/Espo/Resources/i18n/en_US/Email.json +++ b/application/Espo/Resources/i18n/en_US/Email.json @@ -99,6 +99,7 @@ "markAsImportant": "Mark as Important", "markAsNotImportant": "Unmark Importance", "moveToTrash": "Move to Trash", - "moveToFolder": "Move to Folder" + "moveToFolder": "Move to Folder", + "retrieveFromTrash": "Retrieve from Trash" } } diff --git a/client/src/views/email-folder/list-side.js b/client/src/views/email-folder/list-side.js index ca4ca6b3ba..84f34f9869 100644 --- a/client/src/views/email-folder/list-side.js +++ b/client/src/views/email-folder/list-side.js @@ -88,7 +88,7 @@ Espo.define('views/email-folder/list-side', 'view', function (Dep) { this.manageModelRemoving(model); }, this); - this.listenTo(this.emailCollection, 'retrieving-to-trash', function (id) { + this.listenTo(this.emailCollection, 'retrieving-from-trash', function (id) { var model = this.emailCollection.get(id); if (!model) return; if (this.countsIsBeingLoaded) return; diff --git a/client/src/views/email/record/list.js b/client/src/views/email/record/list.js index b91611af9a..134bff7b59 100644 --- a/client/src/views/email/record/list.js +++ b/client/src/views/email/record/list.js @@ -52,6 +52,7 @@ Espo.define('views/email/record/list', 'views/record/list', function (Dep) { this.massActionList.push('markAsImportant'); this.massActionList.push('markAsNotImportant'); this.massActionList.push('moveToFolder'); + this.massActionList.push('retrieveFromTrash'); }, massActionMarkAsRead: function () { @@ -141,13 +142,16 @@ Espo.define('views/email/record/list', 'views/record/list', function (Dep) { for (var i in this.checkedList) { ids.push(this.checkedList[i]); } - $.ajax({ - url: 'Email/action/moveToTrash', - type: 'POST', - data: JSON.stringify({ - ids: ids - }) - }); + + this.ajaxPostRequest('Email/action/moveToTrash', { + ids: ids + }).then(function () { + Espo.Ui.success(this.translate('Done')); + }.bind(this)); + + if (this.collection.data.folderId === 'trash') { + return; + } ids.forEach(function (id) { this.collection.trigger('moving-to-trash', id); @@ -155,6 +159,28 @@ Espo.define('views/email/record/list', 'views/record/list', function (Dep) { }, this); }, + massActionRetrieveFromTrash: function () { + var ids = []; + for (var i in this.checkedList) { + ids.push(this.checkedList[i]); + } + + this.ajaxPostRequest('Email/action/retrieveFromTrash', { + ids: ids + }).then(function () { + Espo.Ui.success(this.translate('Done')); + }.bind(this)); + + if (this.collection.data.folderId !== 'trash') { + return; + } + + ids.forEach(function (id) { + this.collection.trigger('retrieving-from-trash', id); + this.removeRecordFromList(id); + }, this); + }, + massActionMoveToFolder: function () { var ids = []; for (var i in this.checkedList) { @@ -242,7 +268,7 @@ Espo.define('views/email/record/list', 'views/record/list', function (Dep) { id: id }).then(function () { Espo.Ui.warning(this.translate('Retrieved from Trash', 'labels', 'Email')); - this.collection.trigger('retrieving-to-trash', id); + this.collection.trigger('retrieving-from-trash', id); this.removeRecordFromList(id); }.bind(this)); }, From 7774c12ab20fe62d0c955142ccf37049d053a226 Mon Sep 17 00:00:00 2001 From: yuri Date: Fri, 16 Sep 2016 11:02:14 +0300 Subject: [PATCH 09/13] lang --- application/Espo/Resources/i18n/de_DE/EmailTemplate.json | 2 +- application/Espo/Resources/i18n/en_US/EmailTemplate.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/Espo/Resources/i18n/de_DE/EmailTemplate.json b/application/Espo/Resources/i18n/de_DE/EmailTemplate.json index 95f6dfb2c9..086c5422db 100644 --- a/application/Espo/Resources/i18n/de_DE/EmailTemplate.json +++ b/application/Espo/Resources/i18n/de_DE/EmailTemplate.json @@ -14,7 +14,7 @@ "Info": "Info" }, "messages": { - "infoText": "Verfügbare Variablen:\n\n{optOutUrl} – URL für den Abmeldelink};\n\n{optOutLink} – ein Abmeldelink." + "infoText": "Verfügbare Variablen:\n\n{optOutUrl} – URL für den Abmeldelink;\n\n{optOutLink} – ein Abmeldelink." }, "tooltips": { "oneOff": "Überprüfen Sie, ob Sie die Vorlage nur einmal benutzen z.B. für eine Massenaussendung" diff --git a/application/Espo/Resources/i18n/en_US/EmailTemplate.json b/application/Espo/Resources/i18n/en_US/EmailTemplate.json index 19be833405..2740cdb6e8 100644 --- a/application/Espo/Resources/i18n/en_US/EmailTemplate.json +++ b/application/Espo/Resources/i18n/en_US/EmailTemplate.json @@ -16,7 +16,7 @@ "Info": "Info" }, "messages": { - "infoText": "Available variables:\n\n{optOutUrl} – URL for an unsubsbribe link};\n\n{optOutLink} – an unsubscribe link." + "infoText": "Available variables:\n\n{optOutUrl} – URL for an unsubsbribe link;\n\n{optOutLink} – an unsubscribe link." }, "tooltips": { "oneOff": "Check if you are going to use this template only once. E.g. for Mass Email." From 664b2944711b2802ae26575dca8094150a4be7ef Mon Sep 17 00:00:00 2001 From: yuri Date: Fri, 16 Sep 2016 11:23:44 +0300 Subject: [PATCH 10/13] bool notNull --- application/Espo/Resources/metadata/fields/bool.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/application/Espo/Resources/metadata/fields/bool.json b/application/Espo/Resources/metadata/fields/bool.json index 78685388b9..c939f69286 100644 --- a/application/Espo/Resources/metadata/fields/bool.json +++ b/application/Espo/Resources/metadata/fields/bool.json @@ -9,5 +9,8 @@ "type":"bool" } ], - "filter": true + "filter": true, + "fieldDefs":{ + "notNull": true + } } From 4f1f8d93015791871dc42ed1c04397027e437b81 Mon Sep 17 00:00:00 2001 From: yuri Date: Fri, 16 Sep 2016 14:51:20 +0300 Subject: [PATCH 11/13] lead: created fields filter populate --- .../Resources/metadata/entityDefs/Lead.json | 6 ++- .../src/views/lead/fields/created-contact.js | 47 +++++++++++++++++++ .../views/lead/fields/created-opportunity.js | 47 +++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 client/modules/crm/src/views/lead/fields/created-contact.js create mode 100644 client/modules/crm/src/views/lead/fields/created-opportunity.js diff --git a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Lead.json b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Lead.json index 80b550e20c..f72c17c20e 100644 --- a/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Lead.json +++ b/application/Espo/Modules/Crm/Resources/metadata/entityDefs/Lead.json @@ -130,12 +130,14 @@ "createdContact": { "type": "link", "layoutDetailDisabled": true, - "layoutMassUpdateDisabled": true + "layoutMassUpdateDisabled": true, + "view": "crm:views/lead/fields/created-contact" }, "createdOpportunity": { "type": "link", "layoutDetailDisabled": true, - "layoutMassUpdateDisabled": true + "layoutMassUpdateDisabled": true, + "view": "crm:views/lead/fields/created-opportunity" }, "targetLists": { "type": "linkMultiple", diff --git a/client/modules/crm/src/views/lead/fields/created-contact.js b/client/modules/crm/src/views/lead/fields/created-contact.js new file mode 100644 index 0000000000..5a657f0b73 --- /dev/null +++ b/client/modules/crm/src/views/lead/fields/created-contact.js @@ -0,0 +1,47 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko + * Website: http://www.espocrm.com + * + * EspoCRM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EspoCRM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EspoCRM. If not, see http://www.gnu.org/licenses/. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU General Public License version 3. + * + * In accordance with Section 7(b) of the GNU General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +Espo.define('crm:views/lead/fields/created-contact', 'views/fields/link', function (Dep) { + + return Dep.extend({ + + getSelectFilters: function () { + if (this.model.get('createdAccountId')) { + return { + 'account': { + type: 'equals', + field: 'accountId', + value: this.model.get('createdAccountId'), + valueName: this.model.get('createdAccountName') + } + }; + } + }, + }); + +}); diff --git a/client/modules/crm/src/views/lead/fields/created-opportunity.js b/client/modules/crm/src/views/lead/fields/created-opportunity.js new file mode 100644 index 0000000000..2ee92b7cd6 --- /dev/null +++ b/client/modules/crm/src/views/lead/fields/created-opportunity.js @@ -0,0 +1,47 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko + * Website: http://www.espocrm.com + * + * EspoCRM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EspoCRM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EspoCRM. If not, see http://www.gnu.org/licenses/. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU General Public License version 3. + * + * In accordance with Section 7(b) of the GNU General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +Espo.define('crm:views/lead/fields/created-opportunity', 'views/fields/link', function (Dep) { + + return Dep.extend({ + + getSelectFilters: function () { + if (this.model.get('createdAccountId')) { + return { + 'account': { + type: 'equals', + field: 'accountId', + value: this.model.get('createdAccountId'), + valueName: this.model.get('createdAccountName') + } + }; + } + }, + }); + +}); From 87340e29e8a54aafd7ee6f91bddfed55975d48b5 Mon Sep 17 00:00:00 2001 From: yuri Date: Fri, 16 Sep 2016 15:38:21 +0300 Subject: [PATCH 12/13] base field: search data --- client/src/views/fields/base.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/client/src/views/fields/base.js b/client/src/views/fields/base.js index c8ebf447f3..57bd0e8518 100644 --- a/client/src/views/fields/base.js +++ b/client/src/views/fields/base.js @@ -157,6 +157,8 @@ Espo.define('views/fields/base', 'view', function (Dep) { if (this.mode === 'search') { data.searchParams = this.searchParams; data.searchData = this.searchData; + data.searchValues = this.getSearchValues(); + data.searchType = this.getSearchType(); } return data; }, @@ -298,6 +300,14 @@ Espo.define('views/fields/base', 'view', function (Dep) { } }, + getSearchValues: function () { + return (this.searchParams.data || {}).values || {}; + }, + + getSearchType: function () { + return (this.searchParams.data || {}).type || this.searchParams.type; + }, + initInlineEdit: function () { var $cell = this.getCellElement(); var $editLink = $(''); From d3b1114b1eb16e6c32f74d6bc882f9d1cbd0588f Mon Sep 17 00:00:00 2001 From: yuri Date: Fri, 16 Sep 2016 16:38:10 +0300 Subject: [PATCH 13/13] filters refactor --- application/Espo/Core/SelectManagers/Base.php | 127 +++++++++++------- .../Modules/Crm/SelectManagers/Meeting.php | 2 +- .../Espo/Modules/Crm/SelectManagers/Task.php | 24 ++-- client/res/templates/fields/date/search.tpl | 2 +- client/res/templates/fields/int/search.tpl | 2 +- .../templates/fields/link-parent/search.tpl | 2 +- client/res/templates/fields/link/search.tpl | 4 +- client/res/templates/fields/user/search.tpl | 2 +- client/src/search-manager.js | 15 ++- client/src/views/fields/base.js | 13 +- client/src/views/fields/date.js | 14 +- client/src/views/fields/datetime.js | 2 +- client/src/views/fields/int.js | 10 +- client/src/views/fields/link-parent.js | 29 ++-- client/src/views/fields/link.js | 30 +++-- client/src/views/fields/user.js | 10 +- 16 files changed, 186 insertions(+), 102 deletions(-) diff --git a/application/Espo/Core/SelectManagers/Base.php b/application/Espo/Core/SelectManagers/Base.php index 614296bb82..de9e598cd2 100644 --- a/application/Espo/Core/SelectManagers/Base.php +++ b/application/Espo/Core/SelectManagers/Base.php @@ -210,8 +210,17 @@ class Base if (!empty($item['value'])) { $methodName = 'apply' . ucfirst($type); - if (method_exists($this, $methodName)) {; - $this->$methodName($item['field'], $item['value'], $result); + if (method_exists($this, $methodName)) { + $attribute = null; + if (isset($item['field'])) { + $attribute = $item['field']; + } + if (isset($item['attribute'])) { + $attribute = $item['attribute']; + } + if ($attribute) { + $this->$methodName($attribute, $item['value'], $result); + } } } } @@ -689,13 +698,20 @@ class Base protected function checkWhere($where) { foreach ($where as $w) { + $attribute = null; if (isset($w['field'])) { + $attribute = $w['field']; + } + if (isset($w['attribute'])) { + $attribute = $w['attribute']; + } + if ($attribute) { if (isset($w['type']) && $w['type'] === 'linkedWith') { - if (in_array($w['field'], $this->getAcl()->getScopeForbiddenFieldList($this->getEntityType()))) { + if (in_array($attribute, $this->getAcl()->getScopeForbiddenFieldList($this->getEntityType()))) { throw new Forbidden(); } } else { - if (in_array($w['field'], $this->getAcl()->getScopeForbiddenAttributeList($this->getEntityType()))) { + if (in_array($attribute, $this->getAcl()->getScopeForbiddenAttributeList($this->getEntityType()))) { throw new Forbidden(); } } @@ -728,7 +744,15 @@ class Base $value = null; $timeZone = 'UTC'; - if (empty($item['field'])) { + $attribute = null; + if (isset($item['field'])) { + $attribute = $item['field']; + } + if (isset($item['attribute'])) { + $attribute = $item['attribute']; + } + + if (!$attribute) { return null; } if (empty($item['type'])) { @@ -741,14 +765,13 @@ class Base $timeZone = $item['timeZone']; } $type = $item['type']; - $field = $item['field']; if (empty($value) && in_array($type, array('on', 'before', 'after'))) { return null; } $where = array(); - $where['field'] = $field; + $where['attribute'] = $attribute; $dt = new \DateTime('now', new \DateTimeZone($timeZone)); @@ -875,8 +898,16 @@ class Base { $part = array(); - if (!empty($item['field']) && !empty($item['type'])) { - $methodName = 'getWherePart' . ucfirst($item['field']) . ucfirst($item['type']); + $attribute = null; + if (!empty($item['field'])) { // for backward compatibility + $attribute = $item['field']; + } + if (!empty($item['attribute'])) { + $attribute = $item['attribute']; + } + + if (!empty($attribute) && !empty($item['type'])) { + $methodName = 'getWherePart' . ucfirst($attribute) . ucfirst($item['type']); if (method_exists($this, $methodName)) { $value = null; if (!empty($item['value'])) { @@ -909,74 +940,74 @@ class Base } break; case 'like': - $part[$item['field'] . '*'] = $item['value']; + $part[$attribute . '*'] = $item['value']; break; case 'equals': case 'on': - $part[$item['field'] . '='] = $item['value']; + $part[$attribute . '='] = $item['value']; break; case 'startsWith': - $part[$item['field'] . '*'] = $item['value'] . '%'; + $part[$attribute . '*'] = $item['value'] . '%'; break; case 'endsWith': - $part[$item['field'] . '*'] = '%' . $item['value']; + $part[$attribute . '*'] = '%' . $item['value']; break; case 'contains': - $part[$item['field'] . '*'] = '%' . $item['value'] . '%'; + $part[$attribute . '*'] = '%' . $item['value'] . '%'; break; case 'notEquals': case 'notOn': - $part[$item['field'] . '!='] = $item['value']; + $part[$attribute . '!='] = $item['value']; break; case 'greaterThan': case 'after': - $part[$item['field'] . '>'] = $item['value']; + $part[$attribute . '>'] = $item['value']; break; case 'lessThan': case 'before': - $part[$item['field'] . '<'] = $item['value']; + $part[$attribute . '<'] = $item['value']; break; case 'greaterThanOrEquals': - $part[$item['field'] . '>='] = $item['value']; + $part[$attribute . '>='] = $item['value']; break; case 'lessThanOrEquals': - $part[$item['field'] . '<'] = $item['value']; + $part[$attribute . '<'] = $item['value']; break; case 'in': - $part[$item['field'] . '='] = $item['value']; + $part[$attribute . '='] = $item['value']; break; case 'notIn': - $part[$item['field'] . '!='] = $item['value']; + $part[$attribute . '!='] = $item['value']; break; case 'isNull': - $part[$item['field'] . '='] = null; + $part[$attribute . '='] = null; break; case 'isNotNull': case 'ever': - $part[$item['field'] . '!='] = null; + $part[$attribute . '!='] = null; break; case 'isTrue': - $part[$item['field'] . '='] = true; + $part[$attribute . '='] = true; break; case 'isFalse': - $part[$item['field'] . '='] = false; + $part[$attribute . '='] = false; break; case 'today': - $part[$item['field'] . '='] = date('Y-m-d'); + $part[$attribute . '='] = date('Y-m-d'); break; case 'past': - $part[$item['field'] . '<'] = date('Y-m-d'); + $part[$attribute . '<'] = date('Y-m-d'); break; case 'future': - $part[$item['field'] . '>='] = date('Y-m-d'); + $part[$attribute . '>='] = date('Y-m-d'); break; case 'lastSevenDays': $dt1 = new \DateTime(); $dt2 = clone $dt1; $dt2->modify('-7 days'); $part['AND'] = array( - $item['field'] . '>=' => $dt2->format('Y-m-d'), - $item['field'] . '<=' => $dt1->format('Y-m-d'), + $attribute . '>=' => $dt2->format('Y-m-d'), + $attribute . '<=' => $dt1->format('Y-m-d'), ); break; case 'lastXDays': @@ -986,8 +1017,8 @@ class Base $dt2->modify('-'.$number.' days'); $part['AND'] = array( - $item['field'] . '>=' => $dt2->format('Y-m-d'), - $item['field'] . '<=' => $dt1->format('Y-m-d'), + $attribute . '>=' => $dt2->format('Y-m-d'), + $attribute . '<=' => $dt1->format('Y-m-d'), ); break; case 'nextXDays': @@ -996,22 +1027,22 @@ class Base $number = strval(intval($item['value'])); $dt2->modify('+'.$number.' days'); $part['AND'] = array( - $item['field'] . '>=' => $dt1->format('Y-m-d'), - $item['field'] . '<=' => $dt2->format('Y-m-d'), + $attribute . '>=' => $dt1->format('Y-m-d'), + $attribute . '<=' => $dt2->format('Y-m-d'), ); break; case 'currentMonth': $dt = new \DateTime(); $part['AND'] = array( - $item['field'] . '>=' => $dt->modify('first day of this month')->format('Y-m-d'), - $item['field'] . '<' => $dt->add(new \DateInterval('P1M'))->format('Y-m-d'), + $attribute . '>=' => $dt->modify('first day of this month')->format('Y-m-d'), + $attribute . '<' => $dt->add(new \DateInterval('P1M'))->format('Y-m-d'), ); break; case 'lastMonth': $dt = new \DateTime(); $part['AND'] = array( - $item['field'] . '>=' => $dt->modify('first day of last month')->format('Y-m-d'), - $item['field'] . '<' => $dt->add(new \DateInterval('P1M'))->format('Y-m-d'), + $attribute . '>=' => $dt->modify('first day of last month')->format('Y-m-d'), + $attribute . '<' => $dt->add(new \DateInterval('P1M'))->format('Y-m-d'), ); break; case 'currentQuarter': @@ -1019,8 +1050,8 @@ class Base $quarter = ceil($dt->format('m') / 3); $dt->modify('first day of January this year'); $part['AND'] = array( - $item['field'] . '>=' => $dt->add(new \DateInterval('P'.(($quarter - 1) * 3).'M'))->format('Y-m-d'), - $item['field'] . '<' => $dt->add(new \DateInterval('P3M'))->format('Y-m-d'), + $attribute . '>=' => $dt->add(new \DateInterval('P'.(($quarter - 1) * 3).'M'))->format('Y-m-d'), + $attribute . '<' => $dt->add(new \DateInterval('P3M'))->format('Y-m-d'), ); break; case 'lastQuarter': @@ -1033,29 +1064,29 @@ class Base $dt->sub('P1Y'); } $part['AND'] = array( - $item['field'] . '>=' => $dt->add(new \DateInterval('P'.(($quarter - 1) * 3).'M'))->format('Y-m-d'), - $item['field'] . '<' => $dt->add(new \DateInterval('P3M'))->format('Y-m-d'), + $attribute . '>=' => $dt->add(new \DateInterval('P'.(($quarter - 1) * 3).'M'))->format('Y-m-d'), + $attribute . '<' => $dt->add(new \DateInterval('P3M'))->format('Y-m-d'), ); break; case 'currentYear': $dt = new \DateTime(); $part['AND'] = array( - $item['field'] . '>=' => $dt->modify('first day of January this year')->format('Y-m-d'), - $item['field'] . '<' => $dt->add(new \DateInterval('P1Y'))->format('Y-m-d'), + $attribute . '>=' => $dt->modify('first day of January this year')->format('Y-m-d'), + $attribute . '<' => $dt->add(new \DateInterval('P1Y'))->format('Y-m-d'), ); break; case 'lastYear': $dt = new \DateTime(); $part['AND'] = array( - $item['field'] . '>=' => $dt->modify('first day of January last year')->format('Y-m-d'), - $item['field'] . '<' => $dt->add(new \DateInterval('P1Y'))->format('Y-m-d'), + $attribute . '>=' => $dt->modify('first day of January last year')->format('Y-m-d'), + $attribute . '<' => $dt->add(new \DateInterval('P1Y'))->format('Y-m-d'), ); break; case 'between': if (is_array($item['value'])) { $part['AND'] = array( - $item['field'] . '>=' => $item['value'][0], - $item['field'] . '<=' => $item['value'][1], + $attribute . '>=' => $item['value'][0], + $attribute . '<=' => $item['value'][1], ); } break; diff --git a/application/Espo/Modules/Crm/SelectManagers/Meeting.php b/application/Espo/Modules/Crm/SelectManagers/Meeting.php index 97f4bc8c92..9722a50bbf 100644 --- a/application/Espo/Modules/Crm/SelectManagers/Meeting.php +++ b/application/Espo/Modules/Crm/SelectManagers/Meeting.php @@ -87,7 +87,7 @@ class Meeting extends \Espo\Core\SelectManagers\Base { $result['whereClause'][] = $this->convertDateTimeWhere(array( 'type' => 'today', - 'field' => 'dateStart', + 'attribute' => 'dateStart', 'timeZone' => $this->getUserTimeZone() )); } diff --git a/application/Espo/Modules/Crm/SelectManagers/Task.php b/application/Espo/Modules/Crm/SelectManagers/Task.php index e62d63398b..0b50bdc894 100644 --- a/application/Espo/Modules/Crm/SelectManagers/Task.php +++ b/application/Espo/Modules/Crm/SelectManagers/Task.php @@ -64,12 +64,12 @@ class Task extends \Espo\Core\SelectManagers\Base 'OR' => array( $this->convertDateTimeWhere(array( 'type' => 'past', - 'field' => 'dateStart', + 'attribute' => 'dateStart', 'timeZone' => $this->getUserTimeZone() )), $this->convertDateTimeWhere(array( 'type' => 'today', - 'field' => 'dateStart', + 'attribute' => 'dateStart', 'timeZone' => $this->getUserTimeZone() )) ) @@ -91,7 +91,7 @@ class Task extends \Espo\Core\SelectManagers\Base $result['whereClause'][] = [ $this->convertDateTimeWhere(array( 'type' => 'past', - 'field' => 'dateEnd', + 'attribute' => 'dateEnd', 'timeZone' => $this->getUserTimeZone() )), [ @@ -106,7 +106,7 @@ class Task extends \Espo\Core\SelectManagers\Base { $result['whereClause'][] = $this->convertDateTimeWhere(array( 'type' => 'today', - 'field' => 'dateEnd', + 'attribute' => 'dateEnd', 'timeZone' => $this->getUserTimeZone() )); } @@ -118,16 +118,22 @@ class Task extends \Espo\Core\SelectManagers\Base if (empty($result)) { return null; } - $field = $item['field']; + $attribute = null; + if (!empty($item['field'])) { // for backward compatibility + $attribute = $item['field']; + } + if (!empty($item['attribute'])) { + $attribute = $item['attribute']; + } - if ($field != 'dateStart' && $field != 'dateEnd') { + if ($attribute != 'dateStart' && $attribute != 'dateEnd') { return $result; } - $fieldDate = $field . 'Date'; + $attributeDate = $attribute . 'Date'; $dateItem = array( - 'field' => $fieldDate, + 'attribute' => $attributeDate, 'type' => $item['type'] ); if (!empty($item['value'])) { @@ -138,7 +144,7 @@ class Task extends \Espo\Core\SelectManagers\Base 'OR' => array( 'AND' => [ $result, - $fieldDate . '=' => null + $attributeDate . '=' => null ], $this->getWherePart($dateItem) ) diff --git a/client/res/templates/fields/date/search.tpl b/client/res/templates/fields/date/search.tpl index c177d5ba0e..d6a7681c08 100644 --- a/client/res/templates/fields/date/search.tpl +++ b/client/res/templates/fields/date/search.tpl @@ -1,6 +1,6 @@
diff --git a/client/res/templates/fields/int/search.tpl b/client/res/templates/fields/int/search.tpl index bf5e882c77..c4baa8e443 100644 --- a/client/res/templates/fields/int/search.tpl +++ b/client/res/templates/fields/int/search.tpl @@ -1,6 +1,6 @@ diff --git a/client/res/templates/fields/link-parent/search.tpl b/client/res/templates/fields/link-parent/search.tpl index baf1fc77a0..3e7580789f 100644 --- a/client/res/templates/fields/link-parent/search.tpl +++ b/client/res/templates/fields/link-parent/search.tpl @@ -1,5 +1,5 @@
- {{options searchData.typeOptions searchParams.typeFront field='searchRanges'}} + {{options searchTypeList searchType field='searchRanges'}}
@@ -23,5 +23,3 @@
- - diff --git a/client/res/templates/fields/user/search.tpl b/client/res/templates/fields/user/search.tpl index d372b13a71..645337cdbe 100644 --- a/client/res/templates/fields/user/search.tpl +++ b/client/res/templates/fields/user/search.tpl @@ -1,5 +1,5 @@
diff --git a/client/src/search-manager.js b/client/src/search-manager.js index 08037d8528..d22c9b61f2 100644 --- a/client/src/search-manager.js +++ b/client/src/search-manager.js @@ -122,7 +122,7 @@ Espo.define('search-manager', [], function () { }, getWherePart: function (name, defs) { - var field = name; + var attribute = name; if ('where' in defs) { return defs.where; @@ -140,13 +140,16 @@ Espo.define('search-manager', [], function () { value: a }; } - if ('field' in defs) { - field = defs.field; + if ('field' in defs) { // for backward compatibility + attribute = defs.field; + } + if ('attribute' in defs) { + attribute = defs.attribute; } if (defs.dateTime) { return { type: type, - field: field, + attribute: attribute, value: defs.value, dateTime: true, timeZone: this.dateTime.timeZone || 'UTC' @@ -155,8 +158,8 @@ Espo.define('search-manager', [], function () { value = defs.value; return { type: type, - field: field, - value: value, + attribute: attribute, + value: value }; } } diff --git a/client/src/views/fields/base.js b/client/src/views/fields/base.js index 57bd0e8518..0571b29c5a 100644 --- a/client/src/views/fields/base.js +++ b/client/src/views/fields/base.js @@ -159,6 +159,7 @@ Espo.define('views/fields/base', 'view', function (Dep) { data.searchData = this.searchData; data.searchValues = this.getSearchValues(); data.searchType = this.getSearchType(); + data.searchTypeList = this.getSearchTypeList(); } return data; }, @@ -300,12 +301,20 @@ Espo.define('views/fields/base', 'view', function (Dep) { } }, + getSearchParamsData: function () { + return this.searchParams.data || {}; + }, + getSearchValues: function () { - return (this.searchParams.data || {}).values || {}; + return this.getSearchParamsData().values || {}; }, getSearchType: function () { - return (this.searchParams.data || {}).type || this.searchParams.type; + return this.getSearchParamsData().type || this.searchParams.type; + }, + + getSearchTypeList: function () { + return this.searchTypeList; }, initInlineEdit: function () { diff --git a/client/src/views/fields/date.js b/client/src/views/fields/date.js index f1a31ea76d..1dd02ed79e 100644 --- a/client/src/views/fields/date.js +++ b/client/src/views/fields/date.js @@ -38,7 +38,7 @@ Espo.define('views/fields/date', 'views/fields/base', function (Dep) { validations: ['required', 'date', 'after', 'before'], - searchTypeOptions: ['lastSevenDays', 'ever', 'isEmpty', 'currentMonth', 'lastMonth', 'currentQuarter', 'lastQuarter', 'currentYear', 'lastYear', 'today', 'past', 'future', 'lastXDays', 'nextXDays', 'on', 'after', 'before', 'between'], + searchTypeList: ['lastSevenDays', 'ever', 'isEmpty', 'currentMonth', 'lastMonth', 'currentQuarter', 'lastQuarter', 'currentYear', 'lastYear', 'today', 'past', 'future', 'lastXDays', 'nextXDays', 'on', 'after', 'before', 'between'], setup: function () { Dep.prototype.setup.call(this); @@ -49,13 +49,11 @@ Espo.define('views/fields/date', 'views/fields/base', function (Dep) { if (this.mode === 'search') { this.searchData.dateValue = this.getDateTime().toDisplayDate(this.searchParams.dateValue); this.searchData.dateValueTo = this.getDateTime().toDisplayDate(this.searchParams.dateValueTo); - data.searchType = this.searchParams.typeFront || this.searchParams.type; } return data; }, setupSearch: function () { - this.searchData.typeOptions = this.searchTypeOptions; this.events = _.extend({ 'change select.search-type': function (e) { var type = $(e.currentTarget).val(); @@ -250,8 +248,10 @@ Espo.define('views/fields/date', 'views/fields/base', function (Dep) { }; } else if (type === 'isEmpty') { data = { - typeFront: type, - type: 'isNull' + type: 'isNull', + data: { + type: type + } } } else { data = { @@ -261,6 +261,10 @@ Espo.define('views/fields/date', 'views/fields/base', function (Dep) { return data; }, + getSearchType: function () { + return this.getSearchParamsData().type || this.searchParams.typeFront || this.searchParams.type; + }, + validateRequired: function () { if (this.isRequired()) { if (this.model.get(this.name) === null) { diff --git a/client/src/views/fields/datetime.js b/client/src/views/fields/datetime.js index a0495166ca..60aa771f8b 100644 --- a/client/src/views/fields/datetime.js +++ b/client/src/views/fields/datetime.js @@ -36,7 +36,7 @@ Espo.define('views/fields/datetime', 'views/fields/date', function (Dep) { validations: ['required', 'datetime', 'after', 'before'], - searchTypeOptions: ['lastSevenDays', 'ever', 'isEmpty', 'currentMonth', 'lastMonth', 'currentQuarter', 'lastQuarter', 'currentYear', 'lastYear', 'today', 'past', 'future', 'lastXDays', 'nextXDays', 'on', 'after', 'before', 'between'], + searchTypeList: ['lastSevenDays', 'ever', 'isEmpty', 'currentMonth', 'lastMonth', 'currentQuarter', 'lastQuarter', 'currentYear', 'lastYear', 'today', 'past', 'future', 'lastXDays', 'nextXDays', 'on', 'after', 'before', 'between'], timeFormatMap: { 'HH:mm': 'H:i', diff --git a/client/src/views/fields/int.js b/client/src/views/fields/int.js index 9b36b59e85..f4703c8e5f 100644 --- a/client/src/views/fields/int.js +++ b/client/src/views/fields/int.js @@ -42,6 +42,8 @@ Espo.define('views/fields/int', 'views/fields/base', function (Dep) { thousandSeparator: ',', + searchTypeList: ['isNotEmpty', 'isEmpty', 'equals', 'notEquals', 'greaterThan', 'lessThan', 'greaterThanOrEquals', 'lessThanOrEquals', 'between'], + setup: function () { Dep.prototype.setup.call(this); this.defineMaxLength(); @@ -74,9 +76,6 @@ Espo.define('views/fields/int', 'views/fields/base', function (Dep) { if (this.model.get(this.name) !== null && typeof this.model.get(this.name) !== 'undefined') { data.isNotEmpty = true; } - if (this.mode === 'search') { - data.searchType = this.searchParams.typeFront || this.searchParams.type; - } return data; }, @@ -98,7 +97,6 @@ Espo.define('views/fields/int', 'views/fields/base', function (Dep) { }, setupSearch: function () { - this.searchData.typeOptions = [, 'isNotEmpty', 'isEmpty', 'equals', 'notEquals', 'greaterThan', 'lessThan', 'greaterThanOrEquals', 'lessThanOrEquals', 'between']; this.events = _.extend({ 'change select.search-type': function (e) { this.handleSearchType($(e.currentTarget).val()); @@ -247,6 +245,10 @@ Espo.define('views/fields/int', 'views/fields/base', function (Dep) { return data; }, + getSearchType: function () { + return this.searchParams.typeFront || this.searchParams.type; + } + }); }); diff --git a/client/src/views/fields/link-parent.js b/client/src/views/fields/link-parent.js index 61c28b890d..2abb72cde3 100644 --- a/client/src/views/fields/link-parent.js +++ b/client/src/views/fields/link-parent.js @@ -54,6 +54,8 @@ Espo.define('views/fields/link-parent', 'views/fields/base', function (Dep) { createDisabled: false, + searchTypeList: ['is', 'isEmpty', 'isNotEmpty'], + data: function () { return _.extend({ idName: this.idName, @@ -142,7 +144,6 @@ Espo.define('views/fields/link-parent', 'views/fields/base', function (Dep) { }, setupSearch: function () { - this.searchData.typeOptions = ['is', 'isEmpty', 'isNotEmpty']; this.events = _.extend({ 'change select.search-type': function (e) { @@ -301,15 +302,19 @@ Espo.define('views/fields/link-parent', 'views/fields/base', function (Dep) { if (type == 'isEmpty') { var data = { type: 'isNull', - typeFront: type, - field: this.idName + field: this.idName, + data: { + type: type + } }; return data; } else if (type == 'isNotEmpty') { var data = { type: 'isNotNull', - typeFront: type, - field: this.idName + field: this.idName, + data: { + type: type + } }; return data; } @@ -326,7 +331,6 @@ Espo.define('views/fields/link-parent', 'views/fields/base', function (Dep) { var data; if (entityId) { data = { - frontType: 'is', type: 'and', field: this.idName, @@ -345,10 +349,12 @@ Espo.define('views/fields/link-parent', 'views/fields/base', function (Dep) { valueId: entityId, valueName: entityName, valueType: entityType, + data: { + type: 'is' + } }; } else { data = { - frontType: 'is', type: 'and', field: this.idName, value: [ @@ -362,10 +368,17 @@ Espo.define('views/fields/link-parent', 'views/fields/base', function (Dep) { value: entityType, } ], - valueType: entityType + valueType: entityType, + data: { + type: 'is' + } }; } return data; + }, + + getSearchType: function () { + return this.getSearchParamsData().type || this.searchParams.typeFront; } }); }); diff --git a/client/src/views/fields/link.js b/client/src/views/fields/link.js index cfe5507641..cdb1392ee6 100644 --- a/client/src/views/fields/link.js +++ b/client/src/views/fields/link.js @@ -54,6 +54,8 @@ Espo.define('views/fields/link', 'views/fields/base', function (Dep) { createDisabled: false, + searchTypeList: ['is', 'isEmpty', 'isNotEmpty', 'isOneOf'], + data: function () { return _.extend({ idName: this.idName, @@ -161,7 +163,6 @@ Espo.define('views/fields/link', 'views/fields/base', function (Dep) { }, setupSearch: function () { - this.searchData.typeOptions = ['is', 'isEmpty', 'isNotEmpty', 'isOneOf']; this.searchData.oneOfIdList = this.searchParams.oneOfIdList || []; this.searchData.oneOfNameHash = this.searchParams.oneOfNameHash || {}; @@ -395,25 +396,31 @@ Espo.define('views/fields/link', 'views/fields/base', function (Dep) { if (type == 'isEmpty') { var data = { type: 'isNull', - typeFront: type, - field: this.idName + field: this.idName, + data: { + type: type + } }; return data; } else if (type == 'isNotEmpty') { var data = { type: 'isNotNull', - typeFront: type, - field: this.idName + field: this.idName, + data: { + type: type + } }; return data; } else if (type == 'isOneOf') { var data = { type: 'in', - typeFront: type, field: this.idName, value: this.searchData.oneOfIdList, oneOfIdList: this.searchData.oneOfIdList, - oneOfNameHash: this.searchData.oneOfNameHash + oneOfNameHash: this.searchData.oneOfNameHash, + data: { + type: type + } }; return data; @@ -423,14 +430,21 @@ Espo.define('views/fields/link', 'views/fields/base', function (Dep) { } var data = { type: 'equals', - typeFront: type, field: this.idName, value: value, valueName: this.$el.find('[name="' + this.nameName + '"]').val(), + data: { + type: type + } }; return data; } + }, + + getSearchType: function () { + return this.getSearchParamsData().type || this.searchParams.typeFront || this.searchParams.frontType; } + }); }); diff --git a/client/src/views/fields/user.js b/client/src/views/fields/user.js index 1c86c2ef86..fe84e397e5 100644 --- a/client/src/views/fields/user.js +++ b/client/src/views/fields/user.js @@ -35,7 +35,9 @@ Espo.define('views/fields/user', 'views/fields/link', function (Dep) { setupSearch: function () { Dep.prototype.setupSearch.call(this); - this.searchData.typeOptions.push('isFromTeams'); + this.searchTypeList = Espo.Utils.clone(this.searchTypeList); + this.searchTypeList.push('isFromTeams'); + this.searchData.teamIdList = this.searchParams.teamIdList || []; this.searchData.teamNameHash = this.searchParams.teamNameHash || {}; @@ -177,11 +179,13 @@ Espo.define('views/fields/user', 'views/fields/link', function (Dep) { if (type == 'isFromTeams') { var data = { type: 'isUserFromTeams', - typeFront: type, field: this.name, value: this.searchData.teamIdList, teamIdList: this.searchData.teamIdList, - teamNameHash: this.searchData.teamNameHash + teamNameHash: this.searchData.teamNameHash, + data: { + type: type + } }; return data; }