diff --git a/common/libraries/yaml/net.alcetech.Mocha.System/004-Methods/User/System_User__get__Preferred_Display_Name.yaml b/common/libraries/yaml/net.alcetech.Mocha.System/004-Methods/User/System_User__get__Preferred_Display_Name.yaml index d1b1f06..bcb9c4c 100644 --- a/common/libraries/yaml/net.alcetech.Mocha.System/004-Methods/User/System_User__get__Preferred_Display_Name.yaml +++ b/common/libraries/yaml/net.alcetech.Mocha.System/004-Methods/User/System_User__get__Preferred_Display_Name.yaml @@ -42,7 +42,7 @@ singular: yes - getReferencedAttributeMethod: '&IDM_User__get__Preferred_Display_Name_-_Given_Name;' - forClassId: '&IDC_User;' + forClassId: '&IDC_PersonName;' returnsAttributeId: '&IDA_Value;' verb: 'get' name: 'Preferred Display Name - Given Name' @@ -54,7 +54,7 @@ executesMethod: '&IDM_User__get__Preferred_Display_Name_-_Given_Name;' - getReferencedAttributeMethod: '&IDM_User__get__Preferred_Display_Name_-_Family_Name;' - forClassId: '&IDC_User;' + forClassId: '&IDC_PersonName;' returnsAttributeId: '&IDA_Value;' verb: 'get' name: 'Preferred Display Name - Family Name' diff --git a/php/mocha/lib/mocha/oms/Oms.inc.php b/php/mocha/lib/mocha/oms/Oms.inc.php index f54c031..b693b0a 100644 --- a/php/mocha/lib/mocha/oms/Oms.inc.php +++ b/php/mocha/lib/mocha/oms/Oms.inc.php @@ -160,11 +160,23 @@ } return null; } + + private $_instanceTextCache; + public function getInstanceText($inst) { if ($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); if ($parentClass === null) { @@ -184,6 +196,7 @@ $text = $context->getWorkData($textAttr); //$this->printWorkData($context->workData); + $this->_instanceTextCache[$inst->GlobalIdentifier->__toString()] = $text; return $text; } else diff --git a/php/mocha/lib/mocha/ui/controls/InstanceBrowser.inc.php b/php/mocha/lib/mocha/ui/controls/InstanceBrowser.inc.php index ada8c04..bbb6b7c 100644 --- a/php/mocha/lib/mocha/ui/controls/InstanceBrowser.inc.php +++ b/php/mocha/lib/mocha/ui/controls/InstanceBrowser.inc.php @@ -8,6 +8,8 @@ use Mocha\Oms\MySQLDatabaseOms; use Phast\HTMLControl; + use Phast\HTMLControls\Input; + use Phast\HTMLControls\InputType; use Phast\System; use Phast\WebControl; use Phast\WebControlAttribute; @@ -33,6 +35,7 @@ public array $SelectedInstances; public array $ValidClasses; public string $Title; + public $TargetUrl; public function __construct(array $instanceReferences = null) { @@ -179,9 +182,8 @@ } */ - $txt = new WebControl(); - $txt->TagName = "input"; - $txt->Attributes[] = new WebControlAttribute("type", "text"); + $txt = new Input(); + $txt->Type = InputType::Text; $this->Controls[] = $txt; $ul = new WebControl(); diff --git a/php/mocha/lib/mocha/ui/renderers/html/HTMLRenderer.inc.php b/php/mocha/lib/mocha/ui/renderers/html/HTMLRenderer.inc.php index 59dd129..f394c8e 100644 --- a/php/mocha/lib/mocha/ui/renderers/html/HTMLRenderer.inc.php +++ b/php/mocha/lib/mocha/ui/renderers/html/HTMLRenderer.inc.php @@ -17,6 +17,8 @@ use Mocha\UI\Controls\InstanceBrowser; use Mocha\UI\ValidationResult; + use Phast\HTMLControls\Input; + use Phast\HTMLControls\InputType; use Phast\QuickSort; use Phast\System; use Phast\Utilities\Stopwatch; @@ -148,10 +150,18 @@ $this->renderBeginTag("div", [ ], [ "uwt-header-item", "uwt-searchbar" ]); - $searchText = new WebControl(); - $searchText->TagName = "input"; - $searchText->Attributes[] = new WebControlAttribute("type", "text"); + $this->renderBeginTag("form", [ "method" => "GET", "action" => System::ExpandRelativePath("~/d/search.htmld") ]); + $searchText = new Input(); + $searchText->Type = InputType::Text; + $searchText->ClientID = "mcx-primary-search"; + $searchText->Name = "q"; $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"); @@ -462,7 +472,7 @@ //|| $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 else if ($oms->is_a($ecInst, KnownClassGuids::ReturnAttributeMethodBinding)) @@ -792,7 +802,7 @@ $adw->Render(); // echo ("unknown pclass ident " . $oms->getParentClass($ecInst)->GlobalIdentifier . ""); } - echo (""); + //echo (""); } } } @@ -884,12 +894,12 @@ $ecid = $ec->InstanceKey; - $p = new \Phast\WebControl(); - $p->TagName = "input"; + $p = new Input(); + $p->Type = InputType::Text; $p->ClientID = "ec_" . $ecid; - $p->Attributes[] = new \Phast\WebControlAttribute("name", "ec_" . $ecid); - $p->Attributes[] = new \Phast\WebControlAttribute("data-ecid", $ecid); - $p->Attributes[] = new \Phast\WebControlAttribute("value", $value); + $p->Name = "ec_" . $ecid; + $p->Attributes[] = new WebControlAttribute("data-ecid", $ecid); + $p->Value = $value; if ($oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__Required))) { @@ -905,13 +915,10 @@ { $p->Attributes[] = new \Phast\WebControlAttribute("maxlength", $maxLength); } - $p->HasContent = false; - $attType = new \Phast\WebControlAttribute("type", "text"); if ($password) { - $attType->Value = "password"; + $p->Type = InputType::Password; } - $p->Attributes[] = $attType; $p->Render(); } @@ -926,17 +933,16 @@ $ecid = $ec->InstanceKey; - $p = new \Phast\WebControl(); - $p->TagName = "input"; + $p = new Input(); + $p->Type = InputType::CheckBox; $p->ClientID = "ec_" . $ecid; - $p->Attributes[] = new \Phast\WebControlAttribute("name", "ec_" . $ecid); - $p->Attributes[] = new \Phast\WebControlAttribute("data-ecid", $ecid); + $p->Name = "ec_" . $ecid; + $p->Attributes[] = new WebControlAttribute("data-ecid", $ecid); 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))) { $p->ClassList[] = "uwt-required"; @@ -949,15 +955,13 @@ $maxLength = $oms->getAttributeValue($inst, KnownAttributeGuids::MaximumLength); if ($maxLength !== null) { - $p->Attributes[] = new \Phast\WebControlAttribute("maxlength", $maxLength); + $p->Attributes[] = new WebControlAttribute("maxlength", $maxLength); } $p->HasContent = false; - $attType = new \Phast\WebControlAttribute("type", "text"); if ($password) { - $attType->Value = "password"; + $p->Type = InputType::Password; } - $p->Attributes[] = $attType; $p->Render(); } diff --git a/php/mocha/scripts/mcx-instancebrowser.js b/php/mocha/scripts/mcx-instancebrowser.js index f094567..0c790e4 100644 --- a/php/mocha/scripts/mcx-instancebrowser.js +++ b/php/mocha/scripts/mcx-instancebrowser.js @@ -158,10 +158,14 @@ function McxInstanceBrowser(parentElement) } }); + var moniker = McxMoniker.create(json.items[i].iid, json.items[i].title); + /* var span = document.createElement("span"); span.className = "uwt-title uwt-description-empty"; span.innerText = json.items[i].title; li.appendChild(span); + */ + li.appendChild(moniker); this.NativeObject.SearchResultsMenuElement.appendChild(li); } diff --git a/php/mocha/scripts/mcx-moniker.js b/php/mocha/scripts/mcx-moniker.js index 1fccab5..d6fc9c0 100644 --- a/php/mocha/scripts/mcx-moniker.js +++ b/php/mocha/scripts/mcx-moniker.js @@ -139,7 +139,7 @@ function McxMoniker(parentElement) } } ]; - cm.Show(e.clientX, e.clientY, this); + cm.Show(e.clientX, e.clientY, document.body); e.preventDefault(); @@ -268,6 +268,7 @@ function McxMoniker(parentElement) } System.ClassList.Remove(xhr.thiss.PopupElement, "uwt-loading"); + xhr.thiss.ParentElement.NativeObject.UpdatePopupLocation(); } else if (xhr.status == 403) { diff --git a/php/mocha/scripts/mcx-primary-search.js b/php/mocha/scripts/mcx-primary-search.js new file mode 100644 index 0000000..8687694 --- /dev/null +++ b/php/mocha/scripts/mcx-primary-search.js @@ -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]); +}); diff --git a/php/mocha/themes/avondale/uwt-header.less b/php/mocha/themes/avondale/uwt-header.less index 609280e..1790418 100644 --- a/php/mocha/themes/avondale/uwt-header.less +++ b/php/mocha/themes/avondale/uwt-header.less @@ -6,7 +6,8 @@ body &> div.uwt-header-item { - &> input + position: relative; + input[type=text] { background-color: #f2f3f4; border-color: #f2f3f4; @@ -29,12 +30,12 @@ body font-size: 0.75rem; font-weight: 900; - position: relative; + position: absolute; margin-left: -16px; left: 28px; - top: 0; + top: 10px; } - &> input + input { border-radius: 30px; border: 1px solid #d5dbe0; @@ -160,16 +161,16 @@ body.uwt-header-inverse } &.uwt-searchbar { - &> input + input { border-color: transparent; } - div.uwt-textbox-popup + div.uwt-popup { background-color: #1a2229; } } - &> input + input { background-color: rgba(255,255,255,.25); color: #fff; diff --git a/php/mocha/themes/common/styles/uwt-alert.less b/php/mocha/themes/common/styles/uwt-alert.less index 4b24f2d..26b43cb 100644 --- a/php/mocha/themes/common/styles/uwt-alert.less +++ b/php/mocha/themes/common/styles/uwt-alert.less @@ -13,9 +13,9 @@ div.uwt-alert margin-left: auto; margin-bottom: 8px; position: relative; - transition: all 1s, scale 0.3s; + transition: all 0.5s, scale 0.3s; right: 0px; - width: 400px; + width: 600px; &.uwt-collapsible { diff --git a/php/mocha/themes/common/styles/uwt-formview.less b/php/mocha/themes/common/styles/uwt-formview.less index 89c6be9..1305b08 100644 --- a/php/mocha/themes/common/styles/uwt-formview.less +++ b/php/mocha/themes/common/styles/uwt-formview.less @@ -51,7 +51,8 @@ table.uwt-formview /* V2 FormView - now more FLEXible! */ div.uwt-formview { - display: table; + display: grid; + // display: table; /* display: flex; flex-direction: column; @@ -64,13 +65,13 @@ div.uwt-formview align-items: center; align-content: center; */ - display: table-row; + // display: table-row; vertical-align: middle; padding: 16px; &> div.uwt-formview-item-label { - display: table-cell; + // display: table-cell; vertical-align: middle; padding-right: 32px; @@ -85,7 +86,7 @@ div.uwt-formview } &> div.uwt-formview-item-content { - display: table-cell; + // display: table-cell; vertical-align: middle; } } diff --git a/php/mocha/themes/common/styles/uwt-menu.less b/php/mocha/themes/common/styles/uwt-menu.less index 7b4f7bc..c6dfe14 100644 --- a/php/mocha/themes/common/styles/uwt-menu.less +++ b/php/mocha/themes/common/styles/uwt-menu.less @@ -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); - color: var(--uwt-dropdown-menu-highlight-foreground); - &> a + &:hover, &.uwt-highlight { - background-color: inherit; - color: inherit; + background-color: rgba(0, 0, 0, 0.03); // var(--uwt-dropdown-menu-highlight-background); + color: var(--uwt-dropdown-menu-highlight-foreground); + &> a + { + background-color: inherit; + color: inherit; + } } } &.uwt-separator diff --git a/php/mocha/themes/common/styles/uwt-searchbar.less b/php/mocha/themes/common/styles/uwt-searchbar.less index 70f93c5..17a8f0c 100644 --- a/php/mocha/themes/common/styles/uwt-searchbar.less +++ b/php/mocha/themes/common/styles/uwt-searchbar.less @@ -1,6 +1,6 @@ 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 { diff --git a/php/mocha/themes/common/styles/uwt.less b/php/mocha/themes/common/styles/uwt.less index 74eb1f4..014f3ef 100644 --- a/php/mocha/themes/common/styles/uwt.less +++ b/php/mocha/themes/common/styles/uwt.less @@ -183,4 +183,9 @@ div.uwt-center .uwt-nonexistent { display: none; +} + +body.uwt-prevent-scrolling +{ + overflow: hidden !important; } \ No newline at end of file diff --git a/php/mocha/themes/mocha/mcx-instancebrowser.less b/php/mocha/themes/mocha/mcx-instancebrowser.less index b3e1106..ed4aacb 100644 --- a/php/mocha/themes/mocha/mcx-instancebrowser.less +++ b/php/mocha/themes/mocha/mcx-instancebrowser.less @@ -133,9 +133,13 @@ div.mcx-instancebrowser cursor: pointer; &> div.uwt-actionpreviewbutton { - position: absolute; - right: 10px; - top: 6px; + display: block; + &> a.apb-button + { + position: absolute; + right: 10px; + top: 0px; + } } &:hover { diff --git a/php/mocha/ui/pages/SearchPage.phpx.php b/php/mocha/ui/pages/SearchPage.phpx.php index 2ecf534..46ba58c 100644 --- a/php/mocha/ui/pages/SearchPage.phpx.php +++ b/php/mocha/ui/pages/SearchPage.phpx.php @@ -7,11 +7,76 @@ use Mocha\Core\KnownClassGuids; use Mocha\Core\KnownInstanceGuids; use Mocha\Core\KnownRelationshipGuids; + use Mocha\UI\Controls\InstanceBrowser; use Phast\CancelEventArgs; use Phast\RenderingEventArgs; use Phast\System; 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 { protected function OnRendering(RenderingEventArgs $re) @@ -22,13 +87,38 @@ if (InstanceKey::TryParse($query, $inst)) { System::Redirect("~/d/inst/1\$" . $inst->ClassIndex . "/" . $inst->__toString() . ".htmld"); + $re->Handled = true; + return false; } + return true; } protected function RenderContents() { ?>