Admin page refresh. (#6)
Added settings and options. Settings parsing catch. Fix postSetting API responses. Adjusted spinner visibility toggle. Reviewed-on: #6 Co-authored-by: Armored-Dragon <forgejo3829105@armoreddragon.com> Co-committed-by: Armored-Dragon <forgejo3829105@armoreddragon.com>pull/2/head
parent
94424df08f
commit
83da8100dc
|
@ -19,6 +19,12 @@ let settings = {
|
||||||
HIDE_LOGIN: false,
|
HIDE_LOGIN: false,
|
||||||
BLOG_UPLOADING: false,
|
BLOG_UPLOADING: false,
|
||||||
|
|
||||||
|
CD_RSS: false,
|
||||||
|
CD_AP: false,
|
||||||
|
|
||||||
|
WEBSITE_NAME: "",
|
||||||
|
PLAUSIBLE_URL: "",
|
||||||
|
|
||||||
USER_MINIMUM_PASSWORD_LENGTH: 7,
|
USER_MINIMUM_PASSWORD_LENGTH: 7,
|
||||||
|
|
||||||
BLOG_MINIMUM_TITLE_LENGTH: 7,
|
BLOG_MINIMUM_TITLE_LENGTH: 7,
|
||||||
|
@ -372,9 +378,18 @@ async function _getSettings() {
|
||||||
let found_value = await prisma.setting.findUnique({ where: { id: key } });
|
let found_value = await prisma.setting.findUnique({ where: { id: key } });
|
||||||
if (!found_value) return;
|
if (!found_value) return;
|
||||||
|
|
||||||
return (settings[key] = JSON.parse(found_value.value));
|
let value;
|
||||||
|
// Parse JSON if possible
|
||||||
|
try {
|
||||||
|
value = JSON.parse(found_value.value);
|
||||||
|
} catch {
|
||||||
|
value = found_value.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (settings[key] = value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getSetting(key, { parse = true }) {
|
async function getSetting(key, { parse = true }) {
|
||||||
if (!settings[key]) return null;
|
if (!settings[key]) return null;
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,7 @@ async function postSetting(request, response) {
|
||||||
if (!user.success) return response.json({ success: false, message: user.message });
|
if (!user.success) return response.json({ success: false, message: user.message });
|
||||||
if (user.data.role !== "ADMIN") return response.json({ success: false, message: "User is not permitted" });
|
if (user.data.role !== "ADMIN") return response.json({ success: false, message: "User is not permitted" });
|
||||||
|
|
||||||
await core.postSetting(request.body.setting_name, request.body.value);
|
response.json(await core.postSetting(request.body.setting_name, request.body.value));
|
||||||
|
|
||||||
response.json({ success: true });
|
|
||||||
}
|
}
|
||||||
async function deleteImage(req, res) {
|
async function deleteImage(req, res) {
|
||||||
// TODO: Permissions for deleting image
|
// TODO: Permissions for deleting image
|
||||||
|
|
|
@ -2,7 +2,8 @@ const external = require("./core/external_api");
|
||||||
const core = require("./core/core");
|
const core = require("./core/core");
|
||||||
|
|
||||||
function getDefaults(req) {
|
function getDefaults(req) {
|
||||||
return { logged_in_user: req.session.user, website_name: process.env.WEBSITE_NAME, settings: core.settings };
|
// TODO: Fix reference to website_name
|
||||||
|
return { logged_in_user: req.session.user, website_name: core.settings.WEBSITE_NAME || "Yet-Another-Blog", settings: core.settings };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function index(request, response) {
|
async function index(request, response) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-color: #111;
|
background-color: #111;
|
||||||
color: white;
|
color: white;
|
||||||
|
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
|
@ -58,11 +59,18 @@ button:focus {
|
||||||
background-color: #122d57;
|
background-color: #122d57;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.good {
|
button.good,
|
||||||
|
a.good {
|
||||||
background-color: #015b01;
|
background-color: #015b01;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.bad {
|
button.yellow,
|
||||||
|
a.yellow {
|
||||||
|
background-color: #4a4a00;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.bad,
|
||||||
|
a.bad {
|
||||||
background-color: #8e0000;
|
background-color: #8e0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,9 +83,78 @@ button.bad {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
.page .horizontal-button-container button {
|
.page .horizontal-button-container button,
|
||||||
width: 100px;
|
.page .horizontal-button-container a {
|
||||||
|
width: 120px;
|
||||||
min-height: 30px;
|
min-height: 30px;
|
||||||
|
text-decoration: none;
|
||||||
|
display: flex;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
.page .horizontal-button-container button span,
|
||||||
|
.page .horizontal-button-container a span {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
.page .horizontal-button-container button:last-of-type,
|
||||||
|
.page .horizontal-button-container a:last-of-type {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
.page .blog-admin {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.page .pagination {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.page .pagination a {
|
||||||
|
height: 40px;
|
||||||
|
width: 150px;
|
||||||
|
margin-right: 5px;
|
||||||
|
display: flex;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #222;
|
||||||
|
}
|
||||||
|
.page .pagination a span {
|
||||||
|
margin: auto;
|
||||||
|
color: white;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
.page .pagination a:last-of-type {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.page .pagination a.disabled {
|
||||||
|
filter: brightness(50%);
|
||||||
|
}
|
||||||
|
.page .pagination .page-list {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
.page .pagination .page-list a {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #222;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin: 0 10px 0 0;
|
||||||
|
}
|
||||||
|
.page .pagination .page-list a span {
|
||||||
|
margin: auto;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.page .pagination .page-list a:first-of-type {
|
||||||
|
margin: auto 10px auto auto;
|
||||||
|
}
|
||||||
|
.page .pagination .page-list a:last-of-type {
|
||||||
|
margin: auto auto auto 0;
|
||||||
|
}
|
||||||
|
.page .pagination .page-list a.active {
|
||||||
|
background-color: #993d00;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
|
@ -86,7 +163,7 @@ button.bad {
|
||||||
|
|
||||||
@media screen and (max-width: 1010px) {
|
@media screen and (max-width: 1010px) {
|
||||||
.page {
|
.page {
|
||||||
width: 100%;
|
width: 95%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.container {
|
.container {
|
||||||
|
@ -95,32 +172,73 @@ button.bad {
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.container .settings-group .settings-row {
|
.container .category-navigation {
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.container .category-navigation button {
|
||||||
|
width: 100%;
|
||||||
|
margin-right: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-decoration: none;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.container .category-navigation button span {
|
||||||
|
margin: auto;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.container .category-navigation button:not(.active) {
|
||||||
|
background-color: #4c515e;
|
||||||
|
}
|
||||||
|
.container .category-navigation button:hover,
|
||||||
|
.container .category-navigation button:focus {
|
||||||
|
filter: brightness(50%);
|
||||||
|
}
|
||||||
|
.container .setting-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
padding: 4px;
|
min-height: 30px;
|
||||||
|
padding: 5px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.container .settings-group .settings-row .label {
|
.container .setting-row .setting-title {
|
||||||
|
font-size: 18px;
|
||||||
margin: auto auto auto 0;
|
margin: auto auto auto 0;
|
||||||
}
|
}
|
||||||
.container .settings-group .settings-row .button-group {
|
.container .setting-row .setting-toggleable {
|
||||||
|
min-width: 150px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
|
||||||
margin: auto 0 auto auto;
|
margin: auto 0 auto auto;
|
||||||
}
|
}
|
||||||
.container .settings-group .settings-row .button-group .spinner {
|
.container .setting-row .setting-toggleable .spinner {
|
||||||
margin: auto 10px auto auto;
|
margin: auto 0 auto auto;
|
||||||
animation: spin 1s;
|
animation: spin 1s;
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
}
|
}
|
||||||
.container .settings-group .settings-row .button-group button {
|
.container .setting-row .setting-toggleable input {
|
||||||
height: 30px;
|
padding: 0;
|
||||||
padding: 0px 20px;
|
margin: auto 0 auto auto;
|
||||||
|
width: 100px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
.container .settings-group .settings-row:nth-child(even) {
|
.container .setting-row .setting-toggleable input[type=text] {
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
width: 350px;
|
||||||
|
}
|
||||||
|
.container .setting-row .setting-toggleable button {
|
||||||
|
width: 125px;
|
||||||
|
margin-left: auto;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
.container .setting-row:nth-child(even) {
|
||||||
|
background-color: #1c1c1c;
|
||||||
|
}
|
||||||
|
.container .setting-row:nth-child(odd) {
|
||||||
|
background-color: #191919;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
|
|
|
@ -6,35 +6,89 @@
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
.settings-group {
|
.category-navigation {
|
||||||
.settings-row {
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
margin-right: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-decoration: none;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin: auto;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button:not(.active) {
|
||||||
|
background-color: #4c515e;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover,
|
||||||
|
button:focus {
|
||||||
|
filter: brightness(50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
// display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
padding: 4px;
|
min-height: 30px;
|
||||||
|
padding: 5px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
.label {
|
|
||||||
|
.setting-title {
|
||||||
|
font-size: 18px;
|
||||||
margin: auto auto auto 0;
|
margin: auto auto auto 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-group {
|
.setting-toggleable {
|
||||||
|
min-width: 150px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
|
||||||
margin: auto 0 auto auto;
|
margin: auto 0 auto auto;
|
||||||
|
|
||||||
.spinner {
|
.spinner {
|
||||||
margin: auto 10px auto auto;
|
margin: auto 0 auto auto;
|
||||||
animation: spin 1s;
|
animation: spin 1s;
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding: 0;
|
||||||
|
margin: auto 0 auto auto;
|
||||||
|
// width: 100%;
|
||||||
|
width: 100px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
width: 350px;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
width: 125px;
|
||||||
|
margin-left: auto;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
padding: 0px 20px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.settings-row:nth-child(even) {
|
.setting-row:nth-child(even) {
|
||||||
background-color: #00000033;
|
background-color: #1c1c1c;
|
||||||
}
|
}
|
||||||
|
.setting-row:nth-child(odd) {
|
||||||
|
background-color: #191919;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
|
|
|
@ -9,10 +9,11 @@ async function toggleState(setting_name, new_value, element_id) {
|
||||||
|
|
||||||
const response = await request("/setting", "POST", form);
|
const response = await request("/setting", "POST", form);
|
||||||
|
|
||||||
// Check response for errors
|
|
||||||
if (response.body.success) {
|
|
||||||
qs(`#${element_id}`).parentNode.querySelector(".spinner").classList.add("hidden");
|
qs(`#${element_id}`).parentNode.querySelector(".spinner").classList.add("hidden");
|
||||||
|
|
||||||
|
// TODO: On failure, notify the user
|
||||||
|
// Check response for errors
|
||||||
|
if (response.body.success) {
|
||||||
// Update visual to reflect current setting
|
// Update visual to reflect current setting
|
||||||
// Class
|
// Class
|
||||||
const add_class = new_value ? "good" : "bad";
|
const add_class = new_value ? "good" : "bad";
|
||||||
|
@ -30,3 +31,42 @@ async function toggleState(setting_name, new_value, element_id) {
|
||||||
qs(`#${element_id}`).setAttribute("onclick", add_function);
|
qs(`#${element_id}`).setAttribute("onclick", add_function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateValue(key_pressed, setting_name, new_value, element_id) {
|
||||||
|
if (key_pressed !== 13) return;
|
||||||
|
// Show spinner
|
||||||
|
qs(`#${element_id}`).parentNode.querySelector(".spinner").classList.remove("hidden");
|
||||||
|
|
||||||
|
const form = {
|
||||||
|
setting_name: setting_name,
|
||||||
|
value: new_value,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await request("/setting", "POST", form);
|
||||||
|
|
||||||
|
qs(`#${element_id}`).parentNode.querySelector(".spinner").classList.add("hidden");
|
||||||
|
|
||||||
|
// TODO: On failure, notify the user
|
||||||
|
// Check response for errors
|
||||||
|
if (response.body.success) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleActiveCategory(category_id) {
|
||||||
|
// Pages ----------------
|
||||||
|
// Hide all pages
|
||||||
|
qsa(".category-page").forEach((page) => {
|
||||||
|
page.classList.add("hidden");
|
||||||
|
});
|
||||||
|
// Show requested page
|
||||||
|
qs(`#${category_id}`).classList.remove("hidden");
|
||||||
|
|
||||||
|
// Navigation bar -------
|
||||||
|
// Unactive all buttons
|
||||||
|
qsa(".category-navigation button").forEach((btn) => {
|
||||||
|
btn.classList.remove("active");
|
||||||
|
});
|
||||||
|
// Active current page
|
||||||
|
qs(`#${category_id}-nav-btn`).classList.add("active");
|
||||||
|
qs(`#${category_id}-nav-btn`).blur(); // Unfocus the button
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
const qs = (selector) => document.querySelector(selector);
|
const qs = (selector) => document.querySelector(selector);
|
||||||
const qsa = (selector) => document.querySelectorAll(selector);
|
const qsa = (selector) => document.querySelectorAll(selector);
|
||||||
|
|
||||||
|
// TODO: Try/Catch for failed requests
|
||||||
async function request(url, method, body) {
|
async function request(url, method, body) {
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
method: method,
|
method: method,
|
||||||
|
|
|
@ -13,35 +13,38 @@
|
||||||
|
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="settings-group">
|
<div class="category-navigation">
|
||||||
<h1>Accounts</h1>
|
<button id="accounts-nav-btn" class="active" onclick="toggleActiveCategory('accounts')"><span>Accounts</span></button>
|
||||||
<div class="settings-row">
|
<button id="content-delivery-nav-btn" onclick="toggleActiveCategory('content-delivery')"><span>Content Delivery</span></button>
|
||||||
<div class="label">Account registration</div>
|
<button id="groups-nav-btn" onclick="toggleActiveCategory('groups')"><span>Groups</span></button>
|
||||||
<div class="button-group">
|
<button id="yab-master-nav-btn" onclick="toggleActiveCategory('yab-master')"><span>YAB</span></button>
|
||||||
<div class="spinner hidden">
|
|
||||||
<div>↺</div>
|
|
||||||
</div>
|
|
||||||
<% if (!settings.ACCOUNT_REGISTRATION ) { %>
|
|
||||||
<button id="registration_toggle" onclick="toggleState('ACCOUNT_REGISTRATION', true, this.id)" class="bad"><div>Disabled</div></button>
|
|
||||||
<% } else { %>
|
|
||||||
<button id="registration_toggle" onclick="toggleState('ACCOUNT_REGISTRATION', false, this.id)" class="good"><div>Enabled</div></button>
|
|
||||||
<%}%>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div id="accounts" class="category-page">
|
||||||
|
<!-- Account registration -->
|
||||||
|
<%- include("partials/admin-setting-toggle.ejs", {setting: {name: 'ACCOUNT_REGISTRATION', name_pretty: 'Account registration', enabled:
|
||||||
|
settings.ACCOUNT_REGISTRATION}}) %>
|
||||||
|
<!-- Hide login -->
|
||||||
|
<%- include("partials/admin-setting-toggle.ejs", {setting: {name: 'HIDE_LOGIN', name_pretty: 'Hide Login', enabled: settings.HIDE_LOGIN}}) %>
|
||||||
|
<!-- Minimum password length -->
|
||||||
|
<%- include("partials/admin-setting-number.ejs", {setting: {name:'USER_MINIMUM_PASSWORD_LENGTH', name_pretty: 'Minimum Password Length', value:
|
||||||
|
settings.USER_MINIMUM_PASSWORD_LENGTH}}) %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-row">
|
<div id="content-delivery" class="category-page hidden">
|
||||||
<div class="label">Hide Login</div>
|
<!-- RSS -->
|
||||||
<div class="button-group">
|
<%- include("partials/admin-setting-toggle.ejs", {setting: {name: 'CD_RSS', name_pretty: 'RSS Feed', enabled: settings.CD_RSS}}) %>
|
||||||
<div class="spinner hidden">
|
<!-- ActivityPub -->
|
||||||
<div>↺</div>
|
<%- include("partials/admin-setting-toggle.ejs", {setting: {name: 'CD_AP', name_pretty: 'Activity Pub Feed', enabled: settings.CD_AP}}) %>
|
||||||
</div>
|
<!-- TODO: Add these option automatically to footer on active -->
|
||||||
<% if (!settings.HIDE_LOGIN ) { %>
|
|
||||||
<button id="hidelogin_toggle" onclick="toggleState('HIDE_LOGIN', true, this.id)" class="bad"><div>Disabled</div></button>
|
|
||||||
<% } else { %>
|
|
||||||
<button id="hidelogin_toggle" onclick="toggleState('HIDE_LOGIN', false, this.id)" class="good"><div>Enabled</div></button>
|
|
||||||
<%}%>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="groups" class="category-page hidden">TODO</div>
|
||||||
|
<div id="yab-master" class="category-page hidden">
|
||||||
|
<!-- Website title -->
|
||||||
|
<%- include("partials/admin-setting-text.ejs", {setting: {name: 'WEBSITE_NAME', name_pretty: 'Website Title', value: settings.WEBSITE_NAME}}) %>
|
||||||
|
<!-- Placeholder thumbnail -->
|
||||||
|
<!-- Plausible analytics -->
|
||||||
|
<%- include("partials/admin-setting-text.ejs", {setting: {name: 'PLAUSIBLE_URL', name_pretty: 'Plausible URL', value: settings.PLAUSIBLE_URL}}) %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="setting-row">
|
||||||
|
<div class="setting-title"><%=setting.name_pretty%></div>
|
||||||
|
<div class="setting-toggleable">
|
||||||
|
<div class="spinner hidden">
|
||||||
|
<div>↺</div>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="<%=setting.name%>"
|
||||||
|
onkeydown="updateValue(event.keyCode, '<%=setting.name%>', this.value, this.id)"
|
||||||
|
placeholder="<%=setting.name_pretty%>"
|
||||||
|
value="<%=setting.value%>"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="setting-row">
|
||||||
|
<div class="setting-title"><%=setting.name_pretty%></div>
|
||||||
|
<div class="setting-toggleable">
|
||||||
|
<div class="spinner hidden">
|
||||||
|
<div>↺</div>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
id="<%=setting.name%>"
|
||||||
|
type="text"
|
||||||
|
onkeydown="updateValue(event.keyCode, '<%=setting.name%>', this.value, this.id)"
|
||||||
|
placeholder="<%=setting.name_pretty%>"
|
||||||
|
value="<%=setting.value%>"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<div class="setting-row">
|
||||||
|
<div class="setting-title"><%=setting.name_pretty%></div>
|
||||||
|
<div class="setting-toggleable">
|
||||||
|
<div class="spinner hidden">
|
||||||
|
<div>↺</div>
|
||||||
|
</div>
|
||||||
|
<% if (!setting.enabled) { %>
|
||||||
|
<button id="<%=setting.name%>_toggle" onclick="toggleState('<%=setting.name%>', true, this.id)" class="bad"><div>Disabled</div></button>
|
||||||
|
<% } else { %>
|
||||||
|
<button id="<%=setting.name%>_toggle" onclick="toggleState('<%=setting.name%>', false, this.id)" class="good"><div>Enabled</div></button>
|
||||||
|
<%}%>
|
||||||
|
</div>
|
||||||
|
</div>
|
Loading…
Reference in New Issue