various features and improvements

This commit is contained in:
Michael Becker 2024-01-20 00:54:03 -05:00
parent 0e346c9ac0
commit d7f2091c48
15 changed files with 280 additions and 90 deletions

View File

@ -42,7 +42,7 @@
singular: yes singular: yes
- getReferencedAttributeMethod: '&IDM_User__get__Preferred_Display_Name_-_Given_Name;' - getReferencedAttributeMethod: '&IDM_User__get__Preferred_Display_Name_-_Given_Name;'
forClassId: '&IDC_User;' forClassId: '&IDC_PersonName;'
returnsAttributeId: '&IDA_Value;' returnsAttributeId: '&IDA_Value;'
verb: 'get' verb: 'get'
name: 'Preferred Display Name - Given Name' name: 'Preferred Display Name - Given Name'
@ -54,7 +54,7 @@
executesMethod: '&IDM_User__get__Preferred_Display_Name_-_Given_Name;' executesMethod: '&IDM_User__get__Preferred_Display_Name_-_Given_Name;'
- getReferencedAttributeMethod: '&IDM_User__get__Preferred_Display_Name_-_Family_Name;' - getReferencedAttributeMethod: '&IDM_User__get__Preferred_Display_Name_-_Family_Name;'
forClassId: '&IDC_User;' forClassId: '&IDC_PersonName;'
returnsAttributeId: '&IDA_Value;' returnsAttributeId: '&IDA_Value;'
verb: 'get' verb: 'get'
name: 'Preferred Display Name - Family Name' name: 'Preferred Display Name - Family Name'

View File

@ -160,11 +160,23 @@
} }
return null; return null;
} }
private $_instanceTextCache;
public function getInstanceText($inst) public function getInstanceText($inst)
{ {
if ($inst === null) if ($inst === null)
return "ERR: inst null"; return "ERR: inst null";
if ($this->_instanceTextCache === null)
{
$this->_instanceTextCache = array();
}
if (array_key_exists($inst->GlobalIdentifier->__toString(), $this->_instanceTextCache))
{
return $this->_instanceTextCache[$inst->GlobalIdentifier->__toString()];
}
$parentClass = $this->getParentClass($inst); $parentClass = $this->getParentClass($inst);
if ($parentClass === null) if ($parentClass === null)
{ {
@ -184,6 +196,7 @@
$text = $context->getWorkData($textAttr); $text = $context->getWorkData($textAttr);
//$this->printWorkData($context->workData); //$this->printWorkData($context->workData);
$this->_instanceTextCache[$inst->GlobalIdentifier->__toString()] = $text;
return $text; return $text;
} }
else else

View File

@ -8,6 +8,8 @@
use Mocha\Oms\MySQLDatabaseOms; use Mocha\Oms\MySQLDatabaseOms;
use Phast\HTMLControl; use Phast\HTMLControl;
use Phast\HTMLControls\Input;
use Phast\HTMLControls\InputType;
use Phast\System; use Phast\System;
use Phast\WebControl; use Phast\WebControl;
use Phast\WebControlAttribute; use Phast\WebControlAttribute;
@ -33,6 +35,7 @@
public array $SelectedInstances; public array $SelectedInstances;
public array $ValidClasses; public array $ValidClasses;
public string $Title; public string $Title;
public $TargetUrl;
public function __construct(array $instanceReferences = null) public function __construct(array $instanceReferences = null)
{ {
@ -179,9 +182,8 @@
} }
*/ */
$txt = new WebControl(); $txt = new Input();
$txt->TagName = "input"; $txt->Type = InputType::Text;
$txt->Attributes[] = new WebControlAttribute("type", "text");
$this->Controls[] = $txt; $this->Controls[] = $txt;
$ul = new WebControl(); $ul = new WebControl();

View File

@ -17,6 +17,8 @@
use Mocha\UI\Controls\InstanceBrowser; use Mocha\UI\Controls\InstanceBrowser;
use Mocha\UI\ValidationResult; use Mocha\UI\ValidationResult;
use Phast\HTMLControls\Input;
use Phast\HTMLControls\InputType;
use Phast\QuickSort; use Phast\QuickSort;
use Phast\System; use Phast\System;
use Phast\Utilities\Stopwatch; use Phast\Utilities\Stopwatch;
@ -148,10 +150,18 @@
$this->renderBeginTag("div", [ ], [ "uwt-header-item", "uwt-searchbar" ]); $this->renderBeginTag("div", [ ], [ "uwt-header-item", "uwt-searchbar" ]);
$searchText = new WebControl(); $this->renderBeginTag("form", [ "method" => "GET", "action" => System::ExpandRelativePath("~/d/search.htmld") ]);
$searchText->TagName = "input"; $searchText = new Input();
$searchText->Attributes[] = new WebControlAttribute("type", "text"); $searchText->Type = InputType::Text;
$searchText->ClientID = "mcx-primary-search";
$searchText->Name = "q";
$searchText->Render(); $searchText->Render();
$this->renderEndTag("form");
$this->renderBeginTag("div", [ ], [ "uwt-popup", "mcx-primary-search-results" ]);
$this->renderBeginTag("ul", [ ], [ "uwt-menu" ]);
$this->renderEndTag("ul");
$this->renderEndTag("div");
$this->renderEndTag("div"); $this->renderEndTag("div");
@ -462,7 +472,7 @@
//|| $oms->is_a($ecInst, KnownClassGuids::DateAttribute)) //|| $oms->is_a($ecInst, KnownClassGuids::DateAttribute))
) )
{ {
return $oms->getAttributeValue($relatedInstance, $ecInst) === null; return $oms->getAttributeValue($relatedInstance, $ecInst) === null && $oms->getAttributeValue($ecInst, KnownAttributeGuids::Value) === null;
} }
// Executable returning Attribute // Executable returning Attribute
else if ($oms->is_a($ecInst, KnownClassGuids::ReturnAttributeMethodBinding)) else if ($oms->is_a($ecInst, KnownClassGuids::ReturnAttributeMethodBinding))
@ -792,7 +802,7 @@
$adw->Render(); $adw->Render();
// echo ("<span class=\"mcx-value\">unknown pclass ident " . $oms->getParentClass($ecInst)->GlobalIdentifier . "</span>"); // echo ("<span class=\"mcx-value\">unknown pclass ident " . $oms->getParentClass($ecInst)->GlobalIdentifier . "</span>");
} }
echo ("</td>"); //echo ("</td>");
} }
} }
} }
@ -884,12 +894,12 @@
$ecid = $ec->InstanceKey; $ecid = $ec->InstanceKey;
$p = new \Phast\WebControl(); $p = new Input();
$p->TagName = "input"; $p->Type = InputType::Text;
$p->ClientID = "ec_" . $ecid; $p->ClientID = "ec_" . $ecid;
$p->Attributes[] = new \Phast\WebControlAttribute("name", "ec_" . $ecid); $p->Name = "ec_" . $ecid;
$p->Attributes[] = new \Phast\WebControlAttribute("data-ecid", $ecid); $p->Attributes[] = new WebControlAttribute("data-ecid", $ecid);
$p->Attributes[] = new \Phast\WebControlAttribute("value", $value); $p->Value = $value;
if ($oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__Required))) if ($oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__Required)))
{ {
@ -905,13 +915,10 @@
{ {
$p->Attributes[] = new \Phast\WebControlAttribute("maxlength", $maxLength); $p->Attributes[] = new \Phast\WebControlAttribute("maxlength", $maxLength);
} }
$p->HasContent = false;
$attType = new \Phast\WebControlAttribute("type", "text");
if ($password) if ($password)
{ {
$attType->Value = "password"; $p->Type = InputType::Password;
} }
$p->Attributes[] = $attType;
$p->Render(); $p->Render();
} }
@ -926,16 +933,15 @@
$ecid = $ec->InstanceKey; $ecid = $ec->InstanceKey;
$p = new \Phast\WebControl(); $p = new Input();
$p->TagName = "input"; $p->Type = InputType::CheckBox;
$p->ClientID = "ec_" . $ecid; $p->ClientID = "ec_" . $ecid;
$p->Attributes[] = new \Phast\WebControlAttribute("name", "ec_" . $ecid); $p->Name = "ec_" . $ecid;
$p->Attributes[] = new \Phast\WebControlAttribute("data-ecid", $ecid); $p->Attributes[] = new WebControlAttribute("data-ecid", $ecid);
if ($value == "1") if ($value == "1")
{ {
$p->Attributes[] = new \Phast\WebControlAttribute("checked", "checked"); $p->Checked = true;
} }
$p->Attributes[] = new \Phast\WebControlAttribute("type", "checkbox");
if ($oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__Required))) if ($oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__Required)))
{ {
@ -949,15 +955,13 @@
$maxLength = $oms->getAttributeValue($inst, KnownAttributeGuids::MaximumLength); $maxLength = $oms->getAttributeValue($inst, KnownAttributeGuids::MaximumLength);
if ($maxLength !== null) if ($maxLength !== null)
{ {
$p->Attributes[] = new \Phast\WebControlAttribute("maxlength", $maxLength); $p->Attributes[] = new WebControlAttribute("maxlength", $maxLength);
} }
$p->HasContent = false; $p->HasContent = false;
$attType = new \Phast\WebControlAttribute("type", "text");
if ($password) if ($password)
{ {
$attType->Value = "password"; $p->Type = InputType::Password;
} }
$p->Attributes[] = $attType;
$p->Render(); $p->Render();
} }

View File

@ -158,10 +158,14 @@ function McxInstanceBrowser(parentElement)
} }
}); });
var moniker = McxMoniker.create(json.items[i].iid, json.items[i].title);
/*
var span = document.createElement("span"); var span = document.createElement("span");
span.className = "uwt-title uwt-description-empty"; span.className = "uwt-title uwt-description-empty";
span.innerText = json.items[i].title; span.innerText = json.items[i].title;
li.appendChild(span); li.appendChild(span);
*/
li.appendChild(moniker);
this.NativeObject.SearchResultsMenuElement.appendChild(li); this.NativeObject.SearchResultsMenuElement.appendChild(li);
} }

View File

@ -139,7 +139,7 @@ function McxMoniker(parentElement)
} }
} }
]; ];
cm.Show(e.clientX, e.clientY, this); cm.Show(e.clientX, e.clientY, document.body);
e.preventDefault(); e.preventDefault();
@ -268,6 +268,7 @@ function McxMoniker(parentElement)
} }
System.ClassList.Remove(xhr.thiss.PopupElement, "uwt-loading"); System.ClassList.Remove(xhr.thiss.PopupElement, "uwt-loading");
xhr.thiss.ParentElement.NativeObject.UpdatePopupLocation();
} }
else if (xhr.status == 403) else if (xhr.status == 403)
{ {

View File

@ -0,0 +1,87 @@
function McxPrimarySearch(parentElement)
{
this.ParentElement = parentElement;
this.FormElement = this.ParentElement.children[0];
this.TextBoxElement = this.FormElement.children[0];
this.PopupElement = this.ParentElement.children[1];
this.MenuElement = this.PopupElement.children[0];
this.clearSearchResults = function()
{
while (this.MenuElement.children.length > 0)
{
this.MenuElement.children[0].remove();
}
};
this.search = function(query)
{
var xhr = new XMLHttpRequest();
var searchUrl = System.ExpandRelativePath("~/" + System.TenantName + "/search.htmld?q=" + encodeURIComponent(query));
/*
if (this.ParentElement.hasAttribute("data-valid-class-ids"))
{
searchUrl += "&validClassIds=" + this.ParentElement.getAttribute("data-valid-class-ids");
}
*/
xhr.open("GET", searchUrl, true);
xhr.NativeObject = this;
xhr.onreadystatechange = function()
{
if (this.readyState === 4)
{
var resultsText = this.responseText;
var json = JSON.parse(resultsText);
if (json.result === "success")
{
this.NativeObject.clearSearchResults();
for (var i = 0; i < json.items.length; i++)
{
var li = document.createElement("li");
li.className = "uwt-menu-item uwt-menu-item-command uwt-visible";
li.searchResult = json.items[i];
li.NativeObject = this.NativeObject;
li.addEventListener("click", function()
{
if (this.NativeObject.activateSearchResult(this.searchResult))
{
this.NativeObject.setEditing(false);
}
});
var span = document.createElement("span");
span.className = "uwt-title uwt-description-empty";
span.innerText = json.items[i].title;
li.appendChild(span);
this.NativeObject.MenuElement.appendChild(li);
}
System.ClassList.Remove(this.NativeObject.PopupElement, "uwt-loading");
}
else
{
if (json.responseCode === 403)
{
Alert.show("Please log in to continue", "Not Authorized", "uwt-color-danger");
}
System.ClassList.Remove(this.NativeObject.PopupElement, "uwt-loading");
}
}
};
xhr.send(null);
};
this.TextBoxElement.NativeObject = this;
this.TextBoxElement.addEventListener("keydown", function(e)
{
this.NativeObject.search(this.value);
});
}
window.addEventListener("load", function()
{
var primarySearch = document.getElementsByClassName("uwt-searchbar");
primarySearch[0].NativeObject = new McxPrimarySearch(primarySearch[0]);
});

View File

@ -6,7 +6,8 @@ body
&> div.uwt-header-item &> div.uwt-header-item
{ {
&> input position: relative;
input[type=text]
{ {
background-color: #f2f3f4; background-color: #f2f3f4;
border-color: #f2f3f4; border-color: #f2f3f4;
@ -29,12 +30,12 @@ body
font-size: 0.75rem; font-size: 0.75rem;
font-weight: 900; font-weight: 900;
position: relative; position: absolute;
margin-left: -16px; margin-left: -16px;
left: 28px; left: 28px;
top: 0; top: 10px;
} }
&> input input
{ {
border-radius: 30px; border-radius: 30px;
border: 1px solid #d5dbe0; border: 1px solid #d5dbe0;
@ -160,16 +161,16 @@ body.uwt-header-inverse
} }
&.uwt-searchbar &.uwt-searchbar
{ {
&> input input
{ {
border-color: transparent; border-color: transparent;
} }
div.uwt-textbox-popup div.uwt-popup
{ {
background-color: #1a2229; background-color: #1a2229;
} }
} }
&> input input
{ {
background-color: rgba(255,255,255,.25); background-color: rgba(255,255,255,.25);
color: #fff; color: #fff;

View File

@ -13,9 +13,9 @@ div.uwt-alert
margin-left: auto; margin-left: auto;
margin-bottom: 8px; margin-bottom: 8px;
position: relative; position: relative;
transition: all 1s, scale 0.3s; transition: all 0.5s, scale 0.3s;
right: 0px; right: 0px;
width: 400px; width: 600px;
&.uwt-collapsible &.uwt-collapsible
{ {

View File

@ -51,7 +51,8 @@ table.uwt-formview
/* V2 FormView - now more FLEXible! */ /* V2 FormView - now more FLEXible! */
div.uwt-formview div.uwt-formview
{ {
display: table; display: grid;
// display: table;
/* /*
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -64,13 +65,13 @@ div.uwt-formview
align-items: center; align-items: center;
align-content: center; align-content: center;
*/ */
display: table-row; // display: table-row;
vertical-align: middle; vertical-align: middle;
padding: 16px; padding: 16px;
&> div.uwt-formview-item-label &> div.uwt-formview-item-label
{ {
display: table-cell; // display: table-cell;
vertical-align: middle; vertical-align: middle;
padding-right: 32px; padding-right: 32px;
@ -85,7 +86,7 @@ div.uwt-formview
} }
&> div.uwt-formview-item-content &> div.uwt-formview-item-content
{ {
display: table-cell; // display: table-cell;
vertical-align: middle; vertical-align: middle;
} }
} }

View File

@ -31,14 +31,17 @@ ul.uwt-menu
} }
} }
} }
&:hover, &.uwt-highlight &.uwt-menu-item-command
{ {
background-color: rgba(0, 0, 0, 0.05); // var(--uwt-dropdown-menu-highlight-background); &:hover, &.uwt-highlight
color: var(--uwt-dropdown-menu-highlight-foreground);
&> a
{ {
background-color: inherit; background-color: rgba(0, 0, 0, 0.03); // var(--uwt-dropdown-menu-highlight-background);
color: inherit; color: var(--uwt-dropdown-menu-highlight-foreground);
&> a
{
background-color: inherit;
color: inherit;
}
} }
} }
&.uwt-separator &.uwt-separator

View File

@ -1,6 +1,6 @@
body, body > form body, body > form
{ {
&> div.uwt-header > div.uwt-header-item.uwt-searchbar > div.uwt-popup &> div.uwt-header > div.uwt-header-item.uwt-searchbar div.uwt-popup
{ {
&:not(.uwt-loading) > div.uwt-spinner &:not(.uwt-loading) > div.uwt-spinner
{ {

View File

@ -184,3 +184,8 @@ div.uwt-center
{ {
display: none; display: none;
} }
body.uwt-prevent-scrolling
{
overflow: hidden !important;
}

View File

@ -133,9 +133,13 @@ div.mcx-instancebrowser
cursor: pointer; cursor: pointer;
&> div.uwt-actionpreviewbutton &> div.uwt-actionpreviewbutton
{ {
position: absolute; display: block;
right: 10px; &> a.apb-button
top: 6px; {
position: absolute;
right: 10px;
top: 0px;
}
} }
&:hover &:hover
{ {

View File

@ -7,11 +7,76 @@
use Mocha\Core\KnownClassGuids; use Mocha\Core\KnownClassGuids;
use Mocha\Core\KnownInstanceGuids; use Mocha\Core\KnownInstanceGuids;
use Mocha\Core\KnownRelationshipGuids; use Mocha\Core\KnownRelationshipGuids;
use Mocha\UI\Controls\InstanceBrowser;
use Phast\CancelEventArgs; use Phast\CancelEventArgs;
use Phast\RenderingEventArgs; use Phast\RenderingEventArgs;
use Phast\System; use Phast\System;
use Phast\WebPage; use Phast\WebPage;
class OmsSearchResult
{
public $Title;
public $Instance;
public function __construct($instance, $title)
{
$this->Instance = $instance;
$this->Title = $title;
}
}
class SearchHelper
{
private $_OMS;
public function __construct($oms)
{
$this->_OMS = $oms;
$this->ValidClasses = [ ];
}
public $ValidClasses;
public function search(string $query)
{
$oms = $this->_OMS;
$insts = [];
$validClasses = $this->ValidClasses;
if (count($validClasses) === 0)
{
$validClasses = array
(
$oms->getInstanceByGlobalIdentifier(KnownClassGuids::Clasz),
$oms->getInstanceByGlobalIdentifier(KnownClassGuids::Task),
$oms->getInstanceByGlobalIdentifier(KnownClassGuids::SequenceTask)
);
}
foreach ($validClasses as $validClass)
{
$insts2 = $oms->getInstancesOf($validClass);
foreach ($insts2 as $inst2)
{
$insts[] = $inst2;
}
}
$insts = array_unique($insts, SORT_REGULAR);
$count = count($insts);
$results = array();
foreach ($insts as $inst)
{
$title = $oms->getInstanceText($inst);
if (!str_contains(strtolower($title), strtolower($query)))
{
continue;
}
$searchResult = new OmsSearchResult($inst, $title);
$results[] = $searchResult;
}
return $results;
}
}
class SearchPage extends WebPage class SearchPage extends WebPage
{ {
protected function OnRendering(RenderingEventArgs $re) protected function OnRendering(RenderingEventArgs $re)
@ -22,13 +87,38 @@
if (InstanceKey::TryParse($query, $inst)) if (InstanceKey::TryParse($query, $inst))
{ {
System::Redirect("~/d/inst/1\$" . $inst->ClassIndex . "/" . $inst->__toString() . ".htmld"); System::Redirect("~/d/inst/1\$" . $inst->ClassIndex . "/" . $inst->__toString() . ".htmld");
$re->Handled = true;
return false;
} }
return true;
} }
protected function RenderContents() protected function RenderContents()
{ {
?> ?>
<h1>Search Results</h1> <h1>Search Results</h1>
<ul class="uwt-menu">
<?php
/** @var \Mocha\Oms\MySQLDatabaseOMS */
$oms = mocha_get_oms();
$searchHelper = new SearchHelper($oms);
$results = $searchHelper->search($_GET["q"]);
foreach ($results as $result)
{
?>
<li class="uwt-menu-item uwt-menu-item-command uwt-visible">
<?php
$adw = new InstanceBrowser();
$adw->SelectedInstances[] = $result->Instance;
$adw->Render();
?>
</li>
<?php
}
?>
</ul>
<?php <?php
} }
} }
@ -61,54 +151,29 @@
return true; return true;
} }
$insts = []; $searchHelper = new SearchHelper($oms);
$validClassIdsStr = $_GET["validClassIds"]; $validClassIdsStr = $_GET["validClassIds"];
if ($validClassIdsStr == "1$17") if ($validClassIdsStr !== null && $validClassIdsStr !== "1$17")
{
$insts = $oms->getInstances();
}
else
{ {
$validClassIdsParm = explode(",", $_GET["validClassIds"]); $validClassIdsParm = explode(",", $_GET["validClassIds"]);
$validClassIds = []; $validClasses = [];
foreach ($validClassIdsParm as $validClassIdParm) foreach ($validClassIdsParm as $validClassIdParm)
{ {
$validClassIds[] = $validClassIdParm; $validClasses[] = $oms->getInstanceByKey(InstanceKey::parse($validClassIdParm));
$instClass = $oms->getInstanceByKey(InstanceKey::parse($validClassIdParm)); $instClass = $oms->getInstanceByKey(InstanceKey::parse($validClassIdParm));
$subclasses = $oms->getRelatedInstances($instClass, KnownRelationshipGuids::Class__has_sub__Class); $subclasses = $oms->getRelatedInstances($instClass, KnownRelationshipGuids::Class__has_sub__Class);
foreach ($subclasses as $subclass) foreach ($subclasses as $subclass)
{ {
$validClassIds[] = $subclass->InstanceKey->__toString(); $validClasses[] = $subclass;
} }
} }
$searchHelper->ValidClasses = $validClasses;
foreach ($validClassIds as $validClassId)
{
$insts2 = $oms->getInstancesOf(InstanceKey::parse($validClassId));
foreach ($insts2 as $inst2)
{
$insts[] = $inst2;
}
}
$insts = array_unique($insts, SORT_REGULAR);
} }
$count = count($insts); $query = $_GET["q"];
$results = array(); $results = $searchHelper->search($query);
$titles = [];
foreach ($insts as $inst)
{
$title = $oms->getInstanceText($inst);
if (!str_contains(strtolower($title), $_GET["q"]))
{
continue;
}
$results[] = $inst;
$titles[] = $title;
}
$query = strtolower($_GET["q"]);
$count = count($results); $count = count($results);
if ($count > 50) if ($count > 50)
{ {
@ -134,10 +199,10 @@
echo ("{ \"result\": \"success\", \"items\": [ "); echo ("{ \"result\": \"success\", \"items\": [ ");
for ($i = 0; $i < $count; $i++) for ($i = 0; $i < $count; $i++)
{ {
$inst = $results[$i]; $inst = $results[$i]->Instance;
$instClass = $oms->getParentClass($inst); $instClass = $oms->getParentClass($inst);
$viewTask = $oms->getRelatedInstance($instClass, KnownRelationshipGuids::Class__has_default__Task); $viewTask = $oms->getRelatedInstance($instClass, KnownRelationshipGuids::Class__has_default__Task);
$instJson = array("iid" => $inst->InstanceKey->__toString(), "title" => $titles[$i], "viewTask" => $viewTask === null ? null : $viewTask->InstanceKey->__toString()); $instJson = array("iid" => $inst->InstanceKey->__toString(), "title" => $results[$i]->Title, "viewTask" => $viewTask === null ? null : $viewTask->InstanceKey->__toString());
echo (json_encode($instJson)); echo (json_encode($instJson));
if ($i < $count - 1) if ($i < $count - 1)
{ {