Skip to content

Commit

Permalink
[NEW_FEATURE] Event for page action buttons (#6090)
Browse files Browse the repository at this point in the history
Create a new Event for rendering action buttons on the Page Header.
  • Loading branch information
robertdown committed Jan 12, 2023
1 parent 3075a04 commit 1d23ff6
Show file tree
Hide file tree
Showing 7 changed files with 523 additions and 98 deletions.
2 changes: 1 addition & 1 deletion interface/main/finder/dynamic_finder.php
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ function persistCriteria(el, e) {
<div class="table-responsive">
<table class="table" class="border-0 display" id="pt_table">
<thead class="thead-dark">
<tr id="advanced_search" class="hideaway" style="display: none;">
<tr id="advanced_search" class="hideaway d-none">
<?php echo $header0; ?>
</tr>
<tr class="">
Expand Down
3 changes: 2 additions & 1 deletion interface/patient_file/summary/demographics.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,10 @@ function image_widget($doc_id, $doc_catg)
}

$arrOeUiSettings = array(
'page_id' => 'core.mrd',
'heading_title' => xl('Medical Record Dashboard'),
'include_patient_name' => true,
'expandable' => false,
'expandable' => true,
'expandable_files' => array(), //all file names need suffix _xpd
'action' => "", //conceal, reveal, search, reset, link or back
'action_title' => "",
Expand Down
93 changes: 93 additions & 0 deletions src/Events/UserInterface/ActionButtonInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

/**
* ActionButtonInterface defines the requirements to display an action button on pages that support OemrUI pageHeading().
*
* @package OpenEMR
* @subpackage Events
* @author Robert Down <robertdown@live.com>
* @copyright Copyright (c) 2023 Robert Down
* @copyright Copyright (c) 2023 Providence Healthtech
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
*/

namespace OpenEMR\Events\UserInterface;

interface ActionButtonInterface
{
/**
* Get the ID of the element, used to populate the ID attribute of the anchor element
*
* @return string
*/
public function getID();

/**
* Populate the title attribute of the element
*
* @return string
*/
public function getTitle();

/**
* Populate the text dosplayed to the user
*
* @return string
*/
public function getDisplayText();

/**
* Get the class to render the icon, generally a font awesome class
*
* @return string
*/
public function getIconClass();

/**
* Get any data-attributes required.
*
* Return an array of key/value pairs where key is the name of the attribute and value is the value of the attribute.
* Will be escaped at render time.
*
* An important note about injecting your own attributes, the value of the attribute is escaped using attr()
* which will cause problems if you are attempting to use javascript in the value of your attribute
* (i.e. an onclick attribute). If you need javascript, see getClickHandlerFunctionName() and getClickHandlerTemplateName().
*
* @return array
*/
public function getAttributes();

/**
* Get the name of the function handling click events.
*
* This is the name of the function that is attached to the click event of the button. Do not include `()` in the name.
*
* @return string|null
*/
public function getClickHandlerFunctionName();

/**
* Get the path of the file containing the click handler function.
*
* This is the path to a twig file which should contain only the function referenced in getClickHandlerFunctionName()
* that processes whatever action is required when the user clicks the button. do not include `<script>` tags in the
* template.
*
* @return void
*/
public function getClickHandlerTemplateName();

/**
* Return a simple array of class names that will be added to the anchor's class attribute
*
* @return string|null
*/
public function getAnchorClasses();

/**
* Get the href attribute
*
* @return void
*/
public function getHref();
}
128 changes: 128 additions & 0 deletions src/Events/UserInterface/BaseActionButtonHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

/**
* A helper class for simple interaction with the PageHeadingRenderEvent in an interface-compliant manner
*
* This is usefull for the most basic of requirements. If your code requires any type of business logic, it should be
* handled with its own class, returnin a ActionButtonInterface-compliant class. This class sets up the basics to get
* rapidly inject a button into the page heading but does not handle ACL or advanced logic.
*
* @package OpenEMR
* @link http://www.open-emr.org
*
* @author Robert Down <robertdown@live.com>
* @copyright Copyright (c) 2023 Providence Healthtech
* @copyright Copyright (c) 2023 Robert Down <robertdown@live.com>
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
*/

namespace OpenEMR\Events\UserInterface;

class BaseActionButtonHelper implements ActionButtonInterface
{
private $id = "";
private $title = "";
private $displayText = "";
private $iconClass = "";
private $attributes = [];
private $clickHandlerTemplateName;
private $clickHandlerFunctionName;
private $anchorClasses = [];
private $href = "#";

/**
* Populate the critical parts of an action button.
*
* Valid keys are:
* * id
* * title
* * displayText
* * iconClass
* * attributes
* * anchorClasses
* * jsTemplatePath
* * href
*
* The attributes key requires an array value with key/value equating to the name of the attribute and the value of
* the attribute. It is designed to capture data attributes, but could be used to put any attribute on the element.
* If attributes contain the following keys, they are dropped prior to rendering: id, title, class, href
*
* If any allowed keys are not set they will be set to an empty string.
*
* @param [type] $opts
*/
public function __construct($opts)
{
$allowedKeys = [
'id',
'title',
'displayText',
'iconClass',
'attributes',
'anchorClasses',
'clickHandlerTemplateName',
'clickHandlerFunctionName',
'href',
];

foreach ($opts as $k => $v) {
if (!in_array($k, $allowedKeys)) {
continue;
}

$this->$k = $v;
}
}

public function getID(): string
{
return $this->id;
}

public function getAnchorClasses()
{
return $this->anchorClasses;
}

public function getTitle(): string
{
return $this->title;
}

public function getDisplayText(): string
{
return $this->displayText;
}

public function getIconClass(): string
{
return $this->iconClass;
}

/**
* Convert the key/value array of attributes into a single, quoted string
*
* Better to manage the data as an array until the last minute
*
* @return string|null
*/
public function getAttributes(): array
{
return $this->attributes;
}

public function getClickHandlerTemplateName(): string|null
{
return $this->clickHandlerTemplateName;
}

public function getClickHandlerFunctionName(): string|null
{
return $this->clickHandlerFunctionName;
}

public function getHref()
{
return $this->href;
}
}
76 changes: 76 additions & 0 deletions src/Events/UserInterface/PageHeadingRenderEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

/**
* PageHeadingRenderEvent class is fired from the OemrUI class prior to rendering the page-level action buttons, allowing
* event listeners to render action buttons into the list with limited UI flexability.
*
* @package OpenEMR
* @link http://www.open-emr.org
*
* @author Robert Down <robertdown@live.com>
* @copyright Copyright (c) 2023 Providence Healthtech
* @copyright Copyright (c) 2023 Robert Down <robertdown@live.com>
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
*/

namespace OpenEMR\Events\UserInterface;

class PageHeadingRenderEvent
{
const EVENT_PAGE_HEADING_RENDER = 'oemrui.page.header.render';

/**
* The PageID being rendered
*
* @var string
*/
private string $page_id;

private array $actions;

/**
* UserEditRenderEvent constructor.
* @param string $pageName
* @param int|null $userId The userid that is being edited, null if this is a brand new user
* @param array $context
*/
public function __construct(string $page_id)
{
$this->page_id = $page_id;
$this->actions = [];
}

/**
* Return the page ID being rendered
*
* @return string
*/
public function getPageId(): string
{
return $this->page_id;
}

/**
* @return array|null
*/
public function getActions(): array
{
return $this->actions;
}

/**
* @param array
* @return UserEditRenderEvent
*/
public function setActions(array $actions): PageHeadingRenderEvent
{
foreach ($actions as $action) {
if (!($action instanceof ActionButtonInterface)) {
throw new \Exception("{$action} must implement ActionButtonInterface");
}
}

$this->actions = $actions;
return $this;
}
}

0 comments on commit 1d23ff6

Please sign in to comment.