diff --git a/css/jquery.treeview.css b/css/jquery.treeview.css
index dccad6c76..b5f038600 100644
--- a/css/jquery.treeview.css
+++ b/css/jquery.treeview.css
@@ -1,6 +1,4 @@
-.treeview ul { background-color: white; }
-
-.treeview, .treeview ul {
+.treeview, .treeview ul {
padding: 0;
margin: 0;
list-style: none;
diff --git a/css/light-grey.css b/css/light-grey.css
index 8f502a3cb..031720f0a 100644
--- a/css/light-grey.css
+++ b/css/light-grey.css
@@ -2140,3 +2140,49 @@ span.refresh-button {
color: #fff;
border-radius: 4px;
}
+#img-lifecycle {
+ width: 100%;
+}
+#img-lifecycle:hover {
+ width: 100%;
+ cursor: pointer;
+}
+#search-model {
+ width: 98%;
+}
+.mfp-figure:after {
+ background-color: #dff1ff;
+}
+#classDetailsClassName {
+ display: inline;
+}
+.qtip-content a, .qtip-content a:visited {
+ color: #1c94c4;
+ text-decoration: none;
+}
+.qtip-content a:hover, .qtip-content a:active {
+ color: #e87c1e;
+ text-decoration: none;
+}
+.data-model-viewer a, .data-model-viewer a:visited {
+ color: #1c94c4;
+ text-decoration: none;
+}
+.data-model-viewer a:hover {
+ color: #e87c1e;
+ text-decoration: none;
+}
+table.listResults .originColor {
+ width: 0px;
+ padding: 2px !important;
+}
+#displaySelectorLabel, #changeDefaultDisplay {
+ display: inline-block;
+}
+#split-pane {
+ height: 100%;
+}
+#dataModelClassIcon {
+ padding-right: 13px;
+ display: inline;
+}
diff --git a/css/light-grey.scss b/css/light-grey.scss
index f1a1488f7..652d9473d 100644
--- a/css/light-grey.scss
+++ b/css/light-grey.scss
@@ -2352,4 +2352,57 @@ span.refresh-button {
font-size:10px;
color:#fff;
border-radius: 4px;
+}
+#img-lifecycle{
+ width:100%;
+}
+#img-lifecycle:hover{
+ width:100%;
+ cursor:pointer;
+}
+
+#search-model{
+ width:98%;
+}
+
+.mfp-figure:after{
+ background-color: #dff1ff;
+}
+#classDetailsClassName{
+ display:inline;
+}
+
+.qtip-content a, .qtip-content a:visited{
+ color : #1c94c4;
+ text-decoration: none;
+}
+.qtip-content a:hover, .qtip-content a:active{
+ color : #e87c1e;
+ text-decoration: none;
+}
+
+.data-model-viewer a, .data-model-viewer a:visited {
+ color : #1c94c4;
+ text-decoration : none;
+}
+
+.data-model-viewer a:hover {
+ color: #e87c1e;
+ text-decoration: none;
+}
+
+table.listResults .originColor{
+ width : 0px;
+ padding : 2px !important;
+}
+#displaySelectorLabel, #changeDefaultDisplay{
+ display :inline-block;
+}
+
+#split-pane{
+ height:100%;
+}
+#dataModelClassIcon{
+ padding-right: 13px;
+ display: inline;
}
\ No newline at end of file
diff --git a/dictionaries/cs.dictionary.itop.ui.php b/dictionaries/cs.dictionary.itop.ui.php
index 009a4d0c5..33e1c87f5 100755
--- a/dictionaries/cs.dictionary.itop.ui.php
+++ b/dictionaries/cs.dictionary.itop.ui.php
@@ -715,7 +715,12 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Musí se změnit',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'Uživatel bude vyzván ke změně hodnoty',
'UI:Schema:LifeCycleEmptyList' => 'prázdný seznam',
-
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => 'Zadejte první tři znaky...',
'UI:Edit:TestQuery' => 'Otestovat dotaz',
'UI:Combo:SelectValue' => '--- vyberte hodnotu ---',
diff --git a/dictionaries/da.dictionary.itop.ui.php b/dictionaries/da.dictionary.itop.ui.php
index c9588f305..b527427fb 100644
--- a/dictionaries/da.dictionary.itop.ui.php
+++ b/dictionaries/da.dictionary.itop.ui.php
@@ -557,6 +557,12 @@ Dict::Add('DA DA', 'Danish', 'Dansk', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Skal ændres',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'Bruger vil blive bedt om at ændre værdien',
'UI:Schema:LifeCycleEmptyList' => 'Tom liste',
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => '',
'UI:Edit:TestQuery' => 'Test forespørgsel',
'UI:Combo:SelectValue' => '--- vælg en værdi ---',
diff --git a/dictionaries/de.dictionary.itop.ui.php b/dictionaries/de.dictionary.itop.ui.php
index 3af9681e0..527c8c44c 100644
--- a/dictionaries/de.dictionary.itop.ui.php
+++ b/dictionaries/de.dictionary.itop.ui.php
@@ -558,6 +558,12 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Muss ändern',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'Benutzer wird zur Änderung des Wertes aufgefordert werden',
'UI:Schema:LifeCycleEmptyList' => 'Leere Liste',
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => 'Geben Sie die ersten 3 Buchstaben ein...',
'UI:Edit:TestQuery' => 'Query testen',
'UI:Combo:SelectValue' => '--- wählen Sie einen Wert ---',
diff --git a/dictionaries/dictionary.itop.ui.php b/dictionaries/dictionary.itop.ui.php
index 01b48553d..8a91e57a2 100644
--- a/dictionaries/dictionary.itop.ui.php
+++ b/dictionaries/dictionary.itop.ui.php
@@ -719,6 +719,12 @@ Dict::Add('EN US', 'English', 'English', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Must change',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'User will be prompted to change the value',
'UI:Schema:LifeCycleEmptyList' => 'empty list',
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => 'Type the first 3 characters...',
'UI:Edit:TestQuery' => 'Test query',
'UI:Combo:SelectValue' => '--- select a value ---',
diff --git a/dictionaries/es_cr.dictionary.itop.ui.php b/dictionaries/es_cr.dictionary.itop.ui.php
index e80092fc2..4ab7300b8 100644
--- a/dictionaries/es_cr.dictionary.itop.ui.php
+++ b/dictionaries/es_cr.dictionary.itop.ui.php
@@ -708,6 +708,12 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Debe cambiar',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'Se le pedira al usuario que cambie el valor',
'UI:Schema:LifeCycleEmptyList' => 'Lista Vacía',
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => 'Escriba los primeros 3 caracteres...',
'UI:Edit:TestQuery' => 'Consulta de Prueba',
'UI:Combo:SelectValue' => '--- seleccione un valor ---',
diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php
index 3d0fa44ae..fe510815b 100644
--- a/dictionaries/fr.dictionary.itop.ui.php
+++ b/dictionaries/fr.dictionary.itop.ui.php
@@ -610,6 +610,12 @@ Dict::Add('FR FR', 'French', 'Français', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Doit changer',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'L\'utilisateur se verra proposer de changer la valeur',
'UI:Schema:LifeCycleEmptyList' => 'liste vide',
+ 'UI:Schema:ClassFilter' => 'Classe :',
+ 'UI:Schema:DisplayLabel' => 'Affichage :',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label et code',
+ 'UI:Schema:DisplaySelector/Label' => 'Label',
+ 'UI:Schema:DisplaySelector/Code' => 'Code',
+ 'UI:Schema:Attribute/Filter' => 'Filtre',
'UI:LinksWidget:Autocomplete+' => 'Tapez les 3 premiers caractères...',
'UI:Edit:TestQuery' => 'Tester la requête',
'UI:Combo:SelectValue' => '--- choisissez une valeur ---',
diff --git a/dictionaries/hu.dictionary.itop.ui.php b/dictionaries/hu.dictionary.itop.ui.php
index d934f06f0..5cbab10db 100755
--- a/dictionaries/hu.dictionary.itop.ui.php
+++ b/dictionaries/hu.dictionary.itop.ui.php
@@ -489,6 +489,12 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Változtatni kell',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'Felhasználó kéri a változtatását',
'UI:Schema:LifeCycleEmptyList' => 'üres lista',
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => '',
'UI:Combo:SelectValue' => '--- válasszon értéket ---',
'UI:Label:SelectedObjects' => 'Kiválasztott objektumok: ',
diff --git a/dictionaries/it.dictionary.itop.ui.php b/dictionaries/it.dictionary.itop.ui.php
index b54736191..53d845a54 100644
--- a/dictionaries/it.dictionary.itop.ui.php
+++ b/dictionaries/it.dictionary.itop.ui.php
@@ -621,6 +621,12 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Deve cambiare',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'All\'utente verrà richiesto di modificare il valore',
'UI:Schema:LifeCycleEmptyList' => 'lista vuota',
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => '',
'UI:Combo:SelectValue' => '--- seleziona un valore ---',
'UI:Label:SelectedObjects' => 'oggetti selezionati: ',
diff --git a/dictionaries/ja.dictionary.itop.ui.php b/dictionaries/ja.dictionary.itop.ui.php
index fe236da74..2c814205f 100644
--- a/dictionaries/ja.dictionary.itop.ui.php
+++ b/dictionaries/ja.dictionary.itop.ui.php
@@ -557,6 +557,12 @@ Dict::Add('JA JP', 'Japanese', '日本語', array(
'UI:Schema:LifeCycleAttributeMustChange' => '変更必須',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'ユーザはこの値を変更するよう、促されます。',
'UI:Schema:LifeCycleEmptyList' => '空リスト',
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => '最初の3文字をタイプしてください...',
'UI:Edit:TestQuery' => 'Test query',
'UI:Combo:SelectValue' => '--- 値を選んでください ---',
diff --git a/dictionaries/nl.dictionary.itop.ui.php b/dictionaries/nl.dictionary.itop.ui.php
index bf7757232..da49ae263 100644
--- a/dictionaries/nl.dictionary.itop.ui.php
+++ b/dictionaries/nl.dictionary.itop.ui.php
@@ -716,6 +716,12 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Moet worden veranderd',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'Gebruiker zal worden gevraagd om de waarde te veranderen',
'UI:Schema:LifeCycleEmptyList' => 'lege lijst',
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => 'Typ de eerste 3 karakters...',
'UI:Edit:TestQuery' => 'Test query',
'UI:Combo:SelectValue' => '--- selecteer een waarde ---',
diff --git a/dictionaries/pt_br.dictionary.itop.ui.php b/dictionaries/pt_br.dictionary.itop.ui.php
index 0ee75aaa9..db1104628 100644
--- a/dictionaries/pt_br.dictionary.itop.ui.php
+++ b/dictionaries/pt_br.dictionary.itop.ui.php
@@ -708,6 +708,12 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Tem que mudar',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'Usuário será solicitado para alterar o valor',
'UI:Schema:LifeCycleEmptyList' => 'Lista vazia',
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => 'Tipo os 3 primeiro caracteres...',
'UI:Edit:TestQuery' => 'Testar consulta',
'UI:Combo:SelectValue' => '--- selecione um valor ---',
diff --git a/dictionaries/ru.dictionary.itop.ui.php b/dictionaries/ru.dictionary.itop.ui.php
index 42327e45c..c8af7ff5f 100644
--- a/dictionaries/ru.dictionary.itop.ui.php
+++ b/dictionaries/ru.dictionary.itop.ui.php
@@ -690,6 +690,12 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Необходимо изменить',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'Пользователю будет предложено изменить значение',
'UI:Schema:LifeCycleEmptyList' => 'пустой список',
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => 'Введите первые 3 символа...',
'UI:Edit:TestQuery' => 'Проверить запрос',
'UI:Combo:SelectValue' => '--- выбор значения ---',
diff --git a/dictionaries/tr.dictionary.itop.ui.php b/dictionaries/tr.dictionary.itop.ui.php
index d50616a89..aae331517 100644
--- a/dictionaries/tr.dictionary.itop.ui.php
+++ b/dictionaries/tr.dictionary.itop.ui.php
@@ -595,7 +595,12 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', array(
'UI:Schema:LifeCycleAttributeMustChange' => 'Değiştirilmesi gereken',
'UI:Schema:LifeCycleAttributeMustPrompt' => 'Kullanıcıdan değeri değüiştirmesi istenir',
'UI:Schema:LifeCycleEmptyList' => 'boş liste',
-
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => 'İlk 3 karakteri giriniz...',
'UI:Combo:SelectValue' => '--- değer seçiniz ---',
'UI:Label:SelectedObjects' => 'Seçilen nesneler: ',
diff --git a/dictionaries/zh.dictionary.itop.ui.php b/dictionaries/zh.dictionary.itop.ui.php
index 46d3007f5..e0aec0a7a 100644
--- a/dictionaries/zh.dictionary.itop.ui.php
+++ b/dictionaries/zh.dictionary.itop.ui.php
@@ -594,7 +594,12 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'UI:Schema:LifeCycleAttributeMustChange' => '必须变更',
'UI:Schema:LifeCycleAttributeMustPrompt' => '用户将被提示改变值',
'UI:Schema:LifeCycleEmptyList' => '空列表',
-
+ 'UI:Schema:ClassFilter' => 'Class:~~',
+ 'UI:Schema:DisplayLabel' => 'Display:~~',
+ 'UI:Schema:DisplaySelector/LabelAndCode' => 'Label and code~~',
+ 'UI:Schema:DisplaySelector/Label' => 'Label~~',
+ 'UI:Schema:DisplaySelector/Code' => 'Code~~',
+ 'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:LinksWidget:Autocomplete+' => '输入前3个字符...',
'UI:Combo:SelectValue' => '--- 选择一个值 ---',
'UI:Label:SelectedObjects' => '被选对象: ',
diff --git a/js/jquery.treeview.js b/js/jquery.treeview.js
index bc5d9e46b..67906016f 100644
--- a/js/jquery.treeview.js
+++ b/js/jquery.treeview.js
@@ -69,12 +69,12 @@
if (!settings.prerendered) {
// handle closed ones first
- this.filter(":has(>ul:hidden)")
+ this.filter("."+CLASSES.closed)
.addClass(CLASSES.expandable)
.replaceClass(CLASSES.last, CLASSES.lastExpandable);
// handle open ones
- this.not(":has(>ul:hidden)")
+ this.not("."+CLASSES.closed)
.addClass(CLASSES.collapsable)
.replaceClass(CLASSES.last, CLASSES.lastCollapsable);
diff --git a/pages/graphviz.php b/pages/graphviz.php
index 53e089fad..4aaa0791c 100644
--- a/pages/graphviz.php
+++ b/pages/graphviz.php
@@ -63,9 +63,8 @@ function GraphvizLifecycle($sClass)
$aStates = MetaModel::EnumStates($sClass);
$aStimuli = MetaModel::EnumStimuli($sClass);
$sDotFileContent .= "digraph finite_state_machine {
- graph [bgcolor = \"transparent\"];
+ graph [bgcolor = \"#eeeeee\"];
rankdir=LR;
- size=\"12,12\"
node [ fontname=Verdana style=filled fillcolor=\"#ffffff\" ];
edge [ fontname=Verdana ];
";
diff --git a/pages/schema.php b/pages/schema.php
index fa6621ac6..1776f4c77 100644
--- a/pages/schema.php
+++ b/pages/schema.php
@@ -1,5 +1,5 @@
".MetaModel::GetName($sClass)." ($sClass)";
+ return "".MetaModel::GetName($sClass)." ( " .$sClass." ) ";
}
/**
@@ -85,103 +85,6 @@ function DisplaySubclasses($oPage, $sClass, $sContext)
}
}
-/**
- * Helper for the global list and the details of a given class
- */
-function DisplayReferencingClasses($oPage, $sClass, $sContext)
-{
- $bSkipLinkingClasses = false;
- $aRefs = MetaModel::EnumReferencingClasses($sClass, $bSkipLinkingClasses);
- if (count($aRefs) != 0)
- {
- $oPage->add("
\n");
- foreach ($aRefs as $sRemoteClass => $aRemoteKeys)
- {
- foreach ($aRemoteKeys as $sExtKeyAttCode => $oExtKeyAttDef)
- {
- $oPage->add("".Dict::Format('UI:Schema:Class_ReferencingClasses_From_By', $sClass, MakeClassHLink($sRemoteClass, $sContext), $sExtKeyAttCode)." \n");
- }
- }
- $oPage->add(" \n");
- }
-}
-
-/**
- * Helper for the global list and the details of a given class
- */
-function DisplayLinkingClasses($oPage, $sClass, $sContext)
-{
- $bSkipLinkingClasses = false;
- $aRefs = MetaModel::EnumLinkingClasses($sClass);
- if (count($aRefs) != 0)
- {
- $oPage->add("\n");
- foreach ($aRefs as $sLinkClass => $aRemoteClasses)
- {
- foreach($aRemoteClasses as $sExtKeyAttCode => $sRemoteClass)
- {
- $oPage->add("".Dict::Format('UI:Schema:Class_IsLinkedTo_Class_Via_ClassAndAttribute', $sClass, MakeClassHLink($sRemoteClass, $sContext), MakeClassHLink($sLinkClass, $sContext), $sExtKeyAttCode));
- }
- }
- $oPage->add(" \n");
- }
-}
-
-/**
- * Helper for the global list and the details of a given class
- */
-function DisplayRelatedClassesBestInClass($oPage, $sClass, $iLevels = 20, &$aVisitedClasses = array(), $bSubtree = true, $sContext)
-{
- if ($iLevels <= 0) return;
- $iLevels--;
-
- if (array_key_exists($sClass, $aVisitedClasses)) return;
- $aVisitedClasses[$sClass] = true;
-
- if ($bSubtree) $oPage->add("\n");
- foreach (MetaModel::EnumParentClasses($sClass) as $sParentClass)
- {
- DisplayRelatedClassesBestInClass($oPage, $sParentClass, $iLevels, $aVisitedClasses, false, $sContext);
- }
- ////$oPage->add("");
- foreach (MetaModel::EnumReferencedClasses($sClass) as $sExtKeyAttCode => $sRemoteClass)
- {
- $sVisited = (array_key_exists($sRemoteClass, $aVisitedClasses)) ? " ..." : "";
- if (MetaModel::GetAttributeOrigin($sClass, $sExtKeyAttCode) == $sClass)
- {
- $oPage->add("
$sClass| $sExtKeyAttCode =>".MakeClassHLink($sRemoteClass, $sContext)."$sVisited \n");
- DisplayRelatedClassesBestInClass($oPage, $sRemoteClass, $iLevels, $aVisitedClasses, true, $sContext);
- }
- }
- foreach (MetaModel::EnumReferencingClasses($sClass) as $sRemoteClass => $aRemoteKeys)
- {
- foreach ($aRemoteKeys as $sExtKeyAttCode => $oExtKeyAttDef)
- {
- $sVisited = (array_key_exists($sRemoteClass, $aVisitedClasses)) ? " ..." : "";
- $oPage->add("$sClass| <=".MakeClassHLink($sRemoteClass, $sContext)."::$sExtKeyAttCode $sVisited \n");
- DisplayRelatedClassesBestInClass($oPage, $sRemoteClass, $iLevels, $aVisitedClasses, true, $sContext);
- }
- }
- ////$oPage->add("");
- if ($bSubtree) $oPage->add(" \n");
-}
-
-/**
- * Helper for the list of classes related to the given class
- */
-function DisplayRelatedClasses($oPage, $sClass, $sContext)
-{
- $oPage->add("".Dict::Format('UI:Schema:Links:1-n', $sClass)." \n");
- DisplayReferencingClasses($oPage, $sClass, $sContext);
-
- $oPage->add("".Dict::Format('UI:Schema:Links:n-n', $sClass)." \n");
- DisplayLinkingClasses($oPage, $sClass, $sContext);
-
- $oPage->add("".Dict::S('UI:Schema:Links:All')." \n");
- $aEmpty = array();
- DisplayRelatedClassesBestInClass($oPage, $sClass, 4, $aEmpty, true, $sContext);
-}
-
/**
* Helper for the lifecycle details of a given class
*/
@@ -196,15 +99,22 @@ function DisplayLifecycle($oPage, $sClass)
{
$aStates = MetaModel::EnumStates($sClass);
$aStimuli = MetaModel::EnumStimuli($sClass);
- $oPage->add(" \n");
+ $oPage->add(" \n");
+ $oPage->add_ready_script(
+ <<add("".Dict::S('UI:Schema:LifeCycleTransitions')." \n");
- $oPage->add("\n");
+ $oPage->add("\n");
foreach ($aStates as $sStateCode => $aStateDef)
{
$sStateLabel = MetaModel::GetStateLabel($sClass, $sStateCode);
$sStateDescription = MetaModel::GetStateDescription($sClass, $sStateCode);
- $oPage->add("$sStateLabel ($sStateCode) $sStateDescription \n");
- $oPage->add("\n");
+ $oPage->add("$sStateLabel ( $sStateCode ) $sStateDescription \n");
+ $oPage->add("\n");
foreach(MetaModel::EnumTransitions($sClass, $sStateCode) as $sStimulusCode => $aTransitionDef)
{
$sStimulusLabel = $aStimuli[$sStimulusCode]->GetLabel();
@@ -235,19 +145,22 @@ function DisplayLifecycle($oPage, $sClass)
{
$sActions = "";
}
- $oPage->add("$sStimulusLabel ($sStimulusCode) => $sTargetStateLabel ($sTargetState) $sActions \n");
+
+ $oPage->add("$sStimulusLabel
+ ( $sStimulusCode )
+ =>
+ $sTargetStateLabel ( $sTargetState ) $sActions \n");
}
- $oPage->add(" \n");
+ $oPage->add(" \n");
}
$oPage->add(" \n");
-
$oPage->add("".Dict::S('UI:Schema:LifeCyleAttributeOptions')." \n");
- $oPage->add("\n");
+ $oPage->add("\n");
foreach ($aStates as $sStateCode => $aStateDef)
{
$sStateLabel = MetaModel::GetStateLabel($sClass, $sStateCode);
$sStateDescription = MetaModel::GetStateDescription($sClass, $sStateCode);
- $oPage->add("$sStateLabel ($sStateCode) $sStateDescription \n");
+ $oPage->add("$sStateLabel ( $sStateCode ) $sStateDescription \n");
if (count($aStates[$sStateCode]['attribute_list']) > 0)
{
$oPage->add("\n");
@@ -271,9 +184,9 @@ function DisplayLifecycle($oPage, $sClass)
$sOptions = "";
}
- $oPage->add("$sAttLabel $sOptions \n");
+ $oPage->add("$sAttLabel $sOptions \n");
}
- $oPage->add(" \n");
+ $oPage->add(" \n");
}
else
{
@@ -281,7 +194,10 @@ function DisplayLifecycle($oPage, $sClass)
}
}
$oPage->add(" \n");
- }
+ $oPage->add_ready_script('$("#LifeCycleList").treeview();');
+ $oPage->add_ready_script('$("#LifeCycleAttrOptList").treeview();');
+
+ }
}
@@ -303,6 +219,7 @@ function DisplayClassesList($oPage, $sContext)
{
$oPage->add("".Dict::S('UI:Schema:Title')." \n");
+ $oPage->add("" . Dict::S('UI:Schema:ClassFilter') ." ");
$oPage->add("\n");
// Get all the "root" classes for display
$aRootClasses = array();
@@ -316,6 +233,15 @@ function DisplayClassesList($oPage, $sContext)
{
$aRootClasses[$sClassName] = MetaModel::GetName($sClassName);
}
+ $sLabelClassName = MetaModel::GetName($sClassName);
+ //Fetch classes names for autocomplete purpose
+ $oPage->add_script(
+ <<add(" \n");
-
- $oPage->add("".Dict::S('UI:Schema:Relationships')." \n");
-
- $oPage->add("\n");
- foreach (MetaModel::EnumRelations() as $sRelCode)
- {
- $oPage->add("".MakeRelationHLink($sRelCode, $sContext)."\n");
- $oPage->add("\n");
- $oPage->add("Description: ".htmlentities(MetaModel::GetRelationDescription($sRelCode), ENT_QUOTES, 'UTF-8')." \n");
- $oPage->add("Label: ".htmlentities(MetaModel::GetRelationLabel($sRelCode), ENT_QUOTES, 'UTF-8')." \n");
- $oPage->add(" \n");
- $oPage->add(" \n");
- }
- $oPage->add(" \n");
$oPage->add_ready_script('$("#ClassesList").treeview();');
- $oPage->add_ready_script('$("#ClassesRelationships").treeview();');
+}
+
+
+/**
+ * Helper for the list of classes related to the given class in a graphical way
+ */
+function DisplayRelatedClassesGraph($oPage, $sClass)
+{
+ try
+ {
+ $bOnTheLeft = true;
+ $bSkipLinkingClasses = false;
+ // 1) Fetching referencing classes data
+ //
+ $aData = array();
+ $aOrigins = array('_' => true);
+ $aRefs = MetaModel::EnumReferencingClasses($sClass, $bSkipLinkingClasses);
+ $sSelfReference = "false";
+ if (count($aRefs) != 0)
+ {
+ foreach ($aRefs as $sRemoteClass => $aRemoteKeys)
+ {
+ foreach ($aRemoteKeys as $sExtKeyAttCode => $oExtKeyAttDef)
+ {
+ if($sRemoteClass != $sClass)
+ {
+ // ref_prefix to avoid collision between attributes labels that refer to this class and local attributes label that references other classes
+ $aAttribute = array('label' => 'ref_'.$sExtKeyAttCode);
+ // Test if a distant attribut exists and if it uses a link class
+ if(!($oExtKeyAttDef->GetMirrorLinkAttribute() == null ? false : $oExtKeyAttDef->GetMirrorLinkAttribute() instanceof AttributeLinkedSetIndirect))
+ {
+ $aAttribute['related'] = $sRemoteClass;
+ $aAttribute['related_icon'] = MetaModel::GetClassIcon($aAttribute['related'], false);
+ $aAttribute['related_position'] = $bOnTheLeft ? -1 : 1;
+ $aAttribute['relation_type'] = 0;
+ $bOnTheLeft = !$bOnTheLeft; // Toggle the side
+ $sOrigin = MetaModel::GetAttributeOrigin($sRemoteClass, $sExtKeyAttCode);
+ $aAttribute['origin'] = $sOrigin;
+ $aOrigins[$sOrigin] = true;
+ $aData[$sExtKeyAttCode . $sRemoteClass] = $aAttribute;
+ }
+ }
+ }
+ }
+ }
+ $aOrigins = array_keys($aOrigins);
+ $idx = 0;
+ foreach($aData as $sAttCode => $aAttribute)
+ {
+ $aData[$sAttCode]['origin_index'] = $aAttribute['related_position'] == 1 ? $idx : ++$idx;
+ }
+ ksort($aData);
+ $idx = 0;
+ $aFinalDataReferencing = array();
+ foreach($aData as $sAttCode => $aAttribute)
+ {
+ $aData[$sAttCode]['alphabetical_index'] = $aAttribute['related_position'] == 1 ? ++$idx : $idx;
+ $aFinalDataReferencing[] = $aData[$sAttCode];
+ }
+ $sDataReferencing = json_encode($aFinalDataReferencing);
+ $sOriginsReferencing = json_encode(array_keys($aOrigins));
+
+ // 2) Fetching referenced classes data
+ //
+ $aData = array(array('label' => $sClass, 'icon' => MetaModel::GetClassIcon($sClass, false), 'origin_index' => 0, 'alphabetical_index' => 0, 'origin' => '_'));
+ $bOnTheLeft = true;
+ $aOrigins = array('_' => true);
+ foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
+ {
+ $aAttribute = array('label' => $sAttCode);
+ if ($oAttDef->IsLinkSet())
+ {
+ if ($oAttDef->IsIndirect())
+ {
+ $sRemoteAttDef = $oAttDef->GetExtKeyToRemote();
+ $aAttribute['related'] = MetaModel::GetAttributeDef($oAttDef->GetLinkedClass(), $sRemoteAttDef)->GetTargetClass();
+ $aAttribute['related_icon'] = MetaModel::GetClassIcon($aAttribute['related'], false);
+ $aAttribute['related_position'] = $bOnTheLeft ? 1 : -1;
+ $aAttribute['relation_type'] = 0; //
+ $bOnTheLeft = !$bOnTheLeft; // Toggle the side
+ }
+ else
+ {
+ $aAttribute['related'] = $oAttDef->GetLinkedClass();
+ $aAttribute['related_icon'] = MetaModel::GetClassIcon($aAttribute['related'], false);
+ $aAttribute['related_position'] = $bOnTheLeft ? 1 : -1;
+ $aAttribute['relation_type'] = 1;
+ $bOnTheLeft = !$bOnTheLeft; // Toggle the side
+ }
+
+ }
+ else if ($oAttDef->IsHierarchicalKey())
+ {
+ $aAttribute['related'] = $sClass;
+ $aAttribute['related_icon'] = MetaModel::GetClassIcon($aAttribute['related'], false);
+ $aAttribute['related_position'] = $bOnTheLeft ? 1 : -1;
+ $aAttribute['relation_type'] = 2;
+ $bOnTheLeft = !$bOnTheLeft; // Toggle the side
+ $sSelfReference = "true";
+ }
+ else if ($oAttDef->IsExternalKey())
+ {
+ $aAttribute['related'] = $oAttDef->GetTargetClass();
+ $aAttribute['related_icon'] = MetaModel::GetClassIcon($aAttribute['related'], false);
+ $aAttribute['related_position'] = $bOnTheLeft ? 1 : -1;
+ $aAttribute['relation_type'] = 0;
+
+ $bOnTheLeft = !$bOnTheLeft; // Toggle the side
+ }
+ if ($oAttDef->IsLinkSet() || $oAttDef->IsHierarchicalKey() || $oAttDef->IsExternalKey()){
+ $sOrigin = MetaModel::GetAttributeOrigin($sClass, $sAttCode);
+
+ $aAttribute['origin'] = $sOrigin;
+ $aOrigins[$sOrigin] = true;
+ $aData[$sAttCode] = $aAttribute;
+
+ }
+
+ }
+ $idx = 1;
+ foreach($aData as $sAttCode => $aAttribute)
+ {
+ $aData[$sAttCode]['origin_index'] = $idx++;
+ }
+
+ $idx = 1;
+ $aFinalData = array();
+ foreach($aData as $sAttCode => $aAttribute)
+ {
+ $aData[$sAttCode]['alphabetical_index'] = $idx++;
+ $aFinalData[] = $aData[$sAttCode];
+ }
+
+ $sData = json_encode($aFinalData);
+
+ // 3) Processing data and building graph
+ //
+ $oPage->add_style(
+ << .selfattr{
+ fill: #fdf5d0;
+}
+EOF
+ );
+ $oPage->add(
+ <<
+
+
+
+EOF
+ );
+ $oPage->add_ready_script(
+ << 1)
+{
+schema.append("path")
+ .attr("d", "M"+(margins.left + relatedCellWidth + gap + cellWidth*0.75)+" "+ (margins.top + cellHeight + cellHeight*(datareflen+1.5)) +" l 0 "+ cellHeight*-datareflen+"")
+ .attr("fill", "transparent")
+ .attr("stroke", "black")
+ .attr("stroke-linecap", "round")
+ .attr("stroke-width", 2);
+}
+if(dataref.length > 0)
+{
+schema.append("path")
+ .attr("d", "M"+(margins.left + relatedCellWidth + gap + cellWidth*0.25)+" "+ (margins.top + cellHeight + cellHeight*(datareflen+1.5)) +" l 0 "+ cellHeight*-datareflen+"")
+ .attr("fill", "transparent")
+ .attr("stroke", "black")
+ .attr("stroke-linecap", "round")
+ .attr("stroke-width", 2);
+}
+
+//loop + arrow to show that a class has a hierarchical attribute
+if(isSelfReferencing == true)
+{
+ schema.append("path")
+ .attr("d", "M"+(margins.left + relatedCellWidth + gap + cellWidth/1.9)+" "+ (margins.top + cellHeight*(datareflen+1.5))+" a 20 20 0 1 0 20 0 m-10 0l-5 3 m5 -3 l-5 -3")
+ .attr("id", "selfreferencing")
+ .attr("fill", "transparent")
+ .attr("stroke", "black")
+ .attr("stroke-linecap", "round")
+ .attr("stroke-width", 2)
+ .attr("transform", "rotate(95, "+ (margins.left + relatedCellWidth + gap + cellWidth/1.9) + ", " + ((margins.top + cellHeight*(datareflen+1.5))+10)+")");
+}
+
+// 2) Classes linked to horns (classes referencing us)
+//
+var fieldref = schema.selectAll("g")
+ .data(dataref, function(d) { return d.label + d.related } )
+ .enter().append("g")
+ .attr("transform", function(d, i) { return "translate(" + (margins.left + relatedCellWidth + gap + cellWidth/2) + "," + (margins.top + d.origin_index*cellHeight*2) + ")"; });
+
+
+fieldref.filter(function(d) {
+ return (d.related != null);
+}).append("a")
+ .attr("xlink:href",function(d){ return refClassLinkpre + d.related + refClassLinksuf})
+ .append("rect")
+ .attr("x", -relatedCellWidth/2)
+ .attr("width", relatedCellWidth)
+ .attr("height", cellHeight)
+ .attr("fill", "#fff")
+ .attr("stroke", "#000")
+ .attr("stroke-width", 1)
+ .attr("transform", function(d, i) { return "translate("+ d.related_position*(relatedCellWidth/2+cellWidth/2+gap) +", 0)"; });
+
+fieldref.filter(function(d) {
+ return (d.related != null);
+}).append("a")
+ .attr("xlink:href",function(d){ return refClassLinkpre + d.related + refClassLinksuf })
+ .append("text")
+ .attr("x", 0)
+ .attr("y", cellHeight / 2)
+ .attr("dy", ".35em")
+ .text(function(d) { return d.related ? d.related : ''; })
+ .attr("transform", function(d, i) { return "translate("+ (d.related_position*(relatedCellWidth/2+cellWidth/2+gap)) +", 0)"; });
+
+fieldref.filter(function(d) {
+ return (d.related != null);
+}).append("path")
+ .attr("d", "M"+(cellWidth/2 - cellWidth*0.25)+" "+cellHeight/2+" h"+(gap-2 + cellWidth*0.25))
+ .attr("fill", "transparent")
+ .attr("stroke", "black")
+ .attr("stroke-linecap", "round")
+ .attr("stroke-width", 2)
+ .attr("transform", function(d, i) { return (d.related_position < 0) ? "rotate(180, 0, "+(cellHeight/2)+")" : ""});
+
+fieldref.filter(function(d) {
+ return (d.related != null);
+}).append("path")
+ .attr("d", "M"+cellWidth/1.9*-1+" "+cellHeight/2+" m-10 0l-5 3 m5 -3 l-5 -3")
+ .attr("fill", "transparent")
+ .attr("stroke", "black")
+ .attr("stroke-linecap", "round")
+ .attr("stroke-width", 2)
+ .attr("transform", function(d, i) { return (d.related_position < 0) ? "rotate(360, 0, "+(cellHeight/2)+")" : "rotate(180, 0, "+(cellHeight/2)+")"});
+
+fieldref.filter(function(d) {
+ return (d.related != null);
+}).append("svg:image")
+ .attr("x", -relatedCellWidth/2)
+ .attr("width", cellHeight)
+ .attr("height", cellHeight)
+ .attr("xlink:href", function(d, i) { return d.related_icon })
+ .attr("transform", function(d, i) { return "translate("+ (d.related_position*(relatedCellWidth/2+cellWidth/2+gap) - 12)+", -" + cellHeight/2+" )"; });
+
+
+// 3) Main class rectangle and attributes rectangles
+//
+var field = schema.selectAll("g")
+ .data(data, function(d) { console.log(d.label); return d.label} )
+ .enter().append("g")
+ .attr("transform", function(d, i) { return "translate(" + (margins.left + relatedCellWidth + gap + cellWidth/2) + "," + (margins.top + (datareflen+1.5)*cellHeight + d.origin_index*cellHeight) + ")"; });
+
+field.append("rect")
+ .attr("x", -cellWidth/2)
+ .attr("width", cellWidth)
+ .attr("class", function(d, i){return (d.relation_type == 2 ? "selfattr" : "extattr");})
+ .attr("height", cellHeight)
+ .attr("fill", "#fff")
+ .attr("stroke", "#000")
+ .attr("stroke-width", 1);
+
+field.append("text")
+ .attr("x", 0)
+ .attr("y", cellHeight / 2)
+ .attr("dy", ".35em")
+ .text(function(d) { return d.label; });
+
+// 4) Classes that our main class is refering to
+//
+field.filter(function(d) {
+ return (d.related != null);
+}).append("a")
+ .attr("xlink:href",function(d){ return refClassLinkpre + d.related + refClassLinksuf})
+ .append("rect")
+ .attr("x", -relatedCellWidth/2)
+ .attr("width", relatedCellWidth)
+ .attr("height", cellHeight)
+ .attr("fill", "#fff")
+ .attr("stroke", "#000")
+ .attr("stroke-width", 1)
+ .attr("transform", function(d, i) { return "translate("+ d.related_position*(relatedCellWidth/2+cellWidth/2+gap) +", 0)"; });
+
+field.filter(function(d) {
+ return (d.related != null);
+}).append("a")
+ .attr("xlink:href",function(d){ return refClassLinkpre + d.related + refClassLinksuf})
+ .append("text")
+ .attr("x", 0)
+ .attr("y", cellHeight / 2)
+ .attr("dy", ".35em")
+ .text(function(d) { return d.related ? d.related : ''; })
+ .attr("transform", function(d, i) { return "translate("+ (d.related_position*(relatedCellWidth/2+cellWidth/2+gap)) +", 0)"; });
+
+field.filter(function(d) {
+ return (d.related != null);
+}).append("path")
+ .attr("d", "M"+cellWidth/2+" "+cellHeight/2+" h"+(gap-2)+" m-10 0l-5 3 m5 -3 l-5 -3")
+ .attr("fill", "transparent")
+ .attr("stroke", "black")
+ .attr("stroke-linecap", "round")
+ .attr("stroke-width", 2)
+ .attr("transform", function(d, i) { return (d.related_position < 0) ? "rotate(180, 0, "+(cellHeight/2)+")" : ""});
+
+field.filter(function(d) {
+ return (d.related != null) && (d.relation_type == 1);
+}).append("path")
+ .attr("d", "M"+cellWidth/1.9*-1+" "+cellHeight/2+" m-10 0l-5 3 m5 -3 l-5 -3")
+ .attr("fill", "transparent")
+ .attr("stroke", "black")
+ .attr("stroke-linecap", "round")
+ .attr("stroke-width", 2)
+ .attr("transform", function(d, i) { return (d.related_position < 0) ? "rotate(360, 0, "+(cellHeight/2)+")" : "rotate(180, 0, "+(cellHeight/2)+")"});
+
+field.filter(function(d) {
+ return (d.related != null);
+}).append("svg:image")
+ .attr("x", -relatedCellWidth/2)
+ .attr("width", cellHeight)
+ .attr("height", cellHeight)
+ .attr("xlink:href", function(d, i) { return d.related_icon })
+ .attr("transform", function(d, i) { return "translate("+ (d.related_position*(relatedCellWidth/2+cellWidth/2+gap) - 12)+", -" + cellHeight/2+" )"; });
+
+field.append("rect")
+ .attr("x", -cellWidth/2 - 5)
+ .attr("width", 5)
+ .attr("height", cellHeight)
+ .attr("fill", function(d) { return aColors(aOrigins.indexOf(d.origin)); } )
+ .attr("stroke-width", 0)
+ .attr("class","liseret");
+
+field.filter(function(d) {
+ return (d.icon != null);
+}).append("svg:image")
+ .attr("x", -cellWidth/2)
+ .attr("width", 36)
+ .attr("height", 36)
+ .attr("xlink:href", function(d, i) { return d.icon })
+ .attr("transform", "translate(-12, -24)");
+
+EOF
+ );
+ }
+ catch(Exception $e)
+ {
+ $oPage->p(''.Dict::Format('UI:RunQuery:Error', $e->getMessage()).' ');
+ }
}
/**
@@ -356,7 +653,9 @@ function DisplayClassesList($oPage, $sContext)
*/
function DisplayClassDetails($oPage, $sClass, $sContext)
{
- $oPage->add("".MetaModel::GetName($sClass)." ($sClass) - ".MetaModel::GetClassDescription($sClass)." \n");
+ $oPage->add("" . MetaModel::GetClassIcon($sClass) . "
");
+ $sClassDescritpion = MetaModel::GetClassDescription($sClass);
+ $oPage->add("".MetaModel::GetName($sClass)." ($sClass) " . ($sClassDescritpion == "" ? "" : " - " . $sClassDescritpion) . " \n");
if (MetaModel::IsAbstract($sClass))
{
$oPage->p(Dict::S('UI:Schema:AbstractClass'));
@@ -366,8 +665,6 @@ function DisplayClassDetails($oPage, $sClass, $sContext)
$oPage->p(Dict::S('UI:Schema:NonAbstractClass'));
}
-// $oPage->p("".Dict::S('UI:Schema:ClassHierarchyTitle')." ");
-
$aParentClasses = array();
foreach(MetaModel::EnumParentClasses($sClass) as $sParentClass)
{
@@ -398,6 +695,8 @@ function DisplayClassDetails($oPage, $sClass, $sContext)
// List the attributes of the object
$aForwardChangeTracking = MetaModel::GetTrackForwardExternalKeys($sClass);
$aDetails = array();
+
+ $aOrigins = array();
foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode=>$oAttDef)
{
if ($oAttDef->IsExternalKey())
@@ -418,9 +717,13 @@ function DisplayClassDetails($oPage, $sClass, $sContext)
{
$sValue = $oAttDef->GetDescription();
}
- $sType = $oAttDef->GetType().' ('.$oAttDef->GetTypeDesc().')';
- $sOrigin = MetaModel::GetAttributeOrigin($sClass, $sAttCode);
- $sAllowedValues = "";
+ $sType = get_class($oAttDef);
+ $sTypeDict = $oAttDef->GetType();
+ $sTypeDesc = $oAttDef->GetTypeDesc();
+
+ $sOrigin = MetaModel::GetAttributeOrigin($sClass, $sAttCode);
+ $aOrigins[$sOrigin] = true;
+ $sAllowedValues = "";
$sMoreInfo = "";
$aCols = array();
@@ -430,15 +733,14 @@ function DisplayClassDetails($oPage, $sClass, $sContext)
}
if (count($aCols) > 0)
{
- $sCols = implode(', ', $aCols);
-
+
$aMoreInfo = array();
- $aMoreInfo[] = Dict::Format('UI:Schema:Columns_Description', $sCols);
- $aMoreInfo[] = Dict::Format('UI:Schema:Default_Description', $oAttDef->GetDefaultValue());
$aMoreInfo[] = $oAttDef->IsNullAllowed() ? Dict::S('UI:Schema:NullAllowed') : Dict::S('UI:Schema:NullNotAllowed');
$sMoreInfo .= implode(', ', $aMoreInfo);
}
-
+ $sAttrCode = $oAttDef->GetCode();
+ $sIsEnumValues = 'false';
+ $sAllowedValuesEscpd = '';
if ($oAttDef instanceof AttributeEnum)
{
// Display localized values for the enum (which depend on the localization provided by the class)
@@ -446,61 +748,97 @@ function DisplayClassDetails($oPage, $sClass, $sContext)
$aDescription = array();
foreach($aLocalizedValues as $val => $sDisplay)
{
- $aDescription[] = htmlentities("$val => ", ENT_QUOTES, 'UTF-8').$sDisplay;
+ $aDescription[] = "". $sDisplay ." ( " . $val . " ) ";
}
$sAllowedValues = implode(', ', $aDescription);
+ $sIsEnumValues = 'true';
}
elseif (is_object($oAllowedValuesDef = $oAttDef->GetValuesDef()))
{
- $sAllowedValues = $oAllowedValuesDef->GetValuesDescription();
- }
+ $sAllowedValues = trim( $oAllowedValuesDef->GetValuesDescription(), "Filter : ");
+ $sAllowedValuesEscpd = str_replace("'","\'",$sAllowedValues);
+
+ $sFilterURL = urlencode($sAllowedValues);
+ $sAllowedValues = "⚵ " . Dict::S('UI:Schema:Attribute/Filter') . " ";
+ }
else
{
$sAllowedValues = '';
}
+ $sAttrValueEscpd = htmlentities($sValue,ENT_QUOTES,"UTF-8");
+ $sAttrTypeDescEscpd = htmlentities($sValue,ENT_QUOTES,"UTF-8");
+ $sAttrOriginEscpd = htmlentities($sValue,ENT_QUOTES,"UTF-8");
+
+ $aDetails[] = array('code' => "". $oAttDef->GetLabel() ." ( " . $oAttDef->GetCode() ." ) ",
+ 'type' => "". $sTypeDict ." ( " . $sType ." ) ",
+ 'origincolor' => " ",
+ 'origin' => "$sOrigin ",
+ 'values' => $sAllowedValues,
+ 'moreinfo' => $sMoreInfo);
+ //tooltip construction
+ $oPage->add_ready_script(
+ << $oAttDef->GetCode(), 'type' => $sType, 'origin' => $sOrigin, 'label' => $oAttDef->GetLabel(), 'description' => $sValue, 'values' => $sAllowedValues, 'moreinfo' => $sMoreInfo);
- }
$oPage->SetCurrentTab(Dict::S('UI:Schema:Attributes'));
- $aConfig = array( 'code' => array('label' => Dict::S('UI:Schema:AttributeCode'), 'description' => Dict::S('UI:Schema:AttributeCode+')),
- 'label' => array('label' => Dict::S('UI:Schema:Label'), 'description' => Dict::S('UI:Schema:Label+')),
+ $aConfig = array( 'origincolor' => array('label' => "", 'description' => ""),
+ 'code' => array('label' => Dict::S('UI:Schema:AttributeCode'), 'description' => Dict::S('UI:Schema:AttributeCode+')),
'type' => array('label' => Dict::S('UI:Schema:Type'), 'description' => Dict::S('UI:Schema:Type+')),
- 'origin' => array('label' => Dict::S('UI:Schema:Origin'), 'description' => Dict::S('UI:Schema:Origin+')),
- 'description' => array('label' => Dict::S('UI:Schema:Description'), 'description' => Dict::S('UI:Schema:Description+')),
'values' => array('label' => Dict::S('UI:Schema:AllowedValues'), 'description' => Dict::S('UI:Schema:AllowedValues+')),
'moreinfo' => array('label' => Dict::S('UI:Schema:MoreInfo'), 'description' => Dict::S('UI:Schema:MoreInfo+')),
+ 'origin' => array('label' => Dict::S('UI:Schema:Origin'), 'description' => Dict::S('UI:Schema:Origin+')),
);
$oPage->table($aConfig, $aDetails);
+ $sOrigins = json_encode(array_keys($aOrigins));
- // List the search criteria for this object
- $aDetails = array();
- foreach (MetaModel::GetClassFilterDefs($sClass) as $sFilterCode => $oFilterDef)
- {
- $aOpDescs = array();
- foreach ($oFilterDef->GetOperators() as $sOpCode => $sOpDescription)
- {
- $sIsTheLooser = ($sOpCode == $oFilterDef->GetLooseOperator()) ? " (loose search)" : "";
- $aOpDescs[] = "$sOpCode ($sOpDescription)$sIsTheLooser";
- }
- $aDetails[] = array( 'code' => $sFilterCode, 'description' => $oFilterDef->GetLabel(),'operators' => implode(" / ", $aOpDescs));
- }
- $oPage->SetCurrentTab(Dict::S('UI:Schema:SearchCriteria'));
- $aConfig = array( 'code' => array('label' => Dict::S('UI:Schema:FilterCode'), 'description' => Dict::S('UI:Schema:FilterCode+')),
- 'description' => array('label' => Dict::S('UI:Schema:FilterDescription'), 'description' => Dict::S('UI:Schema:FilterDescription+')),
- 'operators' => array('label' => Dict::S('UI:Schema:AvailOperators'), 'description' => Dict::S('UI:Schema:AvailOperators+'))
- );
- $oPage->table($aConfig, $aDetails);
+ //color calculation in order to keep 1 color for 1 extended class. Colors are interpolated and will be used for
+ // graph scheme color too
+ $oPage->add_ready_script(
+ <<< EOF
+ var aOrigins = $sOrigins;
+ var aColors = d3.scale.linear().domain([1,aOrigins.length])
+ .interpolate(d3.interpolateHcl)
+ .range([d3.rgb("#007AFF"), d3.rgb('#FFF500')]);
+ for(var origin of aOrigins)
+ {
+ console.log($('#originColor'+origin).parent());
+ $('.originColor'+origin).parent().css('background-color',aColors(aOrigins.indexOf(origin)));
+ }
+ console.log($(".listResults").find('td:nth-child(1),th:nth-child(1)'));
+ Array.prototype.forEach.call($(".listResults").find('td:nth-child(1),th:nth-child(1)'), e =>{
+ console.log($(e).attr("class"));
+ $(e).removeClass("header").addClass("originColor");
+ console.log($(e).attr("class"));
- $oPage->SetCurrentTab(Dict::S('UI:Schema:ChildClasses'));
- DisplaySubclasses($oPage, $sClass, $sContext);
+ }
+ );
- $oPage->SetCurrentTab(Dict::S('UI:Schema:ReferencingClasses'));
- DisplayReferencingClasses($oPage, $sClass, $sContext);
+EOF
+ );
- $oPage->SetCurrentTab(Dict::S('UI:Schema:RelatedClasses'));
- DisplayRelatedClasses($oPage, $sClass, $sContext);
+ $oPage->SetCurrentTab(Dict::S('UI:Schema:RelatedClasses'));
+ DisplayRelatedClassesGraph($oPage, $sClass);
+ $oPage->SetCurrentTab(Dict::S('UI:Schema:ChildClasses'));
- $oPage->SetCurrentTab(Dict::S('UI:Schema:LifeCycle'));
+ DisplaySubclasses($oPage, $sClass, $sContext);
+
+ $oPage->SetCurrentTab(Dict::S('UI:Schema:LifeCycle'));
DisplayLifecycle($oPage, $sClass, $sContext);
$oPage->SetCurrentTab(Dict::S('UI:Schema:Triggers'));
@@ -511,53 +849,9 @@ function DisplayClassDetails($oPage, $sClass, $sContext)
}
-/**
- * Display the details of a given relation (e.g. "impacts")
- */
-function DisplayRelationDetails($oPage, $sRelCode, $sContext)
-{
- $sDesc = MetaModel::GetRelationDescription($sRelCode);
- $sLabel = MetaModel::GetRelationLabel($sRelCode);
- $oPage->add("".Dict::Format('UI:Schema:Relation_Code_Description', $sRelCode, $sDesc)." ");
- $oPage->p(Dict::Format('UI:Schema:RelationUp_Description', $sLabel));
-
- $oPage->add("\n");
- foreach(MetaModel::GetClasses() as $sClass)
- {
- $aRelQueries = MetaModel::EnumRelationQueries($sClass, $sRelCode);
- if (count($aRelQueries) > 0)
- {
- $oPage->add("class ".MakeClassHLink($sClass, $sContext)."\n");
- $oPage->add("\n");
- foreach ($aRelQueries as $sRelKey => $aQuery)
- {
- $sQueryDown = isset($aQuery['sQueryDown']) ? $aQuery['sQueryDown'] : '';
- $sQueryUp = isset($aQuery['sQueryUp']) ? $aQuery['sQueryUp'] : '';
- $sAttribute = isset($aQuery['sAttribute']) ? $aQuery['sAttribute'] : '';
- /*
- if ($aQuery['bPropagate'])
- {
- $oPage->add("".Dict::Format('UI:Schema:RelationPropagates', $sRelKey, $iDistance, $sQuery)." \n");
- }
- else
- {
- $oPage->add("".Dict::Format('UI:Schema:RelationDoesNotPropagate', $sRelKey, $iDistance, $sQuery)." \n");
- }
- */
- $sLabel = (strlen($sQueryDown) > 0) ? $sQueryDown : $sAttribute;
- if ($aQuery['_legacy_'])
- {
- $sLabel .= ' (Old style specification : it is recommended to upgrade to XML)';
- }
- $oPage->add("".$sLabel." \n");
- }
- $oPage->add(" \n");
- $oPage->add(" \n");
- }
- }
- $oPage->add_ready_script('$("#RelationshipDetails").treeview();');
-}
-
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MAIN BLOCK //
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Display the menu on the left
$oAppContext = new ApplicationContext();
@@ -572,25 +866,103 @@ $oPage = new iTopWebPage(Dict::S('UI:Schema:Title'));
$oPage->no_cache();
$oPage->SetBreadCrumbEntry('ui-tool-datamodel', Dict::S('Menu:DataModelMenu'), Dict::S('Menu:DataModelMenu+'), '', utils::GetAbsoluteUrlAppRoot().'images/wrench.png');
+$oPage->add_script(
+ <<add("
");
+$oPage->add("
");
+DisplayClassesList($oPage, $sContext);
+$oPage->add("
");
+$oPage->add("
");
+$oPage->add("
+ ". Dict::S('UI:Schema:DisplayLabel') .
+ "
+ " . Dict::S('UI:Schema:DisplaySelector/LabelAndCode') . "
+ " . Dict::S('UI:Schema:DisplaySelector/Label') . "
+ " . Dict::S('UI:Schema:DisplaySelector/Code') . "
+
+ ");
+$sDisplayDropDownValue = htmlentities(appUserPreferences::GetPref('datamodel_viewer_display_granularity','labelandcode'),ENT_QUOTES,"UTF-8");
+$sClass = utils::ReadParam('class', 'logRealObject', false, 'class');
+
+//granularity displayer listener
+$oPage->add_ready_script(
+ <<add("
");
+$oPage->add("
");
+
+//split the page in 2 panels
+$oPage->add_ready_script(
+<<output();
?>