mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2025-01-19 01:35:28 +01:00
Add Personalized Transparency for Login Page's Form
This commit is contained in:
parent
3c11f0120d
commit
7984ca8157
@ -10,6 +10,25 @@ class ManagementController:
|
||||
def __init__(self, management_helper):
|
||||
self.management_helper = management_helper
|
||||
|
||||
# **********************************************************************************
|
||||
# Config Methods
|
||||
# **********************************************************************************
|
||||
@staticmethod
|
||||
def set_login_image(path):
|
||||
HelpersManagement.set_login_image(path)
|
||||
|
||||
@staticmethod
|
||||
def get_login_image():
|
||||
return HelpersManagement.get_login_image()
|
||||
|
||||
@staticmethod
|
||||
def set_login_opacity(opacity):
|
||||
return HelpersManagement.set_login_opacity(opacity)
|
||||
|
||||
@staticmethod
|
||||
def get_login_opacity():
|
||||
return HelpersManagement.get_login_opacity()
|
||||
|
||||
# **********************************************************************************
|
||||
# Host_Stats Methods
|
||||
# **********************************************************************************
|
||||
@ -94,14 +113,6 @@ class ManagementController:
|
||||
def delete_scheduled_task(schedule_id):
|
||||
return HelpersManagement.delete_scheduled_task(schedule_id)
|
||||
|
||||
@staticmethod
|
||||
def set_login_image(path):
|
||||
HelpersManagement.set_login_image(path)
|
||||
|
||||
@staticmethod
|
||||
def get_login_image():
|
||||
return HelpersManagement.get_login_image()
|
||||
|
||||
@staticmethod
|
||||
def update_scheduled_task(schedule_id, updates):
|
||||
return HelpersManagement.update_scheduled_task(schedule_id, updates)
|
||||
|
@ -44,6 +44,7 @@ class AuditLog(BaseModel):
|
||||
class CraftySettings(BaseModel):
|
||||
secret_api_key = CharField(default="")
|
||||
login_photo = CharField(default="login_1.jpg")
|
||||
login_opacity = IntegerField(default=100)
|
||||
|
||||
class Meta:
|
||||
table_name = "crafty_settings"
|
||||
@ -255,6 +256,9 @@ class HelpersManagement:
|
||||
)
|
||||
return settings[0].secret_api_key
|
||||
|
||||
# **********************************************************************************
|
||||
# Config Methods
|
||||
# **********************************************************************************
|
||||
@staticmethod
|
||||
def get_login_image():
|
||||
settings = CraftySettings.select(CraftySettings.login_photo).where(
|
||||
@ -268,6 +272,19 @@ class HelpersManagement:
|
||||
CraftySettings.id == 1
|
||||
).execute()
|
||||
|
||||
@staticmethod
|
||||
def get_login_opacity():
|
||||
settings = CraftySettings.select(CraftySettings.login_opacity).where(
|
||||
CraftySettings.id == 1
|
||||
)
|
||||
return settings[0].login_opacity
|
||||
|
||||
@staticmethod
|
||||
def set_login_opacity(opacity):
|
||||
CraftySettings.update({CraftySettings.login_opacity: opacity}).where(
|
||||
CraftySettings.id == 1
|
||||
).execute()
|
||||
|
||||
# **********************************************************************************
|
||||
# Schedules Methods
|
||||
# **********************************************************************************
|
||||
|
@ -356,6 +356,8 @@ class AjaxHandler(BaseHandler):
|
||||
elif page == "select_photo":
|
||||
if exec_user["superuser"]:
|
||||
photo = self.get_argument("photo", None)
|
||||
opacity = self.get_argument("opacity", 100)
|
||||
self.controller.management.set_login_opacity(int(opacity))
|
||||
if photo == "login_1.jpg":
|
||||
self.controller.management.set_login_image("login_1.jpg")
|
||||
self.controller.cached_login = f"{photo}"
|
||||
|
@ -291,6 +291,7 @@ class PanelHandler(BaseHandler):
|
||||
# todo: make this actually pull and compare version data
|
||||
"update_available": self.helper.update_available,
|
||||
"background": self.controller.cached_login,
|
||||
"login_opacity": self.controller.management.get_login_opacity(),
|
||||
"serverTZ": tz,
|
||||
"version_data": self.helper.get_version_string(),
|
||||
"failed_servers": self.controller.servers.failed_servers,
|
||||
@ -883,6 +884,9 @@ class PanelHandler(BaseHandler):
|
||||
if item not in page_data["backgrounds"]:
|
||||
page_data["backgrounds"].append(item)
|
||||
page_data["background"] = self.controller.cached_login
|
||||
page_data[
|
||||
"login_opacity"
|
||||
] = self.controller.management.get_login_opacity()
|
||||
else:
|
||||
page_data["managed_users"] = self.controller.users.get_managed_users(
|
||||
exec_user["user_id"]
|
||||
|
@ -40,6 +40,7 @@ class PublicHandler(BaseHandler):
|
||||
"lang_page": self.helper.get_lang_page(self.helper.get_setting("language")),
|
||||
"query": "",
|
||||
"background": self.controller.cached_login,
|
||||
"login_opacity": self.controller.management.get_login_opacity(),
|
||||
}
|
||||
|
||||
if self.request.query:
|
||||
|
@ -237,16 +237,16 @@
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="col-lg-6">
|
||||
<h4>{{ translate('panelConfig', 'loginImage', data['lang']) }}</h4>
|
||||
<hr>
|
||||
<form class="form-inline" name="zip" method="post" class="server-wizard" onSubmit="wait_msg(true)">
|
||||
<form class="form-row" name="zip" method="post" class="server-wizard" onSubmit="wait_msg(true)">
|
||||
{% raw xsrf_form_html() %}
|
||||
<input type="hidden" value="import_zip" name="create_type">
|
||||
<div class="form-group">
|
||||
<div class="col form-group">
|
||||
<span id="upload_input"><input type="file" class="form-control-file" id="file" name="file" multiple="false" required></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col form-group">
|
||||
<button type="button" class="btn btn-info" id="upload-button" onclick="sendFile()" disabled>UPLOAD</button>
|
||||
</div>
|
||||
</form>
|
||||
@ -264,10 +264,10 @@
|
||||
'delete', data['lang']) }}</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="col-lg-6">
|
||||
<div>
|
||||
<h6>{{ translate('panelConfig', 'preview', data['lang']) }}:</h6>
|
||||
<form>
|
||||
<form id="photo_form">
|
||||
<div class="form-group row">
|
||||
<label for="photo" class="col-sm-6 col-form-label">Selected Background Image</label>
|
||||
<div class="col-sm-6">
|
||||
@ -286,16 +286,106 @@
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3" for="formControlRange">{{ translate('panelConfig', 'loginOpacity', data['lang']) }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="range" class="form-control-range" id="modal_opacity" name="modal_opacity">
|
||||
<label class="col-sm-1" id="opacityValue">{{ data['login_opacity'] }}%</label>
|
||||
<div class="range col-sm-8">
|
||||
<input type="range" class="form-control-range" id="modal_opacity" name="modal_opacity" onchange="previewOpacity()" min="0" max="100" value="{{ data['login_opacity'] }}">
|
||||
</div>
|
||||
</div>
|
||||
<div id="login_preview" style="position: static;">
|
||||
<img id="bg-preview" src="../../static/assets/images/auth/{{ data['background'] }}" class="img-fluid" alt="Responsive image">
|
||||
<div id="login-form-preview" style="position: absolute; top: 10rem; left: 10rem; size-adjust: 10%;">
|
||||
<div id="login-form-background" class="auto-form-wrapper login-modal">
|
||||
<div class="text-center auto-form-logo">
|
||||
<img src="/static/assets/images/logo_long.svg">
|
||||
</div>
|
||||
<style>
|
||||
.auto-form-wrapper {
|
||||
background: rgb(34, 36, 55, 1);
|
||||
padding: 2rem 2rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 -25px 37.7px 11.3px rgb(8 143 220 / 7%);
|
||||
box-shadow: 0 -25px 37.7px 11.3px rgb(8 143 220 / 7%);
|
||||
color: #fff;
|
||||
size-adjust: 2%;
|
||||
}
|
||||
|
||||
/*.auto-form-logo {
|
||||
background: #222437;
|
||||
padding: 0rem;
|
||||
margin: 0.5rem 0rem;
|
||||
border-radius: 0.2rem;
|
||||
color: #fff;
|
||||
}*/
|
||||
|
||||
.login-modal {
|
||||
border-radius: 0.4rem !important;
|
||||
box-shadow: 0 1rem 1rem 0 hsla(0, 0%, 0%, 0.2) !important;
|
||||
}
|
||||
|
||||
.login-text-input {
|
||||
border: none !important;
|
||||
background-color: hsl(234, 30%, 45%);
|
||||
color: var(--white) !important;
|
||||
}
|
||||
|
||||
.login-text-input:hover,
|
||||
.login-text-input:focus {
|
||||
background-color: hsl(234, 30%, 39%) !important;
|
||||
}
|
||||
|
||||
.login-input {
|
||||
border-radius: 0.4rem !important;
|
||||
box-shadow: 0 8rem 12rem 0 hsla(0, 0%, 0%, 0.2);
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.login-input:hover,
|
||||
.login-input:focus {
|
||||
box-shadow: 0 12rem 16rem 0 hsla(0, 0%, 0%, 0.4);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="login_form_data">
|
||||
<input type="hidden" name="_xsrf" value="2|1d603267|809fb6bd82f677d440e484dde7c3a310|1671726040" disabled>
|
||||
<div class="form-group">
|
||||
<label class="label">Username</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control login-text-input login-input" placeholder="Username" name="username" id="username" required="true" disabled>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="label">Password</label>
|
||||
<div class="input-group">
|
||||
<input type="password" class="form-control login-text-input login-input" placeholder="Password" name="password" id="password" required="true" disabled>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button class="login-input btn btn-primary submit-btn btn-block" disabled>Log In</button>
|
||||
</div>
|
||||
|
||||
<fieldset style="color: red; text-align: center;">
|
||||
<span></span>
|
||||
</fieldset>
|
||||
|
||||
<div class="form-group d-flex justify-content-between">
|
||||
<div class="form-check form-check-flat mt-0">
|
||||
|
||||
</div>
|
||||
<a href="#" class="text-small forgot-password" disabled>Forgot Password</a>
|
||||
</div>
|
||||
<div class="text-block text-center my-3">
|
||||
<span class="text-small font-weight-semibold"><a href="https://craftycontrol.com/">Crafty Control
|
||||
4.0.20</a> </span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img id="bg-preview" src="../../static/assets/images/auth/{{ data['background'] }}" class="img-fluid" alt="Responsive image">
|
||||
<div class="form-group">
|
||||
<button class="btn btn-outline-success select-photo" type="button">{{ translate('panelConfig',
|
||||
'select', data['lang']) }}</button>
|
||||
'apply', data['lang']) }}</button>
|
||||
<button class="btn btn-outline-danger delete-photo" type="button">{{ translate('panelConfig',
|
||||
'delete', data['lang']) }}</button>
|
||||
'cancel', data['lang']) }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -407,16 +497,29 @@
|
||||
$('.select-photo').click(function () {
|
||||
var token = getCookie("_xsrf")
|
||||
let photo = $('#photo').find(":selected").val();
|
||||
let opacity = $('#modal_opacity').val();
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
headers: { 'X-XSRFToken': token },
|
||||
url: '/ajax/select_photo?photo=' + photo,
|
||||
url: '/ajax/select_photo?photo=' + photo + '&opacity=' + opacity,
|
||||
success: function (data) {
|
||||
window.location.reload();
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
$(document).ready(function () {
|
||||
let opacity = parseInt($("#modal_opacity").val());
|
||||
document.getElementById('login-form-background').style.background = 'rgb(34, 36, 55, ' + (opacity / 100) + ')';
|
||||
});
|
||||
|
||||
function previewOpacity() {
|
||||
let opacity = parseInt($("#modal_opacity").val())
|
||||
console.debug("Selected Opacity = " + opacity + "%");
|
||||
document.getElementById('opacityValue').innerHTML = (opacity) + "%";
|
||||
document.getElementById('login-form-background').style.background = 'rgb(34, 36, 55, ' + (opacity / 100) + ')';
|
||||
}
|
||||
|
||||
function updateBackgroundSelect() {
|
||||
$("#photo").val($("#try_photo").val()).change();
|
||||
}
|
||||
|
@ -36,8 +36,9 @@
|
||||
<div class="row w-100">
|
||||
<div class="col-lg-4 mx-auto">
|
||||
|
||||
<div class="auto-form-wrapper login-modal">
|
||||
<div class="text-center">
|
||||
<div id="login-form-background" class="auto-form-wrapper login-modal">
|
||||
<div id="login_opacity" data-value="{{ data['login_opacity'] }}" hidden></div>
|
||||
<div class="text-center auto-form-logo">
|
||||
<img src="/static/assets/images/logo_long.svg">
|
||||
</div>
|
||||
<style>
|
||||
@ -78,16 +79,16 @@
|
||||
<label class="label">{{ translate('login', 'username', data['lang']) }}</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control login-text-input login-input"
|
||||
placeholder="{{ translate('login', 'username', data['lang']) }}" name="username" id="username"
|
||||
required="true">
|
||||
placeholder="{{ translate('login', 'username', data['lang']) }}" name="username" id="username"
|
||||
required="true">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="label">{{ translate('login', 'password', data['lang']) }}</label>
|
||||
<div class="input-group">
|
||||
<input type="password" class="form-control login-text-input login-input"
|
||||
placeholder="{{ translate('login', 'password', data['lang']) }}" name="password" id="password"
|
||||
required="true">
|
||||
placeholder="{{ translate('login', 'password', data['lang']) }}" name="password" id="password"
|
||||
required="true">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -133,6 +134,13 @@
|
||||
<script src="/static/assets/js/shared/settings.js"></script>
|
||||
<script src="/static/assets/js/shared/todolist.js"></script>
|
||||
<!-- endinject -->
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
let login_opacity_div = document.getElementById('login_opacity');
|
||||
let opacity = login_opacity_div.getAttribute('data-value');
|
||||
document.getElementById('login-form-background').style.background = 'rgb(34, 36, 55, ' + (opacity / 100) + ')';
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
18
app/migrations/20230111_adding_login_opacity.py
Normal file
18
app/migrations/20230111_adding_login_opacity.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by database migrator
|
||||
import peewee
|
||||
|
||||
|
||||
def migrate(migrator, database, **kwargs):
|
||||
migrator.add_columns(
|
||||
"crafty_settings", login_opacity=peewee.IntegerField(default=100)
|
||||
)
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
|
||||
|
||||
def rollback(migrator, database, **kwargs):
|
||||
migrator.drop_columns("crafty_settings", ["login_opacity"])
|
||||
"""
|
||||
Write your rollback migrations here.
|
||||
"""
|
@ -234,6 +234,7 @@
|
||||
"loginBackground": "Login Background Image",
|
||||
"loginOpacity": "Select the Login Window Opacity",
|
||||
"select": "Select",
|
||||
"apply": "Apply",
|
||||
"selectImage": "Select an image",
|
||||
"preview": "Preview"
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user