mirror of
https://github.com/maxpozdeev/mytinytodo.git
synced 2026-03-11 08:55:27 +00:00
+ extension can have own settings page
This commit is contained in:
parent
85140018dd
commit
456d34d30d
6 changed files with 139 additions and 9 deletions
|
|
@ -20,6 +20,7 @@ require_once(MTTINC. 'api/ListsController.php');
|
|||
require_once(MTTINC. 'api/TasksController.php');
|
||||
require_once(MTTINC. 'api/TagsController.php');
|
||||
require_once(MTTINC. 'api/AuthController.php');
|
||||
require_once(MTTINC. 'api/ExtSettingsController.php');
|
||||
|
||||
$endpoints = array(
|
||||
'/lists' => [
|
||||
|
|
@ -53,6 +54,10 @@ $endpoints = array(
|
|||
'/(login|logout|session)' => [
|
||||
'POST' => [ AuthController::class , 'postAction' ],
|
||||
],
|
||||
'/ext-settings/(.+)' => [
|
||||
'GET' => [ ExtSettingsController::class , 'get' ],
|
||||
'PUT' => [ ExtSettingsController::class , 'put' ],
|
||||
]
|
||||
);
|
||||
|
||||
$req = new ApiRequest();
|
||||
|
|
|
|||
|
|
@ -598,6 +598,9 @@ var mytinytodo = window.mytinytodo = _mtt = {
|
|||
else if (settingsPage == 'ext-activate' || settingsPage == 'ext-deactivate') {
|
||||
activateExtension(settingsPage == 'ext-activate' ? true : false, this.dataset.ext);
|
||||
}
|
||||
else if (settingsPage == 'ext-index') {
|
||||
showExtensionSettings(this.dataset.ext);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
|
|
@ -606,6 +609,11 @@ var mytinytodo = window.mytinytodo = _mtt = {
|
|||
return false;
|
||||
});
|
||||
|
||||
$("#page_ajax").on('submit', '#ext_settings_form', function() {
|
||||
saveExtensionSettings(this);
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).on('click', '.mtt-back-button', function() {
|
||||
_mtt.pageBack(true);
|
||||
this.blur();
|
||||
|
|
@ -2518,16 +2526,10 @@ function flashInfo(str, details)
|
|||
$("#msg").addClass('mtt-info').effect("highlight", {color:_mtt.theme.msgFlashColor}, 700);
|
||||
}
|
||||
|
||||
function toggleMsgDetails()
|
||||
{
|
||||
var el = $("#msg>.msg-details");
|
||||
if(!el) return;
|
||||
if(el.css('display') == 'none') el.show();
|
||||
else el.hide()
|
||||
}
|
||||
|
||||
function hideAlert()
|
||||
{
|
||||
$("#msg>.msg-text").text('');
|
||||
$("#msg>.msg-details").text('');
|
||||
$("#msg").hide().removeClass('mtt-error mtt-info').find('.msg-details').hide();
|
||||
}
|
||||
|
||||
|
|
@ -2654,6 +2656,40 @@ function activateExtension(activate, ext)
|
|||
}, 'json');
|
||||
}
|
||||
|
||||
function showExtensionSettings(ext, callback)
|
||||
{
|
||||
if (_mtt.pages.current && _mtt.pages.current.page == 'ajax' && _mtt.pages.current.pageClass == 'settings') {
|
||||
$('#page_ajax').load(_mtt.apiUrl + 'ext-settings/' + ext, null, function() {
|
||||
if (callback !== undefined) callback();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function saveExtensionSettings(frm)
|
||||
{
|
||||
if (!frm) return false;
|
||||
var ext = frm.dataset.ext;
|
||||
var params = {};
|
||||
$(frm).find("input:hidden,input:text,input:password,input:checked,select").filter(":enabled").each(function() { params[this.name || '__'] = this.value; });
|
||||
$.ajax({
|
||||
url: _mtt.apiUrl + 'ext-settings/' + ext,
|
||||
method: 'PUT',
|
||||
contentType : 'application/json',
|
||||
data: JSON.stringify(params),
|
||||
dataType: 'json',
|
||||
success: function(json) {
|
||||
if (json.saved) {
|
||||
if (json.msg) showExtensionSettings(ext, function(){
|
||||
flashInfo(json.msg);
|
||||
});
|
||||
else showExtensionSettings(ext);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Dialogs
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -938,7 +938,9 @@ li.mtt-item-hidden { display:none; }
|
|||
border-color: var(--color-border-focus);
|
||||
box-shadow:0 0 0 2px var(--color-border-focus-shadow);
|
||||
}
|
||||
|
||||
.mtt-settings-table a {
|
||||
color: var(--color-text-default);
|
||||
}
|
||||
|
||||
#modal {
|
||||
position: absolute;
|
||||
|
|
|
|||
78
src/includes/api/ExtSettingsController.php
Normal file
78
src/includes/api/ExtSettingsController.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
class ExtSettingsController extends ApiController {
|
||||
|
||||
/**
|
||||
* Get extension settings page
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
function get($ext)
|
||||
{
|
||||
/** @var MTTExtension|MTTExtensionSettingsInterface $instance */
|
||||
$instance = $this->extInstance($ext);
|
||||
if (!$instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $instance->settingsPage();
|
||||
|
||||
$title = htmlspecialchars($instance::title);
|
||||
$escapedExt = htmlspecialchars($ext);
|
||||
$e = function($s) { return __($s, true); };
|
||||
$data =
|
||||
<<<EOD
|
||||
<h3 class="page-title"><a class="mtt-back-button"></a> $title </h3>
|
||||
<div id="settings_msg" style="display:none"></div>
|
||||
<form id="ext_settings_form" data-ext="$escapedExt">
|
||||
<div class="mtt-settings-table">
|
||||
$data
|
||||
<div class="form-bottom-buttons">
|
||||
<button type="submit">{$e('set_submit')}</button>
|
||||
<button type="button" class="mtt-back-button">{$e('set_cancel')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
EOD;
|
||||
|
||||
$this->response->htmlContent($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save extension settings
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
function put($ext)
|
||||
{
|
||||
/** @var MTTExtension|MTTExtensionSettingsInterface $instance */
|
||||
$instance = $this->extInstance($ext);
|
||||
if (!$instance) {
|
||||
return;
|
||||
}
|
||||
//$userError = '';
|
||||
$saved = $instance->saveSettings($this->req->jsonBody ?? [], $userError);
|
||||
$a = [ 'saved' => (int)$saved ];
|
||||
if ($userError) {
|
||||
$a['msg'] = $userError;
|
||||
}
|
||||
$this->response->data = $a;
|
||||
}
|
||||
|
||||
private function extInstance($ext): ?MTTExtensionSettingsInterface
|
||||
{
|
||||
$instance = MTTExtensionLoader::extensionInstance($ext);
|
||||
if (!$instance) {
|
||||
$this->response->data = [ 'msg' => "Unknown extension" ];
|
||||
$this->response->code = 404;
|
||||
return null;
|
||||
}
|
||||
if (! ($instance instanceof MTTExtensionSettingsInterface) ) {
|
||||
$this->response->data = [ 'msg' => "No settings page for extension" ];
|
||||
$this->response->code = 500;
|
||||
return null;
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -79,6 +79,11 @@ abstract class MTTExtension
|
|||
}
|
||||
|
||||
|
||||
interface MTTExtensionSettingsInterface
|
||||
{
|
||||
function settingsPage(): string;
|
||||
function saveSettings(array $array, ?string &$userError): bool;
|
||||
}
|
||||
|
||||
|
||||
class MTTExtensionLoader
|
||||
|
|
|
|||
|
|
@ -189,6 +189,10 @@ function listExtensions()
|
|||
$out = "$ext ";
|
||||
if (in_array($ext, $activatedExts)) {
|
||||
$out .= "<a href='#' data-settings-link='ext-deactivate' data-ext='". htmlspecialchars($ext). "'>". __('set_deactivate', true). '</a>';
|
||||
$instance = MTTExtensionLoader::extensionInstance($ext);
|
||||
if ($instance instanceof MTTExtensionSettingsInterface) {
|
||||
$out .= " <a href='#' data-settings-link='ext-index' data-ext='". htmlspecialchars($ext). "'>". __('a_settings', true). "</a>";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$out .= "<a href='#' data-settings-link='ext-activate' data-ext='". htmlspecialchars($ext). "'>". __('set_activate', true). '</a>';
|
||||
|
|
|
|||
Loading…
Reference in a new issue