profiles: use client dialog; move related methods to pref-prefs

This commit is contained in:
Andrew Dolgov 2021-02-18 11:54:22 +03:00
parent b16abc157e
commit 1adb9bb6b6
4 changed files with 144 additions and 164 deletions

View File

@ -1219,102 +1219,97 @@ class Pref_Prefs extends Handler_Protected {
print json_encode(["value" => $value]); print json_encode(["value" => $value]);
} }
function editPrefProfiles() { function activateprofile() {
print "<div dojoType='fox.Toolbar'>"; $_SESSION["profile"] = (int) clean($_REQUEST["id"]);
print "<div dojoType='fox.form.DropDownButton'>". // default value
"<span>" . __('Select')."</span>"; if (!$_SESSION["profile"]) $_SESSION["profile"] = null;
print "<div dojoType='dijit.Menu' style='display: none'>"; }
print "<div onclick=\"Tables.select('pref-profiles-list', true)\"
dojoType='dijit.MenuItem'>".__('All')."</div>";
print "<div onclick=\"Tables.select('pref-profiles-list', false)\"
dojoType='dijit.MenuItem'>".__('None')."</div>";
print "</div></div>";
print "<div style='float : right'>"; function remprofiles() {
$ids = explode(",", clean($_REQUEST["ids"]));
print "<input name='newprofile' dojoType='dijit.form.ValidationTextBox' foreach ($ids as $id) {
required='1'> if ($_SESSION["profile"] != $id) {
<button dojoType='dijit.form.Button' $sth = $this->pdo->prepare("DELETE FROM ttrss_settings_profiles WHERE id = ? AND
onclick=\"dijit.byId('profileEditDlg').addProfile()\">". owner_uid = ?");
__('Create profile')."</button></div>"; $sth->execute([$id, $_SESSION['uid']]);
}
}
}
print "</div>"; function addprofile() {
$title = clean($_REQUEST["title"]);
if ($title) {
$this->pdo->beginTransaction();
$sth = $this->pdo->prepare("SELECT id FROM ttrss_settings_profiles
WHERE title = ? AND owner_uid = ?");
$sth->execute([$title, $_SESSION['uid']]);
if (!$sth->fetch()) {
$sth = $this->pdo->prepare("INSERT INTO ttrss_settings_profiles (title, owner_uid)
VALUES (?, ?)");
$sth->execute([$title, $_SESSION['uid']]);
$sth = $this->pdo->prepare("SELECT id FROM ttrss_settings_profiles WHERE
title = ? AND owner_uid = ?");
$sth->execute([$title, $_SESSION['uid']]);
if ($row = $sth->fetch()) {
$profile_id = $row['id'];
if ($profile_id) {
Pref_Prefs::_init_user_prefs($_SESSION["uid"], $profile_id);
}
}
}
$this->pdo->commit();
}
}
function saveprofile() {
$id = clean($_REQUEST["id"]);
$title = clean($_REQUEST["title"]);
if ($id == 0) {
print __("Default profile");
return;
}
if ($title) {
$sth = $this->pdo->prepare("UPDATE ttrss_settings_profiles
SET title = ? WHERE id = ? AND
owner_uid = ?");
$sth->execute([$title, $id, $_SESSION['uid']]);
print $title;
}
}
// TODO: this maybe needs to be unified with Public::getProfiles()
function getProfiles() {
$rv = [];
$sth = $this->pdo->prepare("SELECT title,id FROM ttrss_settings_profiles $sth = $this->pdo->prepare("SELECT title,id FROM ttrss_settings_profiles
WHERE owner_uid = ? ORDER BY title"); WHERE owner_uid = ? ORDER BY title");
$sth->execute([$_SESSION['uid']]); $sth->execute([$_SESSION['uid']]);
print "<form onsubmit='return false'>"; array_push($rv, ["title" => __("Default profile"),
"id" => 0,
"active" => empty($_SESSION["profile"])
]);
print "<div class='panel panel-scrollable'>"; while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
$row["active"] = isset($_SESSION["profile"]) && $_SESSION["profile"] == $row["id"];
print "<table width='100%' id='pref-profiles-list'>"; array_push($rv, $row);
};
print "<tr>"; # data-row-id='0' <-- no point, shouldn't be removed
print "<td><input onclick='Tables.onRowChecked(this);' dojoType='dijit.form.CheckBox' type='checkbox'></td>";
if (!isset($_SESSION["profile"])) {
$is_active = __("(active)");
} else {
$is_active = "";
}
print "<td width='100%'><span>" . __("Default profile") . " $is_active</span></td>";
print "</tr>";
while ($line = $sth->fetch()) {
$profile_id = $line["id"];
print "<tr data-row-id='$profile_id'>";
$edit_title = htmlspecialchars($line["title"]);
print "<td><input onclick='Tables.onRowChecked(this);' dojoType='dijit.form.CheckBox' type='checkbox'></td>";
if (isset($_SESSION["profile"]) && $_SESSION["profile"] == $line["id"]) {
$is_active = __("(active)");
} else {
$is_active = "";
}
print "<td><span dojoType='dijit.InlineEditBox'
width='300px' autoSave='false'
profile-id='$profile_id'>" . $edit_title .
"<script type='dojo/method' event='onChange' args='item'>
var elem = this;
dojo.xhrPost({
url: 'backend.php',
content: {op: 'rpc', method: 'saveprofile',
value: this.value,
id: this.srcNodeRef.getAttribute('profile-id')},
load: function(response) {
elem.attr('value', response);
}
});
</script>
</span> $is_active</td>";
print "</tr>";
}
print "</table>";
print "</div>";
print "<footer>
<button style='float : left' class='alt-danger' dojoType='dijit.form.Button' onclick='App.dialogOf(this).removeSelected()'>".
__('Remove selected profiles')."</button>
<button dojoType='dijit.form.Button' class='alt-primary' type='submit' onclick='App.dialogOf(this).execute()'>".
__('Activate profile')."</button>
<button dojoType='dijit.form.Button' onclick='App.dialogOf(this).hide()'>".
__('Cancel')."</button>";
print "</footer>";
print "</form>";
print json_encode($rv);
} }
private function _get_short_desc($pref_name) { private function _get_short_desc($pref_name) {

View File

@ -2,84 +2,11 @@
class RPC extends Handler_Protected { class RPC extends Handler_Protected {
function csrf_ignore($method) { function csrf_ignore($method) {
$csrf_ignored = array("completelabels", "saveprofile"); $csrf_ignored = array("completelabels");
return array_search($method, $csrf_ignored) !== false; return array_search($method, $csrf_ignored) !== false;
} }
function setprofile() {
$_SESSION["profile"] = (int) clean($_REQUEST["id"]);
// default value
if (!$_SESSION["profile"]) $_SESSION["profile"] = null;
}
function remprofiles() {
$ids = explode(",", clean($_REQUEST["ids"]));
foreach ($ids as $id) {
if ($_SESSION["profile"] != $id) {
$sth = $this->pdo->prepare("DELETE FROM ttrss_settings_profiles WHERE id = ? AND
owner_uid = ?");
$sth->execute([$id, $_SESSION['uid']]);
}
}
}
// Silent
function addprofile() {
$title = clean($_REQUEST["title"]);
if ($title) {
$this->pdo->beginTransaction();
$sth = $this->pdo->prepare("SELECT id FROM ttrss_settings_profiles
WHERE title = ? AND owner_uid = ?");
$sth->execute([$title, $_SESSION['uid']]);
if (!$sth->fetch()) {
$sth = $this->pdo->prepare("INSERT INTO ttrss_settings_profiles (title, owner_uid)
VALUES (?, ?)");
$sth->execute([$title, $_SESSION['uid']]);
$sth = $this->pdo->prepare("SELECT id FROM ttrss_settings_profiles WHERE
title = ? AND owner_uid = ?");
$sth->execute([$title, $_SESSION['uid']]);
if ($row = $sth->fetch()) {
$profile_id = $row['id'];
if ($profile_id) {
Pref_Prefs::_init_user_prefs($_SESSION["uid"], $profile_id);
}
}
}
$this->pdo->commit();
}
}
function saveprofile() {
$id = clean($_REQUEST["id"]);
$title = clean($_REQUEST["value"]);
if ($id == 0) {
print __("Default profile");
return;
}
if ($title) {
$sth = $this->pdo->prepare("UPDATE ttrss_settings_profiles
SET title = ? WHERE id = ? AND
owner_uid = ?");
$sth->execute([$title, $id, $_SESSION['uid']]);
print $title;
}
}
function togglepref() { function togglepref() {
$key = clean($_REQUEST["key"]); $key = clean($_REQUEST["key"]);
set_pref($key, !get_pref($key)); set_pref($key, !get_pref($key));

View File

@ -42,6 +42,12 @@ const App = {
cancel_dialog_tag: function(value, attributes = {}) { cancel_dialog_tag: function(value, attributes = {}) {
return this.button_tag(value, "", {...{onclick: "App.dialogOf(this).hide()"}, ...attributes}); return this.button_tag(value, "", {...{onclick: "App.dialogOf(this).hide()"}, ...attributes});
}, },
checkbox_tag: function(name, checked = false, value = "", attributes = {}, id = "") {
return `<input dojoType="dijit.form.CheckBox" type="checkbox" name="${App.escapeHtml(name)}"
${checked ? "checked" : ""}
${value ? `value="${App.escapeHtml(value)}"` : ""}
${this.attributes_to_string(attributes)} id="${App.escapeHtml(id)}">`
},
select_tag: function(name, value, values = [], attributes = {}, id = "") { select_tag: function(name, value, values = [], attributes = {}, id = "") {
return ` return `
<select name="${name}" dojoType="fox.form.Select" id="${App.escapeHtml(id)}" ${this.attributes_to_string(attributes)}> <select name="${name}" dojoType="fox.form.Select" id="${App.escapeHtml(id)}" ${this.attributes_to_string(attributes)}>

View File

@ -104,7 +104,7 @@ const Helpers = {
Notify.progress("Removing selected profiles...", true); Notify.progress("Removing selected profiles...", true);
const query = { const query = {
op: "rpc", method: "remprofiles", op: "pref-prefs", method: "remprofiles",
ids: sel_rows.toString() ids: sel_rows.toString()
}; };
@ -122,7 +122,7 @@ const Helpers = {
if (this.validate()) { if (this.validate()) {
Notify.progress("Creating profile...", true); Notify.progress("Creating profile...", true);
const query = {op: "rpc", method: "addprofile", title: dialog.attr('value').newprofile}; const query = {op: "pref-prefs", method: "addprofile", title: dialog.attr('value').newprofile};
xhrPost("backend.php", query, () => { xhrPost("backend.php", query, () => {
Notify.close(); Notify.close();
@ -132,8 +132,60 @@ const Helpers = {
} }
}, },
refresh: function() { refresh: function() {
xhrPost("backend.php", {op: 'pref-prefs', method: 'editPrefProfiles'}, (transport) => { xhrJson("backend.php", {op: 'pref-prefs', method: 'getprofiles'}, (reply) => {
dialog.attr('content', transport.responseText); dialog.attr('content', `
<div dojoType='fox.Toolbar'>
<div dojoType='fox.form.DropDownButton'>
<span>${__('Select')}</span>
<div dojoType='dijit.Menu' style='display: none'>
<div onclick="Tables.select('pref-profiles-list', true)"
dojoType='dijit.MenuItem'>${__('All')}</div>
<div onclick="Tables.select('pref-profiles-list', false)"
dojoType='dijit.MenuItem'>${__('None')}</div>
</div>
</div>
<div class="pull-right">
<input name='newprofile' dojoType='dijit.form.ValidationTextBox' required='1'>
${App.FormFields.button_tag(__('Create profile'), "", {onclick: 'App.dialogOf(this).addProfile()'})}
</div>
</div>
<form onsubmit='return false'>
<div class='panel panel-scrollable'>
<table width='100%' id='pref-profiles-list'>
${reply.map((profile) => `
<tr data-row-id="${profile.id}">
<td width='5%'>
${App.FormFields.checkbox_tag("", false, "", {onclick: 'Tables.onRowChecked(this)'})}
</td>
<td>
${profile.id > 0 ?
`<span dojoType='dijit.InlineEditBox' width='300px' autoSave='false'
profile-id='${profile.id}'>${profile.title}
<script type='dojo/method' event='onChange' args='value'>
xhrPost("backend.php",
{op: 'pref-prefs', method: 'saveprofile', value: value, id: this.attr('profile-id')}, (transport) => {
//
});
</script>
</span>` : `${profile.title}`}
${profile.active ? __("(active)") : ""}
</td>
</tr>
`).join("")}
</table>
</div>
<footer>
${App.FormFields.button_tag(__('Remove selected profiles'), "",
{class: 'pull-left alt-danger', onclick: 'App.dialogOf(this).removeSelected()'})}
${App.FormFields.submit_tag(__('Activate profile'), {onclick: 'App.dialogOf(this).execute()'})}
${App.FormFields.cancel_dialog_tag(__('Cancel'))}
</footer>
</form>
`);
}); });
}, },
execute: function () { execute: function () {
@ -143,7 +195,7 @@ const Helpers = {
if (confirm(__("Activate selected profile?"))) { if (confirm(__("Activate selected profile?"))) {
Notify.progress("Loading, please wait..."); Notify.progress("Loading, please wait...");
xhrPost("backend.php", {op: "rpc", method: "setprofile", id: sel_rows.toString()}, () => { xhrPost("backend.php", {op: "pref-prefs", method: "activateprofile", id: sel_rows.toString()}, () => {
window.location.reload(); window.location.reload();
}); });
} }