Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[my_preference] Add support for my_preference widgets #8938

Merged
merged 2 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions modules/my_preferences/php/my_preferences.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,25 @@ class My_Preferences extends \NDB_Form
$this->tpl_data['notification_rows'] = $notification_rows;
//------------------------------------------------------------

$widgets = [];
$modules = $this->loris->getActiveModules();
foreach ($modules as $module) {
if ($module->hasAccess($user)) {
$mwidgets = $module->getWidgets(
'userpreference',
$user,
[],
);
foreach ($mwidgets as $widget) {
if (!($widget instanceof UserPreferenceWidget)) {
continue;
}
$widgets[] = $widget;
}
}
}
$this->tpl_data['module_userpreference_widgets'] = $widgets;

// unique key and password rules
$this->form->addFormRule([&$this, '_validateMyPreferences']);
}
Expand Down Expand Up @@ -468,6 +487,7 @@ class My_Preferences extends \NDB_Form
[
$baseurl . '/js/passwordVisibility.js',
$baseurl . '/my_preferences/js/my_preferences_helper.js',
$baseurl . '/js/components/CSSGrid.js',
]
);
}
Expand Down
42 changes: 42 additions & 0 deletions modules/my_preferences/php/userpreferencewidget.class.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php declare(strict_types=1);
namespace LORIS\my_preferences;

/**
* A \LORIS\candidate_profile\UserPreferenceWidget is a type of \LORIS\GUI\Widget
* used by the my preference page to register extra preference types.
*
* All UserPreferenceWidgets consist of React components which are loaded on the fly.
* The React component can have arbitrary props sent to it from LORIS.
*
* @license http://www.gnu.org/licenses/gpl-3.0.txt GPLv3
*/
class UserPreferenceWidget implements \LORIS\GUI\Widget
{
/**
* Construct a dashboard widget with the specified properties.
*
* @param string $title The title of the card to display.
* @param string $jsurl The URL containing the React component.
* @param string $componentname The React component name for this widget.
* @param array $props Additional React props to pass to the React
* component.
*/
public function __construct(
public string $title,
public string $jsurl,
public string $componentname,
public array $props,
) {
}

/**
* Renders the widget within a preference panel and implements
* the \LORIS\GUI\Widget interface.
*
* @return string the URL to the javascript which contains the React component
*/
public function __toString()
{
return $this->jsurl;
}
}
21 changes: 20 additions & 1 deletion modules/my_preferences/templates/form_my_preferences.tpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<br />
<form method="post" name="my_preferences" id="my_preferences" autocomplete="off">
<h3>Password Rules</h3>
<ul>
Expand Down Expand Up @@ -89,6 +88,26 @@
{/foreach}
</tbody>
</table>
{* Add any preferences registered from other modules *}
<div id="module_preferences" style="display: flex">
{section name=widget loop=$module_userpreference_widgets}
{assign var="widget" value=$module_userpreference_widgets[widget]}
<div id="widget_{$widget->componentname}">
<h3>{$widget->title}</h3>
{* Include the widget's javascript before trying to invoke it *}
<script src="{$widget->jsurl}" type="text/javascript"></script>

{* Create a react root to render it into *}
<script>
const el = document.createElement("div");
ReactDOM.createRoot(el).render(
{$widget->componentname}({})
);
document.getElementById("widget_{$widget->componentname}").appendChild(el);
</script>
</div>
{/section}
</div>
<div class="row form-group">
<div class="col-sm-2">
<input class="btn btn-sm btn-primary col-xs-12" name="fire_away" value="Save" type="submit" />
Expand Down
Loading