1
0
mirror of https://github.com/hrfee/jfa-go.git synced 2024-12-22 09:00:10 +00:00

settings: add loader, improve css a bit

Loader appears on about/user profiles area. These two are now shown next
to each other.
on small screens, the sidebar list of sections is displayed without a
card around it, and the top left/right corner buttons on all pages are
correctly aligned with the content.
This commit is contained in:
Harvey Tindall 2024-08-05 20:23:10 +01:00
parent ce6a5772b1
commit b40211a6e0
Signed by: hrfee
GPG Key ID: BBC65952848FB1A2
6 changed files with 84 additions and 70 deletions

View File

@ -66,14 +66,14 @@ html:not(.dark) .card.\@low:not(.\~neutral):not(.\~positive):not(.\~urge):not(.\
margin: 5% 20% 5% 20%; margin: 5% 20% 5% 20%;
} }
@media (max-width: 1100px) { @media (max-width: 1024px) {
.page-container { .page-container {
margin: 2%; margin: 2%;
margin-top: 5rem; margin-top: 5rem;
} }
} }
@media screen and (max-width: 1000px) { @media screen and (max-width: 1024px) {
:root { :root {
font-size: 0.9rem; font-size: 0.9rem;
} }

View File

@ -535,7 +535,7 @@
</form> </form>
</div> </div>
<div id="notification-box"></div> <div id="notification-box"></div>
<div class="top-4 left-4 absolute flex flex-row gap-2"> <div class="top-[2%] left-[2%] lg:top-4 lg:left-4 absolute flex flex-row gap-2">
<span class="dropdown z-[11]" tabindex="0" id="lang-dropdown"> <span class="dropdown z-[11]" tabindex="0" id="lang-dropdown">
<span class="button ~urge dropdown-button"> <span class="button ~urge dropdown-button">
<i class="ri-global-line"></i> <i class="ri-global-line"></i>
@ -558,7 +558,7 @@
<span class="button ~warning" alt="{{ .strings.theme }}" id="button-theme"><i class="ri-sun-line"></i></span> <span class="button ~warning" alt="{{ .strings.theme }}" id="button-theme"><i class="ri-sun-line"></i></span>
</div> </div>
{{ if .userPageEnabled }} {{ if .userPageEnabled }}
<div class="top-4 right-4 absolute"> <div class="top-[2%] lg:top-4 right-[2%] lg:right-4 absolute">
<a class="button ~info" href="{{ .urlBase }}/my/account"><i class="ri-account-circle-fill mr-2"></i>{{ .strings.myAccount }}</a> <a class="button ~info" href="{{ .urlBase }}/my/account"><i class="ri-account-circle-fill mr-2"></i>{{ .strings.myAccount }}</a>
</div> </div>
{{ end }} {{ end }}
@ -895,7 +895,7 @@
</div> </div>
</div> </div>
<div id="tab-settings" class="unfocused"> <div id="tab-settings" class="unfocused">
<div class="card @low dark:~d_neutral settings overflow"> <div class="card @low dark:~d_neutral settings overflow flex flex-col gap-2">
<div class="flex flex-col md:flex-row align-middle gap-2"> <div class="flex flex-col md:flex-row align-middle gap-2">
<div class="flex flex-row align-middle justify-between md:justify-normal"> <div class="flex flex-row align-middle justify-between md:justify-normal">
<span class="heading">{{ .strings.settings }}</span> <span class="heading">{{ .strings.settings }}</span>
@ -912,16 +912,18 @@
</div> </div>
</div> </div>
<div class="flex flex-col md:flex-row gap-3"> <div class="flex flex-col md:flex-row gap-3">
<div class="card @low dark:~d_neutral col" id="settings-sidebar"> <div class="md:card @low dark:~d_neutral flex md:flex flex-col gap-2 flex-1" id="settings-sidebar">
<div class="flex flex-row justify-between"> <div class="flex flex-row justify-between">
<input type="search" class="field ~neutral @low input settings-section-button justify-between mb-2" id="settings-search" placeholder="{{ .strings.search }}"> <input type="search" class="field ~neutral @low input settings-section-button justify-between" id="settings-search" placeholder="{{ .strings.search }}">
<button class="button ~neutral @low center -ml-10 rounded-s-none mb-2 settings-search-clear" aria-label="{{ .strings.clearSearch }}" text="{{ .strings.clearSearch }}"><i class="ri-close-line"></i></button> <button class="button ~neutral @low center -ml-10 rounded-s-none settings-search-clear" aria-label="{{ .strings.clearSearch }}" text="{{ .strings.clearSearch }}"><i class="ri-close-line"></i></button>
</div>
<aside class="aside sm ~urge dark:~d_info @low" id="settings-message">Note: <span class="badge ~critical">*</span> indicates a required field, <span class="badge ~info dark:~d_warning">R</span> indicates changes require a restart.</aside>
<div id="settings-loader" class="flex flex-row gap-2">
<span class="button ~neutral @low settings-section-button justify-center grow" id="setting-about"><span class="flex">{{ .strings.aboutProgram }} <i class="ri-information-line ml-2"></i></span></span>
<span class="button ~neutral @low settings-section-button justify-center grow" id="setting-profiles"><span class="flex">{{ .strings.userProfiles }} <i class="ri-user-line ml-2"></i></span></span>
</div> </div>
<aside class="aside sm ~urge dark:~d_info mb-2 @low" id="settings-message">Note: <span class="badge ~critical">*</span> indicates a required field, <span class="badge ~info dark:~d_warning">R</span> indicates changes require a restart.</aside>
<span class="button ~neutral @low settings-section-button justify-between mb-2" id="setting-about"><span class="flex">{{ .strings.aboutProgram }} <i class="ri-information-line ml-2"></i></span></span>
<span class="button ~neutral @low settings-section-button justify-between mb-2" id="setting-profiles"><span class="flex">{{ .strings.userProfiles }} <i class="ri-user-line ml-2"></i></span></span>
</div> </div>
<div class="card ~neutral @low col overflow" id="settings-panel"> <div class="card ~neutral @low overflow flex-1" id="settings-panel">
<div class="settings-section unfocused h-[100%]" id="settings-not-found"> <div class="settings-section unfocused h-[100%]" id="settings-not-found">
<div class="flex flex-col h-[100%] justify-center items-center"> <div class="flex flex-col h-[100%] justify-center items-center">
<span class="text-2xl font-medium italic mb-2">{{ .strings.noResultsFound }}</span> <span class="text-2xl font-medium italic mb-2">{{ .strings.noResultsFound }}</span>

View File

@ -35,7 +35,7 @@
</div> </div>
</div> </div>
{{ template "account-linking.html" . }} {{ template "account-linking.html" . }}
<div class="top-4 left-4 absolute"> <div class="top-[2%] lg:top-4 left-[2%] lg:left-4 absolute">
<span class="dropdown" tabindex="0" id="lang-dropdown"> <span class="dropdown" tabindex="0" id="lang-dropdown">
<span class="button ~urge dropdown-button"> <span class="button ~urge dropdown-button">
<i class="ri-global-line"></i> <i class="ri-global-line"></i>

View File

@ -7,7 +7,7 @@
</head> </head>
<body class="max-w-full overflow-x-hidden section"> <body class="max-w-full overflow-x-hidden section">
<div id="notification-box"></div> <div id="notification-box"></div>
<div class="top-4 left-4 absolute"> <div class="top-[2%] lg:top-4 left-[2%] lg:left-4 absolute">
<span class="dropdown" tabindex="0" id="lang-dropdown"> <span class="dropdown" tabindex="0" id="lang-dropdown">
<span class="button ~urge dropdown-button"> <span class="button ~urge dropdown-button">
<i class="ri-global-line"></i> <i class="ri-global-line"></i>

View File

@ -79,7 +79,7 @@
{{ template "login-modal.html" . }} {{ template "login-modal.html" . }}
{{ template "account-linking.html" . }} {{ template "account-linking.html" . }}
<div id="notification-box"></div> <div id="notification-box"></div>
<div class="top-4 left-4 absolute"> <div class="top-[2%] lg:top-4 left-[2%] lg:left-4 absolute">
<span class="dropdown" tabindex="0" id="lang-dropdown"> <span class="dropdown" tabindex="0" id="lang-dropdown">
<span class="button ~urge dropdown-button"> <span class="button ~urge dropdown-button">
<i class="ri-global-line"></i> <i class="ri-global-line"></i>
@ -102,7 +102,7 @@
<span class="button ~warning" alt="{{ .strings.theme }}" id="button-theme"><i class="ri-sun-line"></i></span> <span class="button ~warning" alt="{{ .strings.theme }}" id="button-theme"><i class="ri-sun-line"></i></span>
<span class="button ~critical @low mb-4 unfocused" id="logout-button">{{ .strings.logout }}</span> <span class="button ~critical @low mb-4 unfocused" id="logout-button">{{ .strings.logout }}</span>
</div> </div>
<div class="top-4 right-4 absolute"> <div class="top-[2%] lg:top-4 right-[2%] lg:right-4 absolute">
<a class="button ~info unfocused" href="/" id="admin-back-button"><i class="ri-arrow-left-fill mr-2"></i>{{ .strings.admin }}</a> <a class="button ~info unfocused" href="/" id="admin-back-button"><i class="ri-arrow-left-fill mr-2"></i>{{ .strings.admin }}</a>
</div> </div>
<div class="page-container unfocused"> <div class="page-container unfocused">

View File

@ -627,6 +627,8 @@ export class settingsList {
private _saveNoRestart = document.getElementById("settings-apply-no-restart") as HTMLSpanElement; private _saveNoRestart = document.getElementById("settings-apply-no-restart") as HTMLSpanElement;
private _saveRestart = document.getElementById("settings-apply-restart") as HTMLSpanElement; private _saveRestart = document.getElementById("settings-apply-restart") as HTMLSpanElement;
private _loader = document.getElementById("settings-loader") as HTMLDivElement;
private _panel = document.getElementById("settings-panel") as HTMLDivElement; private _panel = document.getElementById("settings-panel") as HTMLDivElement;
private _sidebar = document.getElementById("settings-sidebar") as HTMLDivElement; private _sidebar = document.getElementById("settings-sidebar") as HTMLDivElement;
private _visibleSection: string; private _visibleSection: string;
@ -650,7 +652,7 @@ export class settingsList {
this._sections[name] = section; this._sections[name] = section;
this._panel.appendChild(this._sections[name].asElement()); this._panel.appendChild(this._sections[name].asElement());
const button = document.createElement("span") as HTMLSpanElement; const button = document.createElement("span") as HTMLSpanElement;
button.classList.add("button", "~neutral", "@low", "settings-section-button", "justify-between", "mb-2"); button.classList.add("button", "~neutral", "@low", "settings-section-button", "justify-between");
button.textContent = s.meta.name; button.textContent = s.meta.name;
if (subButton) { button.appendChild(subButton); } if (subButton) { button.appendChild(subButton); }
button.onclick = () => { this._showPanel(name); }; button.onclick = () => { this._showPanel(name); };
@ -905,63 +907,73 @@ export class settingsList {
window.modals.matrix.show(); window.modals.matrix.show();
} }
reload = () => _get("/config", null, (req: XMLHttpRequest) => { reload = () => {
if (req.readyState == 4) { for (let i = 0; i < this._loader.children.length; i++) {
if (req.status != 200) { this._loader.children[i].classList.add("invisible");
window.notifications.customError("settingsLoadError", window.lang.notif("errorLoadSettings")); }
return; addLoader(this._loader, false, true);
} _get("/config", null, (req: XMLHttpRequest) => {
this._settings = req.response as Settings; if (req.readyState == 4) {
for (let name of this._settings.order) { if (req.status != 200) {
if (name in this._sections) { window.notifications.customError("settingsLoadError", window.lang.notif("errorLoadSettings"));
this._sections[name].update(this._settings.sections[name]); return;
} else { }
if (name == "messages" || name == "user_page") { this._settings = req.response as Settings;
const editButton = document.createElement("div"); for (let name of this._settings.order) {
editButton.classList.add("tooltip", "left"); if (name in this._sections) {
editButton.innerHTML = ` this._sections[name].update(this._settings.sections[name]);
<span class="button ~neutral @low">
<i class="icon ri-edit-line"></i>
</span>
<span class="content sm">
${window.lang.get("strings", "customizeMessages")}
</span>
`;
(editButton.querySelector("span.button") as HTMLSpanElement).onclick = () => {
this._messageEditor.showList(name == "messages" ? "email" : "user");
};
this.addSection(name, this._settings.sections[name], editButton);
} else if (name == "updates") {
const icon = document.createElement("span") as HTMLSpanElement;
if (window.updater.updateAvailable) {
icon.classList.add("button", "~urge");
icon.innerHTML = `<i class="ri-download-line" title="${window.lang.strings("update")}"></i>`;
icon.onclick = () => window.updater.checkForUpdates(window.modals.updateInfo.show);
}
this.addSection(name, this._settings.sections[name], icon);
} else if (name == "matrix" && !window.matrixEnabled) {
const addButton = document.createElement("div");
addButton.classList.add("tooltip", "left");
addButton.innerHTML = `
<span class="button ~neutral @low">+</span>
<span class="content sm">
${window.lang.strings("linkMatrix")}
</span>
`;
(addButton.querySelector("span.button") as HTMLSpanElement).onclick = this._addMatrix;
this.addSection(name, this._settings.sections[name], addButton);
} else { } else {
this.addSection(name, this._settings.sections[name]); if (name == "messages" || name == "user_page") {
const editButton = document.createElement("div");
editButton.classList.add("tooltip", "left");
editButton.innerHTML = `
<span class="button ~neutral @low">
<i class="icon ri-edit-line"></i>
</span>
<span class="content sm">
${window.lang.get("strings", "customizeMessages")}
</span>
`;
(editButton.querySelector("span.button") as HTMLSpanElement).onclick = () => {
this._messageEditor.showList(name == "messages" ? "email" : "user");
};
this.addSection(name, this._settings.sections[name], editButton);
} else if (name == "updates") {
const icon = document.createElement("span") as HTMLSpanElement;
if (window.updater.updateAvailable) {
icon.classList.add("button", "~urge");
icon.innerHTML = `<i class="ri-download-line" title="${window.lang.strings("update")}"></i>`;
icon.onclick = () => window.updater.checkForUpdates(window.modals.updateInfo.show);
}
this.addSection(name, this._settings.sections[name], icon);
} else if (name == "matrix" && !window.matrixEnabled) {
const addButton = document.createElement("div");
addButton.classList.add("tooltip", "left");
addButton.innerHTML = `
<span class="button ~neutral @low">+</span>
<span class="content sm">
${window.lang.strings("linkMatrix")}
</span>
`;
(addButton.querySelector("span.button") as HTMLSpanElement).onclick = this._addMatrix;
this.addSection(name, this._settings.sections[name], addButton);
} else {
this.addSection(name, this._settings.sections[name]);
}
} }
} }
removeLoader(this._loader);
for (let i = 0; i < this._loader.children.length; i++) {
this._loader.children[i].classList.remove("invisible");
}
this._showPanel(this._settings.order[0]);
document.dispatchEvent(new CustomEvent("settings-loaded"));
document.dispatchEvent(new CustomEvent("settings-advancedState", { detail: false }));
this._saveButton.classList.add("unfocused");
this._needsRestart = false;
} }
this._showPanel(this._settings.order[0]); })
document.dispatchEvent(new CustomEvent("settings-loaded")); };
document.dispatchEvent(new CustomEvent("settings-advancedState", { detail: false }));
this._saveButton.classList.add("unfocused");
this._needsRestart = false;
}
})
// FIXME: Search "About" & "User profiles", pseudo-search "User profiles" for things like "Ombi", "Referrals", etc. // FIXME: Search "About" & "User profiles", pseudo-search "User profiles" for things like "Ombi", "Referrals", etc.
search = (query: string) => { search = (query: string) => {