mirror of
https://github.com/OliveTin/OliveTin
synced 2026-08-24 11:36:37 +00:00
+56
-50
@@ -92,35 +92,6 @@
|
||||
</fieldset>
|
||||
</section>
|
||||
|
||||
<section id = "contentLogin" title = "Login" hidden>
|
||||
<div class = "flex-col">
|
||||
<form class = "box-shadow padded-content">
|
||||
<h2>OAuth Login</h2>
|
||||
<div>
|
||||
<button>GitHub</button>
|
||||
<button>Google</button>
|
||||
</div>
|
||||
<hr />
|
||||
<h2>Local Login</h2>
|
||||
<div class = "arguments">
|
||||
<label for = "username">
|
||||
<span>Username:</span>
|
||||
</label>
|
||||
<input type = "text" name = "username" />
|
||||
<span></span>
|
||||
|
||||
<label for = "password">
|
||||
<span>Password:</span>
|
||||
</label>
|
||||
<input type = "password" name = "password" />
|
||||
<span></span>
|
||||
|
||||
<button type = "submit">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<noscript>
|
||||
<div class = "error">Sorry, JavaScript is required to use OliveTin.</div>
|
||||
</noscript>
|
||||
@@ -129,16 +100,16 @@
|
||||
<footer title = "footer">
|
||||
<p><img title = "application icon" src = "OliveTinLogo.png" alt = "OliveTin logo" height = "1em" class = "logo" /> OliveTin</p>
|
||||
<p>
|
||||
<a href = "https://docs.olivetin.app" target = "_new">Documentation</a> |
|
||||
<a href = "https://github.com/OliveTin/OliveTin/issues/new/choose" target = "_new">Raise an issue on GitHub</a> |
|
||||
<span>Version: <span id = "currentVersion">?</span></span> |
|
||||
<span>Server connection:
|
||||
<span id = "serverConnectionRest">REST</span>,
|
||||
<span id = "serverConnectionWebSocket">WebSocket</span>
|
||||
</span>
|
||||
<a href = "https://docs.olivetin.app" target = "_new">Documentation</a> |
|
||||
<a href = "https://github.com/OliveTin/OliveTin/issues/new/choose" target = "_new">Raise an issue on GitHub</a> |
|
||||
<span>Version: <span id = "currentVersion">?</span></span> |
|
||||
<span>Server connection:
|
||||
<span id = "serverConnectionRest">REST</span>,
|
||||
<span id = "serverConnectionWebSocket">WebSocket</span>
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<a id = "available-version" href = "http://olivetin.app" target = "_blank" hidden>?</a>
|
||||
<a id = "available-version" href = "http://olivetin.app" target = "_blank" hidden>?</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
@@ -159,11 +130,11 @@
|
||||
</button>
|
||||
</div>
|
||||
<div id = "execution-dialog-basics" class = "padded-content-sides">
|
||||
<strong>Duration: </strong><span id = "execution-dialog-duration">unknown</span>
|
||||
<strong>Duration: </strong><span id = "execution-dialog-duration">unknown</span>
|
||||
</div>
|
||||
<div id = "execution-dialog-details" class = "padded-content-sides">
|
||||
<p>
|
||||
<strong>Status: </strong><span id = "execution-dialog-status">unknown</span>
|
||||
<strong>Status: </strong><span id = "execution-dialog-status">unknown</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -178,6 +149,41 @@
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<template id = "tplLoginForm">
|
||||
<section id = "content-login" title = "Login" hidden>
|
||||
<div class = "flex-col">
|
||||
<form class = "box-shadow padded-content border-radius">
|
||||
<p class = "login-disabled">Login with OAuth or Local users is not enabled on this server.</p>
|
||||
|
||||
<div class = "login-oauth2" hidden>
|
||||
<h2>OAuth Login</h2>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div class = "login-local" hidden>
|
||||
<h2>Local Login</h2>
|
||||
<div class = "arguments">
|
||||
<label for = "username">
|
||||
<span>Username:</span>
|
||||
</label>
|
||||
<input type = "text" name = "username" />
|
||||
<span></span>
|
||||
|
||||
<label for = "password">
|
||||
<span>Password:</span>
|
||||
</label>
|
||||
<input type = "password" name = "password" />
|
||||
<span></span>
|
||||
|
||||
<button type = "submit">Login</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<template id = "tplArgumentForm">
|
||||
<dialog title = "Arguments" id = "argument-popup">
|
||||
<form class = "action-arguments padded-content">
|
||||
@@ -225,24 +231,24 @@
|
||||
|
||||
/**
|
||||
This is the bootstrap code, which relies on very simple, old javascript
|
||||
to at least display a helpful error message if we can't use OliveTin.
|
||||
*/
|
||||
to at least display a helpful error message if we can't use OliveTin.
|
||||
*/
|
||||
window.showBigError = function (type, friendlyType, message, isFatal) {
|
||||
bigErrorDialog.innerHTML = '<h1>Error ' + friendlyType + '</h1><p>' + message + "</p><p><a href = 'http://docs.olivetin.app/err-" + type + ".html' target = 'blank'/>" + type + " error in OliveTin Documentation</a></p>"
|
||||
bigErrorDialog.innerHTML = '<h1>Error ' + friendlyType + '</h1><p>' + message + "</p><p><a href = 'http://docs.olivetin.app/err-" + type + ".html' target = 'blank'/>" + type + " error in OliveTin Documentation</a></p>"
|
||||
|
||||
if (isFatal) {
|
||||
bigErrorDialog.innerHTML += '<p>You will need to refresh your browser to clear this message.</p>'
|
||||
} else {
|
||||
bigErrorDialog.innerHTML += '<p>This error message will go away automatically if the problem is solved.</p>'
|
||||
}
|
||||
if (isFatal) {
|
||||
bigErrorDialog.innerHTML += '<p>You will need to refresh your browser to clear this message.</p>'
|
||||
} else {
|
||||
bigErrorDialog.innerHTML += '<p>This error message will go away automatically if the problem is solved.</p>'
|
||||
}
|
||||
|
||||
bigErrorDialog.showModal()
|
||||
bigErrorDialog.showModal()
|
||||
|
||||
console.error('Error ' + type + ': ', message)
|
||||
console.error('Error ' + type + ': ', message)
|
||||
}
|
||||
|
||||
window.clearBigErrors = function () {
|
||||
bigErrorDialog.close()
|
||||
bigErrorDialog.close()
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
export class LoginForm extends window.HTMLElement {
|
||||
setup () {
|
||||
const tpl = document.getElementById('tplLoginForm')
|
||||
this.content = tpl.content.cloneNode(true)
|
||||
|
||||
this.appendChild(this.content)
|
||||
}
|
||||
|
||||
processOAuth2Providers (providers) {
|
||||
if (providers === null) {
|
||||
return
|
||||
}
|
||||
|
||||
if (providers.length > 0) {
|
||||
this.querySelector('.login-oauth2').hidden = false
|
||||
this.querySelector('.login-disabled').hidden = true
|
||||
|
||||
for (const provider of providers) {
|
||||
const providerForm = document.createElement('form')
|
||||
providerForm.method = 'GET'
|
||||
providerForm.action = '/oauth2?provider=' + provider.Name
|
||||
|
||||
const providerButton = document.createElement('button')
|
||||
providerButton.type = 'submit'
|
||||
providerButton.innerHTML = '<span class = "oauth2-icon">' + provider.Icon + '</span> Login with ' + provider.Title
|
||||
|
||||
providerForm.appendChild(providerButton)
|
||||
|
||||
this.querySelector('.login-oauth2').appendChild(providerForm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processLocalLogin (enabled) {
|
||||
if (enabled) {
|
||||
this.querySelector('.login-local').hidden = false
|
||||
this.querySelector('.login-disabled').hidden = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.customElements.define('login-form', LoginForm)
|
||||
+26
-10
@@ -10,6 +10,8 @@ import {
|
||||
} from './js/marshaller.js'
|
||||
import { checkWebsocketConnection } from './js/websocket.js'
|
||||
|
||||
import { LoginForm } from './js/LoginForm.js'
|
||||
|
||||
function searchLogs (e) {
|
||||
document.getElementById('searchLogsClear').disabled = false
|
||||
|
||||
@@ -126,28 +128,42 @@ function processWebuiSettingsJson (settings) {
|
||||
if (titleElem) titleElem.innerText = window.pageTitle
|
||||
}
|
||||
|
||||
processAdditionaLinks(settings.AdditionalLinks)
|
||||
processAdditionalLinks(settings.AdditionalLinks)
|
||||
|
||||
const loginForm = new LoginForm()
|
||||
loginForm.setup()
|
||||
loginForm.processOAuth2Providers(settings.AuthOAuth2Providers)
|
||||
loginForm.processLocalLogin(settings.AuthLocalLogin)
|
||||
|
||||
document.getElementsByTagName('main')[0].appendChild(loginForm)
|
||||
|
||||
window.settings = settings
|
||||
|
||||
refreshDiagnostics()
|
||||
}
|
||||
|
||||
function processAdditionaLinks (links) {
|
||||
function processAdditionalLinks (links) {
|
||||
if (links === null) {
|
||||
return
|
||||
}
|
||||
|
||||
for (const link of links) {
|
||||
const linkA = document.createElement('a')
|
||||
linkA.href = link.Url
|
||||
linkA.innerText = link.Title
|
||||
linkA.target = '_blank'
|
||||
if (links.length > 0) {
|
||||
for (const link of links) {
|
||||
const linkA = document.createElement('a')
|
||||
linkA.href = link.Url
|
||||
linkA.innerText = link.Title
|
||||
|
||||
const linkLi = document.createElement('li')
|
||||
linkLi.appendChild(linkA)
|
||||
if (link.Target === '') {
|
||||
linkA.target = '_blank'
|
||||
} else {
|
||||
linkA.target = link.Target
|
||||
}
|
||||
|
||||
document.getElementById('supplemental-links').prepend(linkLi)
|
||||
const linkLi = document.createElement('li')
|
||||
linkLi.appendChild(linkA)
|
||||
|
||||
document.getElementById('supplemental-links').prepend(linkLi)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+41
-16
@@ -177,7 +177,7 @@ nav.topbar ul li a {
|
||||
nav.sidebar ul li {
|
||||
list-style: none;
|
||||
text-align: left;
|
||||
border-bottom: 1px inset black;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
table {
|
||||
@@ -502,9 +502,12 @@ span.annotation-value {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.border-radius {
|
||||
border-radius: .7em;
|
||||
}
|
||||
|
||||
.box-shadow p {
|
||||
padding: .6em;
|
||||
background-color: #fff;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -557,17 +560,12 @@ div.display {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#contentLogin form {
|
||||
width: 40%;
|
||||
place-self: center;
|
||||
}
|
||||
|
||||
#contentLogin hr {
|
||||
#content-login hr {
|
||||
border: 0;
|
||||
border-top: 1px dashed #ccc;
|
||||
}
|
||||
|
||||
#contentLogin button {
|
||||
#content-login button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
grid-column: 1 / span 3;
|
||||
@@ -576,10 +574,25 @@ div.display {
|
||||
background-color: #ced3d7;
|
||||
}
|
||||
|
||||
#contentLogin button:last-child {
|
||||
#content-login button:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#content-login ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#content-login form {
|
||||
width: auto;
|
||||
place-self: center;
|
||||
}
|
||||
|
||||
.oauth2-icon {
|
||||
font-size: 1.8em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@media screen and (width <= 600px) {
|
||||
fieldset {
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
@@ -622,10 +635,7 @@ div.display {
|
||||
}
|
||||
|
||||
.box-shadow {
|
||||
box-shadow: 0 0 6px 0 #ccc;
|
||||
}
|
||||
|
||||
.box-shadow p {
|
||||
box-shadow: 0 0 6px 0 #625c5c;
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
@@ -670,8 +680,17 @@ div.display {
|
||||
color: white;
|
||||
}
|
||||
|
||||
nav.sidebar ul li {
|
||||
border-bottom: 1px solid #3e3e3e;
|
||||
}
|
||||
|
||||
nav ul li a:hover {
|
||||
background-color: #666;
|
||||
background-color: #1b5988;
|
||||
color: white;
|
||||
}
|
||||
|
||||
nav ul li a.selected {
|
||||
background-color: #0c3351;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@@ -692,7 +711,7 @@ div.display {
|
||||
}
|
||||
|
||||
tr:hover td {
|
||||
background-color: #666;
|
||||
background-color: #1b5988;
|
||||
}
|
||||
|
||||
div.toolbar {
|
||||
@@ -702,4 +721,10 @@ div.display {
|
||||
div.display {
|
||||
box-shadow: 0 0 6px 0 #444;
|
||||
}
|
||||
|
||||
#content-login button {
|
||||
background-color: #000;
|
||||
border: 1px solid #666;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user