mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 17:10:10 +00:00
settings: "no results found", section matching
No results found screen added, nd when a section name matches the search, all settings in the section are shown normally.
This commit is contained in:
parent
6909477f45
commit
73cfa5bef2
@ -731,13 +731,23 @@
|
|||||||
<div class="card @low dark:~d_neutral col" id="settings-sidebar">
|
<div class="card @low dark:~d_neutral col" id="settings-sidebar">
|
||||||
<div class="flex-expand">
|
<div class="flex-expand">
|
||||||
<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 mb-2" id="settings-search" placeholder="{{ .strings.search }}">
|
||||||
<button class="button ~neutral @low center -ml-8 mb-2" id="settings-search-clear" aria-label="{{ .strings.clearSearch }}" text="{{ .strings.clearSearch }}"><i class="ri-close-line"></i></button>
|
<button class="button ~neutral @low center -ml-8 mb-2 settings-search-clear" aria-label="{{ .strings.clearSearch }}" text="{{ .strings.clearSearch }}"><i class="ri-close-line"></i></button>
|
||||||
</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>
|
<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-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>
|
<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>
|
<div class="card ~neutral @low col overflow" id="settings-panel">
|
||||||
|
<div class="settings-section unfocused h-[100%]" id="settings-not-found">
|
||||||
|
<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="mb-2 px-12 text-center">{{ .strings.settingsMaybeUnderAdvanced }}</span>
|
||||||
|
<button class="button ~neutral @low settings-search-clear">
|
||||||
|
<span class="mr-2">{{ .strings.clearSearch }}</span><i class="ri-close-line"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
"donate": "Donate",
|
"donate": "Donate",
|
||||||
"unlink": "Unlink Account",
|
"unlink": "Unlink Account",
|
||||||
"sendPWR": "Send Password Reset",
|
"sendPWR": "Send Password Reset",
|
||||||
|
"noResultsFound": "No Results Found",
|
||||||
"contactThrough": "Contact through:",
|
"contactThrough": "Contact through:",
|
||||||
"extendExpiry": "Extend expiry",
|
"extendExpiry": "Extend expiry",
|
||||||
"sendPWRManual": "User {n} has no method of contact, press copy to get a link to send to them.",
|
"sendPWRManual": "User {n} has no method of contact, press copy to get a link to send to them.",
|
||||||
@ -86,6 +87,7 @@
|
|||||||
"settingsHiddenDependency": "Matching settings are hidden because they depend on the value of another setting:",
|
"settingsHiddenDependency": "Matching settings are hidden because they depend on the value of another setting:",
|
||||||
"settingsDependsOn": "{setting}: Depends on {dependency}",
|
"settingsDependsOn": "{setting}: Depends on {dependency}",
|
||||||
"settingsAdvancedMode": "{setting}: Advanced Settings must be enabled",
|
"settingsAdvancedMode": "{setting}: Advanced Settings must be enabled",
|
||||||
|
"settingsMaybeUnderAdvanced": "Tip: You might find what you're looking for by enabling Advanced Settings.",
|
||||||
"ombiProfile": "Ombi user profile",
|
"ombiProfile": "Ombi user profile",
|
||||||
"ombiUserDefaultsDescription": "Create an Ombi user and configure it, then select it below. It's settings/permissions will be stored and applied to new Ombi users created by jfa-go when this profile is selected.",
|
"ombiUserDefaultsDescription": "Create an Ombi user and configure it, then select it below. It's settings/permissions will be stored and applied to new Ombi users created by jfa-go when this profile is selected.",
|
||||||
"userProfiles": "User Profiles",
|
"userProfiles": "User Profiles",
|
||||||
@ -125,7 +127,7 @@
|
|||||||
"jellyfinID": "Jellyfin ID",
|
"jellyfinID": "Jellyfin ID",
|
||||||
"userPageLogin": "User Page: Login",
|
"userPageLogin": "User Page: Login",
|
||||||
"userPagePage": "User Page: Page",
|
"userPagePage": "User Page: Page",
|
||||||
"buildTime": "Build Time",
|
"buildTime": "Build Time",
|
||||||
"builtBy": "Built By",
|
"builtBy": "Built By",
|
||||||
"loginNotAdmin": "Not an Admin?"
|
"loginNotAdmin": "Not an Admin?"
|
||||||
},
|
},
|
||||||
|
@ -622,6 +622,7 @@ export class settingsList {
|
|||||||
|
|
||||||
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 _sections: { [name: string]: sectionPanel }
|
private _sections: { [name: string]: sectionPanel }
|
||||||
private _buttons: { [name: string]: HTMLSpanElement }
|
private _buttons: { [name: string]: HTMLSpanElement }
|
||||||
private _needsRestart: boolean = false;
|
private _needsRestart: boolean = false;
|
||||||
@ -630,7 +631,9 @@ export class settingsList {
|
|||||||
private _advanced: boolean = false;
|
private _advanced: boolean = false;
|
||||||
|
|
||||||
private _searchbox: HTMLInputElement = document.getElementById("settings-search") as HTMLInputElement;
|
private _searchbox: HTMLInputElement = document.getElementById("settings-search") as HTMLInputElement;
|
||||||
private _clearSearchbox: HTMLButtonElement = document.getElementById("settings-search-clear") as HTMLButtonElement;
|
private _clearSearchboxButtons: Array<HTMLButtonElement> = Array.from(document.getElementsByClassName("settings-search-clear")) as Array<HTMLButtonElement>;
|
||||||
|
|
||||||
|
private _noResultsPanel: HTMLElement = document.getElementById("settings-not-found");
|
||||||
|
|
||||||
|
|
||||||
addSection = (name: string, s: Section, subButton?: HTMLElement) => {
|
addSection = (name: string, s: Section, subButton?: HTMLElement) => {
|
||||||
@ -681,6 +684,7 @@ export class settingsList {
|
|||||||
for (let n in this._sections) {
|
for (let n in this._sections) {
|
||||||
if (n == name) {
|
if (n == name) {
|
||||||
this._sections[name].visible = true;
|
this._sections[name].visible = true;
|
||||||
|
this._visibleSection = name;
|
||||||
this._buttons[name].classList.add("selected");
|
this._buttons[name].classList.add("selected");
|
||||||
} else {
|
} else {
|
||||||
this._sections[n].visible = false;
|
this._sections[n].visible = false;
|
||||||
@ -763,9 +767,11 @@ export class settingsList {
|
|||||||
this._searchbox.oninput = () => {
|
this._searchbox.oninput = () => {
|
||||||
this.search(this._searchbox.value);
|
this.search(this._searchbox.value);
|
||||||
};
|
};
|
||||||
this._clearSearchbox.onclick = () => {
|
for (let b of this._clearSearchboxButtons) {
|
||||||
this._searchbox.value = "";
|
b.onclick = () => {
|
||||||
this._searchbox.oninput(null);
|
this._searchbox.value = "";
|
||||||
|
this._searchbox.oninput(null);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,8 +867,11 @@ export class settingsList {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// FIXME: Search "About" & "User profiles", pseudo-search "User profiles" for things like "Ombi", "Referrals", etc.
|
||||||
search = (query: string) => {
|
search = (query: string) => {
|
||||||
query = query.toLowerCase();
|
query = query.toLowerCase().trim();
|
||||||
|
// Make sure a blank search is detected when there's just whitespace.
|
||||||
|
if (query.replace(/\s+/g, "") == "") query = "";
|
||||||
|
|
||||||
let firstVisibleSection = "";
|
let firstVisibleSection = "";
|
||||||
for (let section of this._settings.order) {
|
for (let section of this._settings.order) {
|
||||||
@ -875,12 +884,15 @@ export class settingsList {
|
|||||||
// hide button, unhide if matched
|
// hide button, unhide if matched
|
||||||
this._buttons[section].classList.add("unfocused");
|
this._buttons[section].classList.add("unfocused");
|
||||||
|
|
||||||
|
let matchedSection = false;
|
||||||
|
|
||||||
if (section.toLowerCase().includes(query) ||
|
if (section.toLowerCase().includes(query) ||
|
||||||
this._settings.sections[section].meta.name.toLowerCase().includes(query) ||
|
this._settings.sections[section].meta.name.toLowerCase().includes(query) ||
|
||||||
this._settings.sections[section].meta.description.toLowerCase().includes(query)) {
|
this._settings.sections[section].meta.description.toLowerCase().includes(query)) {
|
||||||
if ((this._settings.sections[section].meta.advanced && this._advanced) || !(this._settings.sections[section].meta.advanced)) {
|
if ((this._settings.sections[section].meta.advanced && this._advanced) || !(this._settings.sections[section].meta.advanced)) {
|
||||||
this._buttons[section].classList.remove("unfocused");
|
this._buttons[section].classList.remove("unfocused");
|
||||||
firstVisibleSection = firstVisibleSection || section;
|
firstVisibleSection = firstVisibleSection || section;
|
||||||
|
matchedSection = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const sectionElement = this._sections[section].asElement();
|
const sectionElement = this._sections[section].asElement();
|
||||||
@ -888,6 +900,13 @@ export class settingsList {
|
|||||||
if (this._settings.sections[section].settings[setting].type == "note") continue;
|
if (this._settings.sections[section].settings[setting].type == "note") continue;
|
||||||
const element = sectionElement.querySelector(`div[data-name="${setting}"]`) as HTMLElement;
|
const element = sectionElement.querySelector(`div[data-name="${setting}"]`) as HTMLElement;
|
||||||
|
|
||||||
|
// If we match the whole section, don't bother searching settings.
|
||||||
|
if (matchedSection) {
|
||||||
|
element.classList.remove("opacity-50", "pointer-events-none");
|
||||||
|
element.setAttribute("aria-disabled", "false");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// element.classList.remove("-mx-2", "my-2", "p-2", "aside", "~neutral", "@low");
|
// element.classList.remove("-mx-2", "my-2", "p-2", "aside", "~neutral", "@low");
|
||||||
element.classList.add("opacity-50", "pointer-events-none");
|
element.classList.add("opacity-50", "pointer-events-none");
|
||||||
element.setAttribute("aria-disabled", "true");
|
element.setAttribute("aria-disabled", "true");
|
||||||
@ -902,12 +921,12 @@ export class settingsList {
|
|||||||
const shouldShow = (query != "" &&
|
const shouldShow = (query != "" &&
|
||||||
((this._settings.sections[section].settings[setting].advanced && this._advanced) ||
|
((this._settings.sections[section].settings[setting].advanced && this._advanced) ||
|
||||||
!(this._settings.sections[section].settings[setting].advanced)));
|
!(this._settings.sections[section].settings[setting].advanced)));
|
||||||
if (shouldShow) {
|
if (shouldShow || query == "") {
|
||||||
// element.classList.add("-mx-2", "my-2", "p-2", "aside", "~neutral", "@low");
|
// element.classList.add("-mx-2", "my-2", "p-2", "aside", "~neutral", "@low");
|
||||||
element.classList.remove("opacity-50", "pointer-events-none");
|
element.classList.remove("opacity-50", "pointer-events-none");
|
||||||
element.setAttribute("aria-disabled", "false");
|
element.setAttribute("aria-disabled", "false");
|
||||||
}
|
}
|
||||||
if ((shouldShow && element.querySelector("label").classList.contains("unfocused")) || (!shouldShow)) {
|
if (query != "" && ((shouldShow && element.querySelector("label").classList.contains("unfocused")) || (!shouldShow))) {
|
||||||
// Add a note explaining why the setting is hidden
|
// Add a note explaining why the setting is hidden
|
||||||
if (!dependencyCard) {
|
if (!dependencyCard) {
|
||||||
dependencyCard = document.createElement("aside");
|
dependencyCard = document.createElement("aside");
|
||||||
@ -942,10 +961,16 @@ export class settingsList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (firstVisibleSection) {
|
if (firstVisibleSection && (query != "" || this._visibleSection == "")) {
|
||||||
this._buttons[firstVisibleSection].onclick(null);
|
this._buttons[firstVisibleSection].onclick(null);
|
||||||
} else {
|
this._noResultsPanel.classList.add("unfocused");
|
||||||
// FIXME: Show "no results found" in right panel (mention enabling advanced settings
|
} else if (query != "") {
|
||||||
|
this._noResultsPanel.classList.remove("unfocused");
|
||||||
|
if (this._visibleSection) {
|
||||||
|
this._sections[this._visibleSection].visible = false;
|
||||||
|
this._buttons[this._visibleSection].classList.remove("selected");
|
||||||
|
this._visibleSection = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user