Merge branch 'master' of ssh://172.20.0.1/var/git/espo/backend

This commit is contained in:
Taras Machyshyn
2016-09-20 11:47:40 +03:00
45 changed files with 431 additions and 158 deletions
+79 -48
View File
@@ -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;
@@ -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",
@@ -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",
@@ -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()
));
}
@@ -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)
)
+2 -2
View File
@@ -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) {
+5 -5
View File
@@ -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:
@@ -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,
+10 -2
View File
@@ -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)) {
@@ -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 <strong>@username</strong> pro zmínění uživatelů v příspěvku.\n\nDostupná syntaxe:\n`<code>code</code>`\n**<strong>tučný text</strong>**\n*<em>kurzíva</em>*\n~<del>smazaný text</del>~\n> citace\n(url)[link]"
"streamPostInfo": "Napište <strong>@username</strong> pro zmínění uživatelů v příspěvku.\n\nDostupná syntaxe:\n`<code>code</code>`\n**<strong>tučný text</strong>**\n*<em>kurzíva</em>*\n~<del>smazaný text</del>~\n> citace\n[text](url)"
},
"boolFilters": {
"onlyMy": "Pouze moje",
@@ -14,7 +14,7 @@
"Info": "Info"
},
"messages": {
"infoText": "Verfügbare Variablen:\n\n{optOutUrl} &#8211; URL für den Abmeldelink};\n\n{optOutLink} &#8211; ein Abmeldelink."
"infoText": "Verfügbare Variablen:\n\n{optOutUrl} &#8211; URL für den Abmeldelink;\n\n{optOutLink} &#8211; ein Abmeldelink."
},
"tooltips": {
"oneOff": "Überprüfen Sie, ob Sie die Vorlage nur einmal benutzen z.B. für eine Massenaussendung"
@@ -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 <strong>@username</strong> um Benutzer in der Notiz hervorzuheben.\n\nVerfügbare Syntax:\n`<code>Code</code>`\n**<strong>fetter Text</strong>**\n*<em>Hervorgehobener Text</em>*\n~<del>Durchgestrichen</del>~\n> blockquote\n(url)[link]",
"streamPostInfo": "Schreiben Sie <strong>@username</strong> um Benutzer in der Notiz hervorzuheben.\n\nVerfügbare Syntax:\n`<code>Code</code>`\n**<strong>fetter Text</strong>**\n*<em>Hervorgehobener Text</em>*\n~<del>Durchgestrichen</del>~\n> blockquote\n[text](url)",
"writeYourCommentHere": "Notiz hier einfügen",
"writeMessageToUser": "Nachricht an {user} schreiben",
"writeMessageToSelf": "Nachricht an sich selbst schreiben",
@@ -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"
}
}
@@ -16,7 +16,7 @@
"Info": "Info"
},
"messages": {
"infoText": "Available variables:\n\n{optOutUrl} &#8211; URL for an unsubsbribe link};\n\n{optOutLink} &#8211; an unsubscribe link."
"infoText": "Available variables:\n\n{optOutUrl} &#8211; URL for an unsubsbribe link;\n\n{optOutLink} &#8211; an unsubscribe link."
},
"tooltips": {
"oneOff": "Check if you are going to use this template only once. E.g. for Mass Email."
@@ -219,7 +219,7 @@
"massRemoveResultSingle": "{count} record has been removed",
"noRecordsRemoved": "No records were removed",
"clickToRefresh": "Click to refresh",
"streamPostInfo": "Type <strong>@username</strong> to mention users in the post.\n\nAvailable markdown syntax:\n`<code>code</code>`\n**<strong>strong text</strong>**\n*<em>emphasized text</em>*\n~<del>deleted text</del>~\n> blockquote\n(link name)[url]",
"streamPostInfo": "Type <strong>@username</strong> to mention users in the post.\n\nAvailable markdown syntax:\n`<code>code</code>`\n**<strong>strong text</strong>**\n*<em>emphasized text</em>*\n~<del>deleted text</del>~\n> blockquote\n[link text](url)",
"writeYourCommentHere": "Write your comment here",
"writeMessageToUser": "Write a message to {user}",
"writeMessageToSelf": "Write a message on your stream",
@@ -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",
@@ -498,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",
@@ -218,7 +218,7 @@
"massRemoveResultSingle": "{count} registro se ha eliminado",
"noRecordsRemoved": "No hay registros se eliminaron",
"clickToRefresh": "Clic aqui para actualizar",
"streamPostInfo": "Escriba <strong>@username</strong> para mencionar usuarios en el comentario.\n\nLa sintaxis markdown disponible es:\n\n`<code>código</code>`\n**<strong>texto en negritas</strong>**\n*<em>un texto con énfasis</em>*\n~<del>el texto eliminado</del>~\n> Citar bloque\n(nombre del enlace)[url]",
"streamPostInfo": "Escriba <strong>@username</strong> para mencionar usuarios en el comentario.\n\nLa sintaxis markdown disponible es:\n\n`<code>código</code>`\n**<strong>texto en negritas</strong>**\n*<em>un texto con énfasis</em>*\n~<del>el texto eliminado</del>~\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",
@@ -177,7 +177,7 @@
"massRemoveResultSingle": "{count} enregistrement a été supprimé",
"noRecordsRemoved": "Aucun enregistrement n'a été trouvé",
"clickToRefresh": "Cliquer pour rafraîchir",
"streamPostInfo": "Taper <strong>@utilisateur</strong> pour mentionner des utilisateurs dans votre message.\n\nSyntaxe disponible:\n`<code>code</code>`\n**<strong>gras</strong>**\n*<em>italique</em>*\n~<del>texte barré</del>~\n> bloc de citation\n(url)[lien]",
"streamPostInfo": "Taper <strong>@utilisateur</strong> pour mentionner des utilisateurs dans votre message.\n\nSyntaxe disponible:\n`<code>code</code>`\n**<strong>gras</strong>**\n*<em>italique</em>*\n~<del>texte barré</del>~\n> bloc de citation\n[url](lien)",
"writeYourCommentHere": "Écrivez votre commentaire ici"
},
"boolFilters": {
@@ -215,7 +215,7 @@
"massRemoveResultSingle": "{count} record telah dihapus",
"noRecordsRemoved": "Tidak ada catatan yang dihapus",
"clickToRefresh": "Klik untuk refresh",
"streamPostInfo": "Ketik <strong> @nama pengguna </ strong> untuk menyebutkan pengguna di pos.\n\nSintaks yang tersedia:\n`<Code> Kode </ code>`\n** <Strong> teks yang kuat </ strong> **\n* <Em> menekankan teks </ em> *\n~ <Del> teks yang dihapus </ del> ~\n> blockquote\n(D) [url]",
"streamPostInfo": "Ketik <strong> @nama pengguna </ strong> untuk menyebutkan pengguna di pos.\n\nSintaks yang tersedia:\n`<Code> Kode </ code>`\n** <Strong> teks yang kuat </ strong> **\n* <Em> menekankan teks </ em> *\n~ <Del> teks yang dihapus </ del> ~\n> blockquote\n[D](url)",
"writeYourCommentHere": "Tulis komentar Anda di sini",
"writeMessageToUser": "Tulis pesan ke {user}",
"writeMessageToSelf": "Tulis pesan ke diri sendiri",
@@ -216,7 +216,7 @@
"massRemoveResult": "{count} record sono stati rimossi",
"noRecordsRemoved": "Nessun record è stato rimosso",
"clickToRefresh": "Clicca per aggiornare",
"streamPostInfo": "Type <strong>@username</strong> to mention users in the post.\n\nAvailable markdown syntax:\n`<code>code</code>`\n**<strong>strong text</strong>**\n*<em>emphasized text</em>*\n~<del>deleted text</del>~\n> blockquote\n(link name)[url]",
"streamPostInfo": "Type <strong>@username</strong> to mention users in the post.\n\nAvailable markdown syntax:\n`<code>code</code>`\n**<strong>strong text</strong>**\n*<em>emphasized text</em>*\n~<del>deleted text</del>~\n> blockquote\n[text](url)",
"writeYourCommentHere": "Scrivi il tuo commento qui",
"writeMessageToUser": "Scrivi un messaggio a {user}",
"writeMessageToSelf": "Scrivi un messaggio sul tuo streame",
@@ -202,7 +202,7 @@
"massRemoveResultSingle": "{count} bestanden zijn verwijderd",
"noRecordsRemoved": "Er werden geen bestanden verwijderd ",
"clickToRefresh": "Click to refresh",
"streamPostInfo": "Type <strong>@username</strong> to mention users in the post.\n\nAvailable markdown syntax:\n`<code>code</code>`\n**<strong>strong text</strong>**\n*<em>emphasized text</em>*\n~<del>deleted text</del>~\n> blockquote\n(url)[link]",
"streamPostInfo": "Type <strong>@username</strong> to mention users in the post.\n\nAvailable markdown syntax:\n`<code>code</code>`\n**<strong>strong text</strong>**\n*<em>emphasized text</em>*\n~<del>deleted text</del>~\n> blockquote\n[text](url)",
"writeYourCommentHere": "Schrijf hier uw opmerkingen"
},
"boolFilters": {
@@ -215,7 +215,7 @@
"massRemoveResultSingle": "Ilość usuniętych rekordów: {count}",
"noRecordsRemoved": "Nic nie usunięto",
"clickToRefresh": "Kliknij aby odświeżyć",
"streamPostInfo": "Wpisz <strong>@użytkownik</strong> aby zaznaczyć użytkownika w poście.\n\nDostępne znaczniki:\n`<code>kod</code>`\n**<strong>pogrubiony</strong>**\n*<em>pochylony</em>*\n~<del>skasowany</del>~\n> blockquote\n(link name)[url]",
"streamPostInfo": "Wpisz <strong>@użytkownik</strong> aby zaznaczyć użytkownika w poście.\n\nDostępne znaczniki:\n`<code>kod</code>`\n**<strong>pogrubiony</strong>**\n*<em>pochylony</em>*\n~<del>skasowany</del>~\n> blockquote\n[link text](url)",
"writeYourCommentHere": "Dodaj swój komentarz tutaj",
"writeMessageToUser": "Napisz wiadomość do {user}",
"writeMessageToSelf": "Napisz wiadomość do siebie",
@@ -173,7 +173,7 @@
"massRemoveResultSingle": "{count} registro foi removido",
"noRecordsRemoved": "Nenhum registro foi removido",
"clickToRefresh": "Clique para atualizar",
"streamPostInfo": "Digite <strong>@usuario</strong> para mencionar usuários na postagem.\n\nSintaxe markdown disponível::\n`<code>code</code>`\n**<strong>strong text</strong>**\n*<em>emphasized text</em>*\n~<del>deleted text</del>~\n> blockquote\n(url)[link]",
"streamPostInfo": "Digite <strong>@usuario</strong> para mencionar usuários na postagem.\n\nSintaxe markdown disponível::\n`<code>code</code>`\n**<strong>strong text</strong>**\n*<em>emphasized text</em>*\n~<del>deleted text</del>~\n> blockquote\n[link text](url)",
"writeYourCommentHere": "Escreva seu comentário aqui"
},
"boolFilters": {
@@ -215,7 +215,7 @@
"massRemoveResultSingle": "{count} запись была удалена",
"noRecordsRemoved": "Записи не были удалены",
"clickToRefresh": "Нажмите для обновления",
"streamPostInfo": "Введите <strong>@username</strong> чтобы упомянуть пользователей в сообщении.\n\nДоступный синтаксис разметки:\n`<code>код</code>`\n**<strong>важный текст</strong>**\n*<em>эмоционально выделенный текст</em>*\n~<del>удаленный текст</del>~\n> цитата\n(название ссылки)[URL]",
"streamPostInfo": "Введите <strong>@username</strong> чтобы упомянуть пользователей в сообщении.\n\nДоступный синтаксис разметки:\n`<code>код</code>`\n**<strong>важный текст</strong>**\n*<em>эмоционально выделенный текст</em>*\n~<del>удаленный текст</del>~\n> цитата\n[текст ссылки](URL)",
"writeYourCommentHere": "Оставьте свою заметку здесь",
"writeMessageToUser": "Оставить сообщение для {user}",
"writeMessageToSelf": "Оставить сообщение для себя",
@@ -183,7 +183,7 @@
"massRemoveResultSingle": "{count} запис була видалена",
"noRecordsRemoved": "Жодних записів не було видалено",
"clickToRefresh": "Натисніть, щоби поновити",
"streamPostInfo": "Тип <strong>@username</strong> для згадування користувачів у дописі.\nПрипустимий синтаксис розмітки:`<code>code</code>`\n**<strong>strong text</strong>**\n*<em>emphasized text</em>*\n~<del>deleted text</del>~\n> blockquote\n(url)[link]",
"streamPostInfo": "Тип <strong>@username</strong> для згадування користувачів у дописі.\nПрипустимий синтаксис розмітки:`<code>code</code>`\n**<strong>strong text</strong>**\n*<em>emphasized text</em>*\n~<del>deleted text</del>~\n> blockquote\n[текст](url)",
"writeYourCommentHere": "Напишіть свій коментар"
},
"boolFilters": {
@@ -9,5 +9,8 @@
"type":"bool"
}
],
"filter": true
"filter": true,
"fieldDefs":{
"notNull": true
}
}
@@ -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')
}
};
}
},
});
});
@@ -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')
}
};
}
},
});
});
+1 -1
View File
@@ -1,6 +1,6 @@
<select class="form-control search-type input-sm" name="{{name}}-type">
{{options searchData.typeOptions searchParams.type field='dateSearchRanges'}}
{{options searchTypeList searchType field='dateSearchRanges'}}
</select>
<div class="input-group primary">
<input class="main-element form-control input-sm" type="text" name="{{name}}" value="{{searchData.dateValue}}" autocomplete="off">
+3 -3
View File
@@ -1,9 +1,9 @@
<select class="form-control search-type input-sm" name="{{name}}-type">
{{options searchData.typeOptions searchParams.type field='intSearchRanges'}}
{{options searchTypeList searchType field='intSearchRanges'}}
</select>
<input type="text" class="form-control input-sm" name="{{name}}" value="{{searchParams.value1}}" pattern="[\-]?[0-9]*" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} placeholder="{{translate 'Value'}}">
<input type="text" class="form-control{{#ifNotEqual searchParams.type 'between'}} hide{{/ifNotEqual}} additional input-sm" name="{{name}}-additional" value="{{searchParams.value2}}" pattern="[\-]?[0-9]*" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} placeholder="{{translate 'Value'}}">
<input type="text" class="form-control input-sm hidden" name="{{name}}" value="{{searchParams.value1}}" pattern="[\-]?[0-9]*" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} placeholder="{{translate 'Value'}}">
<input type="text" class="form-control{{#ifNotEqual searchParams.type 'between'}} hidden{{/ifNotEqual}} additional input-sm" name="{{name}}-additional" value="{{searchParams.value2}}" pattern="[\-]?[0-9]*" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} placeholder="{{translate 'Value'}}">
@@ -1,5 +1,5 @@
<select class="form-control search-type input-sm" name="{{name}}-type">
{{options searchData.typeOptions searchParams.typeFront field='searchRanges'}}
{{options searchTypeList searchType field='searchRanges'}}
</select>
<div class="primary">
<select class="form-control input-sm" name="{{typeName}}">
+1 -3
View File
@@ -1,5 +1,5 @@
<select class="form-control search-type input-sm" name="{{name}}-type">
{{options searchData.typeOptions searchParams.typeFront field='searchRanges'}}
{{options searchTypeList searchType field='searchRanges'}}
</select>
<div class="primary">
<div class="input-group">
@@ -23,5 +23,3 @@
</span>
</div>
</div>
+1 -1
View File
@@ -1,5 +1,5 @@
<select class="form-control search-type input-sm" name="{{name}}-type">
{{options searchData.typeOptions searchParams.typeFront field='searchRanges'}}
{{options searchTypeList searchType field='searchRanges'}}
</select>
<div class="primary">
<div class="input-group">
+9 -6
View File
@@ -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
};
}
}
+3 -3
View File
@@ -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]);
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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');
+34 -8
View File
@@ -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));
},
+19
View File
@@ -157,6 +157,9 @@ 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();
data.searchTypeList = this.getSearchTypeList();
}
return data;
},
@@ -298,6 +301,22 @@ Espo.define('views/fields/base', 'view', function (Dep) {
}
},
getSearchParamsData: function () {
return this.searchParams.data || {};
},
getSearchValues: function () {
return this.getSearchParamsData().values || {};
},
getSearchType: function () {
return this.getSearchParamsData().type || this.searchParams.type;
},
getSearchTypeList: function () {
return this.searchTypeList;
},
initInlineEdit: function () {
var $cell = this.getCellElement();
var $editLink = $('<a href="javascript:" class="pull-right inline-edit-link hidden"><span class="glyphicon glyphicon-pencil"></span></a>');
@@ -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({
+14 -3
View File
@@ -38,22 +38,22 @@ 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'],
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);
},
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);
}
return Dep.prototype.data.call(this);
return data;
},
setupSearch: function () {
this.searchData.typeOptions = this.searchTypeOptions;
this.events = _.extend({
'change select.search-type': function (e) {
var type = $(e.currentTarget).val();
@@ -246,6 +246,13 @@ Espo.define('views/fields/date', 'views/fields/base', function (Dep) {
value: value,
dateValue: value
};
} else if (type === 'isEmpty') {
data = {
type: 'isNull',
data: {
type: type
}
}
} else {
data = {
type: type
@@ -254,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) {
+1 -1
View File
@@ -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'],
searchTypeList: ['lastSevenDays', 'ever', 'isEmpty', 'currentMonth', 'lastMonth', 'currentQuarter', 'lastQuarter', 'currentYear', 'lastYear', 'today', 'past', 'future', 'lastXDays', 'nextXDays', 'on', 'after', 'before', 'between'],
timeFormatMap: {
'HH:mm': 'H:i',
+49 -14
View File
@@ -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();
@@ -59,6 +61,15 @@ 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);
@@ -86,19 +97,29 @@ Espo.define('views/fields/int', 'views/fields/base', function (Dep) {
},
setupSearch: function () {
this.searchData.typeOptions = ['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 +214,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,10 +225,30 @@ 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;
},
getSearchType: function () {
return this.searchParams.typeFront || this.searchParams.type;
}
});
});
+21 -8
View File
@@ -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;
}
});
});
+22 -8
View File
@@ -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;
}
});
});
+7 -3
View File
@@ -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;
}
+1 -1
View File
@@ -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');