mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-28 20:10:11 +00:00
Compare commits
8 Commits
76bb95098c
...
bf12016315
Author | SHA1 | Date | |
---|---|---|---|
bf12016315 | |||
b544931ee5 | |||
9cef626b28 | |||
708d382a3f | |||
f24ea4a5f8 | |||
6ddd09ff1f | |||
ddc560e862 | |||
6f452c62de |
@ -490,10 +490,10 @@ a:hover:not(.lang-link):not(.\~urge), a:active:not(.lang-link):not(.\~urge) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.search {
|
||||
/* .search {
|
||||
max-width: 15rem;
|
||||
min-width: 10rem;
|
||||
}
|
||||
} */
|
||||
|
||||
td.img-circle {
|
||||
width: 32px;
|
||||
@ -548,6 +548,11 @@ div.card:contains(section.banner.footer) {
|
||||
padding-bottom: 0px !important
|
||||
}
|
||||
|
||||
.mx-0i {
|
||||
margin-left: 0px !important;
|
||||
margin-right: 0px !important
|
||||
}
|
||||
|
||||
.text-center-i {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
@ -580,49 +580,50 @@
|
||||
</div>
|
||||
<div id="tab-accounts" class="unfocused">
|
||||
<div class="card @low dark:~d_neutral accounts mb-4 overflow-visible">
|
||||
<div class="flex-expand row">
|
||||
<div class="row w-6/12">
|
||||
<span class="text-3xl font-bold mr-2 col">{{ .strings.accounts }}</span>
|
||||
<input type="search" class="col sm field ~neutral @low input search ml-2 mr-2" id="accounts-search" placeholder="{{ .strings.search }}">
|
||||
<div id="accounts-filter-dropdown" class="col sm dropdown pb-0i" tabindex="0">
|
||||
<span class="h-100 sm button ~neutral @low center mb-2" id="accounts-filter-button">{{ .strings.filters }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low mt-2" id="accounts-filter-list">
|
||||
<p class="supra pb-2">{{ .strings.filters }}</p>
|
||||
</div>
|
||||
<div class="flex-expand align-middle">
|
||||
<span class="text-3xl font-bold mr-4">{{ .strings.accounts }}</span>
|
||||
<div id="accounts-filter-dropdown" class="dropdown z-10" tabindex="0">
|
||||
<span class="h-100 button ~neutral @low center" id="accounts-filter-button">{{ .strings.filters }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low mt-2" id="accounts-filter-list">
|
||||
<p class="supra pb-2">{{ .strings.filters }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col sm button ~neutral @low center mb-2" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
|
||||
<div id="accounts-announce-dropdown" class="col sm dropdown pb-0i" tabindex="0">
|
||||
<span class="h-100 sm button ~info @low center mb-2" id="accounts-announce">{{ .strings.announce }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<span class="supra sm">{{ .strings.templates }}</span>
|
||||
<div id="accounts-announce-templates"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col sm button ~urge @low center mb-2" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
|
||||
<span class="col sm button ~warning @low center mb-2" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
|
||||
<div id="accounts-disable-enable-dropdown" class="col sm dropdown manual pb-0i" tabindex="0">
|
||||
<span class="h-100 sm button ~positive @low center mb-2" id="accounts-disable-enable">{{ .strings.disable }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<span class="button ~urge sm full-width accounts-announce-template-button" id="accounts-enable-expiry">{{ .strings.setExpiry }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col sm button ~info @low center mb-2 unfocused" id="accounts-send-pwr">{{ .strings.sendPWR }}</span>
|
||||
<span class="col sm button ~critical @low center mb-2" id="accounts-delete-user">{{ .quantityStrings.deleteUser.Singular }}</span>
|
||||
</div>
|
||||
<input type="search" class="field ~neutral @low input search ml-2 mr-2" id="accounts-search" placeholder="{{ .strings.search }}">
|
||||
<span class="button ~neutral @low center -ml-8" id="accounts-search-clear" aria-label="{{ .strings.clearSearch }}" text="{{ .strings.clearSearch }}"><i class="ri-close-line"></i></span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button type="button" class="button ~neutral @low center ml-2 mr-2 hidden"><span id="accounts-sort-by-field"></span> <span class="ml-2">×</span></button>
|
||||
<div class="supra py-1 sm hidden" id="accounts-search-options-header">{{ .strings.searchOptions }}</div>
|
||||
<div class="row -mx-2">
|
||||
<button type="button" class="button ~neutral @low center m-2 hidden"><span id="accounts-sort-by-field"></span> <i class="ri-close-line ml-2 text-2xl"></i></button>
|
||||
<span id="accounts-filter-area"></span>
|
||||
</div>
|
||||
<div class="card @low accounts-header table-responsive mt-8">
|
||||
<div class="supra py-1 sm">{{ .strings.actions }}</div>
|
||||
<div class="row -mx-2">
|
||||
<span class="col button ~neutral @low center max-w-[20%]" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
|
||||
<div id="accounts-announce-dropdown" class="col dropdown pb-0i max-w-[20%]" tabindex="0">
|
||||
<span class="w-100 button ~info @low center" id="accounts-announce">{{ .strings.announce }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<span class="supra sm">{{ .strings.templates }}</span>
|
||||
<div id="accounts-announce-templates"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col button ~urge @low center max-w-[20%]" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
|
||||
<span class="col button ~warning @low center max-w-[20%]" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
|
||||
<div id="accounts-disable-enable-dropdown" class="col dropdown manual pb-0i max-w-[20%]" tabindex="0">
|
||||
<span class="w-100 button ~positive @low center" id="accounts-disable-enable">{{ .strings.disable }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<span class="button ~urge full-width accounts-announce-template-button" id="accounts-enable-expiry">{{ .strings.setExpiry }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col button ~info @low center unfocused max-w-[20%]" id="accounts-send-pwr">{{ .strings.sendPWR }}</span>
|
||||
<span class="col button ~critical @low center max-w-[20%]" id="accounts-delete-user">{{ .quantityStrings.deleteUser.Singular }}</span>
|
||||
</div>
|
||||
<div class="card @low accounts-header table-responsive mt-2">
|
||||
<table class="table text-base leading-4">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -119,7 +119,12 @@
|
||||
"accessJFASettings": "Cannot be changed as either \"Admin Only\" or \"Allow All\" has been set in Settings > General.",
|
||||
"sortingBy": "Sorting By",
|
||||
"filters": "Filters",
|
||||
"clickToRemoveFilter": "Click to remove this filter."
|
||||
"clickToRemoveFilter": "Click to remove this filter.",
|
||||
"clearSearch": "Clear search",
|
||||
"actions": "Actions",
|
||||
"searchOptions": "Search Options",
|
||||
"matchText": "Match Text",
|
||||
"jellyfinID": "Jellyfin ID"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Changed email address of {n}.",
|
||||
|
@ -39,6 +39,7 @@ interface announcementTemplate {
|
||||
var addDiscord: (passData: string) => void;
|
||||
|
||||
class user implements User {
|
||||
private _id = "";
|
||||
private _row: HTMLTableRowElement;
|
||||
private _check: HTMLInputElement;
|
||||
private _username: HTMLSpanElement;
|
||||
@ -67,7 +68,6 @@ class user implements User {
|
||||
private _userLabel: string;
|
||||
private _labelEditButton: HTMLElement;
|
||||
private _accounts_admin: HTMLInputElement
|
||||
id = "";
|
||||
private _selected: boolean;
|
||||
|
||||
lastNotifyMethod = (): string => {
|
||||
@ -690,6 +690,9 @@ class user implements User {
|
||||
}
|
||||
});
|
||||
|
||||
get id() { return this._id; }
|
||||
set id(v: string) { this._id = v; }
|
||||
|
||||
|
||||
update = (user: User) => {
|
||||
this.id = user.id;
|
||||
@ -768,6 +771,8 @@ export class accountsList {
|
||||
private _activeSortColumn: string;
|
||||
|
||||
private _sortingByButton = document.getElementById("accounts-sort-by-field") as HTMLButtonElement;
|
||||
private _filterArea = document.getElementById("accounts-filter-area");
|
||||
private _searchOptionsHeader = document.getElementById("accounts-search-options-header");
|
||||
|
||||
// Whether the "Extend expiry" is extending or setting an expiry.
|
||||
private _settingExpiry = false;
|
||||
@ -790,30 +795,42 @@ export class accountsList {
|
||||
}
|
||||
}
|
||||
|
||||
showHideSearchOptionsHeader = () => {
|
||||
const sortingBy = !(this._sortingByButton.parentElement.classList.contains("hidden"));
|
||||
const hasFilters = this._filterArea.textContent != "";
|
||||
console.log("sortingBy", sortingBy, "hasFilters", hasFilters);
|
||||
if (sortingBy || hasFilters) {
|
||||
this._searchOptionsHeader.classList.remove("hidden");
|
||||
} else {
|
||||
this._searchOptionsHeader.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
private _queries: { [field: string]: { name: string, getter: string, bool: boolean, string: boolean, date: boolean, dependsOnTableHeader?: string, show?: boolean }} = {
|
||||
"id": {
|
||||
name: "Jellyfin ID",
|
||||
// We don't use a translation here to circumvent the name substitution feature.
|
||||
name: "Jellyfin/Emby ID",
|
||||
getter: "id",
|
||||
bool: false,
|
||||
string: true,
|
||||
date: false
|
||||
},
|
||||
"label": {
|
||||
name: "Label",
|
||||
name: window.lang.strings("label"),
|
||||
getter: "label",
|
||||
bool: true,
|
||||
string: true,
|
||||
date: false
|
||||
},
|
||||
"username": {
|
||||
name: "Username",
|
||||
name: window.lang.strings("username"),
|
||||
getter: "name",
|
||||
bool: false,
|
||||
string: true,
|
||||
date: false
|
||||
},
|
||||
"name": {
|
||||
name: "Username",
|
||||
name: window.lang.strings("username"),
|
||||
getter: "name",
|
||||
bool: false,
|
||||
string: true,
|
||||
@ -821,21 +838,21 @@ export class accountsList {
|
||||
show: false
|
||||
},
|
||||
"admin": {
|
||||
name: "Admin",
|
||||
name: window.lang.strings("admin"),
|
||||
getter: "admin",
|
||||
bool: true,
|
||||
string: false,
|
||||
date: false
|
||||
},
|
||||
"disabled": {
|
||||
name: "Disabled",
|
||||
name: window.lang.strings("disabled"),
|
||||
getter: "disabled",
|
||||
bool: true,
|
||||
string: false,
|
||||
date: false
|
||||
},
|
||||
"access-jfa": {
|
||||
name: "Access jfa-go",
|
||||
name: window.lang.strings("accessJFA"),
|
||||
getter: "accounts_admin",
|
||||
bool: true,
|
||||
string: false,
|
||||
@ -843,7 +860,7 @@ export class accountsList {
|
||||
dependsOnTableHeader: "accounts-header-access-jfa"
|
||||
},
|
||||
"email": {
|
||||
name: "Email",
|
||||
name: window.lang.strings("emailAddress"),
|
||||
getter: "email",
|
||||
bool: true,
|
||||
string: true,
|
||||
@ -875,7 +892,7 @@ export class accountsList {
|
||||
dependsOnTableHeader: "accounts-header-discord"
|
||||
},
|
||||
"expiry": {
|
||||
name: "Expiry",
|
||||
name: window.lang.strings("expiry"),
|
||||
getter: "expiry",
|
||||
bool: true,
|
||||
string: false,
|
||||
@ -883,7 +900,7 @@ export class accountsList {
|
||||
dependsOnTableHeader: "accounts-header-expiry"
|
||||
},
|
||||
"last-active": {
|
||||
name: "Last Active",
|
||||
name: window.lang.strings("lastActiveTime"),
|
||||
getter: "last_active",
|
||||
bool: true,
|
||||
string: false,
|
||||
@ -892,8 +909,8 @@ export class accountsList {
|
||||
}
|
||||
|
||||
search = (query: String): string[] => {
|
||||
const filterArea = document.getElementById("accounts-filter-area");
|
||||
filterArea.textContent = "";
|
||||
console.log(this._queries);
|
||||
this._filterArea.textContent = "";
|
||||
|
||||
query = query.toLowerCase();
|
||||
let result: string[] = [...this._ordering];
|
||||
@ -970,7 +987,7 @@ export class accountsList {
|
||||
// FIXME: Generate filter card for each filter class
|
||||
const filterCard = document.createElement("span");
|
||||
filterCard.ariaLabel = window.lang.strings("clickToRemoveFilter");
|
||||
filterCard.classList.add("button", "~" + (boolState ? "positive" : "critical"), "@high", "center", "ml-2", "mr-2");
|
||||
filterCard.classList.add("button", "~" + (boolState ? "positive" : "critical"), "@high", "center", "m-2");
|
||||
filterCard.innerHTML = `
|
||||
<span class="font-bold mr-2">${queryFormat.name}</span>
|
||||
<i class="text-2xl ri-${boolState? "checkbox" : "close"}-circle-fill"></i>
|
||||
@ -983,7 +1000,7 @@ export class accountsList {
|
||||
this._search.oninput((null as Event));
|
||||
})
|
||||
|
||||
filterArea.appendChild(filterCard);
|
||||
this._filterArea.appendChild(filterCard);
|
||||
|
||||
// console.log("is bool, state", boolState);
|
||||
// So removing elements doesn't affect us
|
||||
@ -1004,7 +1021,7 @@ export class accountsList {
|
||||
if (queryFormat.string) {
|
||||
const filterCard = document.createElement("span");
|
||||
filterCard.ariaLabel = window.lang.strings("clickToRemoveFilter");
|
||||
filterCard.classList.add("button", "~neutral", "@low", "center", "ml-2", "mr-2", "h-full");
|
||||
filterCard.classList.add("button", "~neutral", "@low", "center", "m-2", "h-full");
|
||||
filterCard.innerHTML = `
|
||||
<span class="font-bold mr-2">${queryFormat.name}:</span> "${split[1]}"
|
||||
`;
|
||||
@ -1017,7 +1034,7 @@ export class accountsList {
|
||||
this._search.oninput((null as Event));
|
||||
})
|
||||
|
||||
filterArea.appendChild(filterCard);
|
||||
this._filterArea.appendChild(filterCard);
|
||||
|
||||
let cachedResult = [...result];
|
||||
for (let id of cachedResult) {
|
||||
@ -1048,7 +1065,7 @@ export class accountsList {
|
||||
|
||||
const filterCard = document.createElement("span");
|
||||
filterCard.ariaLabel = window.lang.strings("clickToRemoveFilter");
|
||||
filterCard.classList.add("button", "~neutral", "@low", "center", "ml-2", "mr-2", "h-full");
|
||||
filterCard.classList.add("button", "~neutral", "@low", "center", "m-2", "h-full");
|
||||
filterCard.innerHTML = `
|
||||
<span class="font-bold mr-2">${queryFormat.name}:</span> ${(compareType == 1) ? window.lang.strings("after")+" " : ((compareType == -1) ? window.lang.strings("before")+" " : "")}${split[1]}
|
||||
`;
|
||||
@ -1062,7 +1079,7 @@ export class accountsList {
|
||||
this._search.oninput((null as Event));
|
||||
})
|
||||
|
||||
filterArea.appendChild(filterCard);
|
||||
this._filterArea.appendChild(filterCard);
|
||||
|
||||
let cachedResult = [...result];
|
||||
for (let id of cachedResult) {
|
||||
@ -1138,10 +1155,10 @@ export class accountsList {
|
||||
this._modifySettings.classList.add("unfocused");
|
||||
this._deleteUser.classList.add("unfocused");
|
||||
if (window.emailEnabled || window.telegramEnabled) {
|
||||
this._announceButton.classList.add("unfocused");
|
||||
this._announceButton.parentElement.classList.add("unfocused");
|
||||
}
|
||||
this._extendExpiry.classList.add("unfocused");
|
||||
this._disableEnable.classList.add("unfocused");
|
||||
this._disableEnable.parentElement.classList.add("unfocused");
|
||||
this._sendPWR.classList.add("unfocused");
|
||||
} else {
|
||||
let visibleCount = 0;
|
||||
@ -1161,7 +1178,7 @@ export class accountsList {
|
||||
this._deleteUser.classList.remove("unfocused");
|
||||
this._deleteUser.textContent = window.lang.quantity("deleteUser", list.length);
|
||||
if (window.emailEnabled || window.telegramEnabled) {
|
||||
this._announceButton.classList.remove("unfocused");
|
||||
this._announceButton.parentElement.classList.remove("unfocused");
|
||||
}
|
||||
let anyNonExpiries = list.length == 0 ? true : false;
|
||||
let allNonExpiries = true;
|
||||
@ -1179,7 +1196,7 @@ export class accountsList {
|
||||
}
|
||||
if (showDisableEnable && this._users[id].disabled != this._shouldEnable) {
|
||||
showDisableEnable = false;
|
||||
this._disableEnable.classList.add("unfocused");
|
||||
this._disableEnable.parentElement.classList.add("unfocused");
|
||||
}
|
||||
if (!showDisableEnable && anyNonExpiries) { break; }
|
||||
if (!this._users[id].lastNotifyMethod()) {
|
||||
@ -1215,7 +1232,7 @@ export class accountsList {
|
||||
this._disableEnable.classList.add("~warning");
|
||||
this._disableEnable.classList.remove("~positive");
|
||||
}
|
||||
this._disableEnable.classList.remove("unfocused");
|
||||
this._disableEnable.parentElement.classList.remove("unfocused");
|
||||
this._disableEnable.textContent = message;
|
||||
}
|
||||
}
|
||||
@ -1764,13 +1781,13 @@ export class accountsList {
|
||||
this._deleteUser.classList.add("unfocused");
|
||||
|
||||
this._announceButton.onclick = this.announce;
|
||||
this._announceButton.classList.add("unfocused");
|
||||
this._announceButton.parentElement.classList.add("unfocused");
|
||||
|
||||
this._extendExpiry.onclick = () => { this.extendExpiry(); };
|
||||
this._extendExpiry.classList.add("unfocused");
|
||||
|
||||
this._disableEnable.onclick = this.enableDisableUsers;
|
||||
this._disableEnable.classList.add("unfocused");
|
||||
this._disableEnable.parentElement.classList.add("unfocused");
|
||||
|
||||
this._enableExpiry.onclick = () => { this.extendExpiry(true); };
|
||||
this._enableExpiryNotify.onchange = () => {
|
||||
@ -1796,17 +1813,26 @@ export class accountsList {
|
||||
this._deleteNotify.checked = false;
|
||||
}*/
|
||||
|
||||
this._search.oninput = () => {
|
||||
const onchange = () => {
|
||||
const query = this._search.value;
|
||||
if (!query) {
|
||||
this.setVisibility(this._ordering, true);
|
||||
// this.setVisibility(this._ordering, true);
|
||||
this._inSearch = false;
|
||||
} else {
|
||||
this._inSearch = true;
|
||||
this.setVisibility(this.search(query), true);
|
||||
// this.setVisibility(this.search(query), true);
|
||||
}
|
||||
this.setVisibility(this.search(query), true);
|
||||
this._checkCheckCount();
|
||||
this.showHideSearchOptionsHeader();
|
||||
};
|
||||
this._search.oninput = onchange;
|
||||
|
||||
const clearSearchButton = document.getElementById("accounts-search-clear") as HTMLSpanElement;
|
||||
clearSearchButton.addEventListener("click", () => {
|
||||
this._search.value = "";
|
||||
onchange();
|
||||
});
|
||||
|
||||
this._announceTextarea.onkeyup = this.loadPreview;
|
||||
addDiscord = newDiscordSearch(window.lang.strings("linkDiscord"), window.lang.strings("searchDiscordUser"), window.lang.strings("add"), (user: DiscordUser, id: string) => {
|
||||
@ -1846,6 +1872,7 @@ export class accountsList {
|
||||
this._columns[this._activeSortColumn].ascending = true;
|
||||
this._columns[this._activeSortColumn].hideIcon();
|
||||
this._sortingByButton.parentElement.classList.add("hidden");
|
||||
this.showHideSearchOptionsHeader();
|
||||
};
|
||||
|
||||
this._sortingByButton.parentElement.addEventListener("click", defaultSort);
|
||||
@ -1861,9 +1888,11 @@ export class accountsList {
|
||||
} else {
|
||||
this.setVisibility(this.search(this._search.value), true);
|
||||
}
|
||||
this.showHideSearchOptionsHeader();
|
||||
});
|
||||
|
||||
defaultSort();
|
||||
this.showHideSearchOptionsHeader();
|
||||
|
||||
const filterList = document.getElementById("accounts-filter-list");
|
||||
|
||||
@ -1910,7 +1939,7 @@ export class accountsList {
|
||||
const button = document.createElement("button") as HTMLButtonElement;
|
||||
button.type = "button";
|
||||
button.classList.add("button", "~urge", "ml-2");
|
||||
button.innerHTML = `<i class="ri-equal-line mr-2"></i>Match Text`;
|
||||
button.innerHTML = `<i class="ri-equal-line mr-2"></i>${window.lang.strings("matchText")}`;
|
||||
|
||||
// Position cursor between quotes
|
||||
button.addEventListener("click", () => fillInFilter(queryName, `""`, -1));
|
||||
|
Loading…
Reference in New Issue
Block a user