mirror of
https://github.com/hrfee/jfa-go.git
synced 2025-01-22 00:00:10 +00:00
Add accounts search
This commit is contained in:
parent
e6e5b0f3cf
commit
03247ddef8
@ -445,3 +445,7 @@ a:visited {
|
|||||||
a:hover, a:active {
|
a:hover, a:active {
|
||||||
color: var(--color-urge-200);
|
color: var(--color-urge-200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search {
|
||||||
|
max-width: 15rem;
|
||||||
|
}
|
||||||
|
@ -396,13 +396,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="tab-accounts" class="unfocused">
|
<div id="tab-accounts" class="unfocused">
|
||||||
<div class="card ~neutral !low accounts mb-1">
|
<div class="card ~neutral !low accounts mb-1">
|
||||||
<span class="heading">{{ .strings.accounts }}</span>
|
<div class="flex-expand">
|
||||||
<div class="fr">
|
<div class="flex-row">
|
||||||
<span class="button ~neutral !normal mb-half" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
|
<span class="heading">{{ .strings.accounts }}</span>
|
||||||
<span class="button ~info !normal mb-half" id="accounts-announce">{{ .strings.announce }}</span>
|
<input type="search" class="field ~neutral !normal input search ml-1" id="accounts-search" placeholder="{{ .strings.search }}">
|
||||||
<span class="button ~urge !normal mb-half" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
|
</div>
|
||||||
<span class="button ~warning !normal mb-half" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
|
<div>
|
||||||
<span class="button ~critical !normal mb-half" id="accounts-delete-user">{{ .quantityStrings.deleteUser.Singular }}</span>
|
<span class="button ~neutral !normal mb-half" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
|
||||||
|
<span class="button ~info !normal mb-half" id="accounts-announce">{{ .strings.announce }}</span>
|
||||||
|
<span class="button ~urge !normal mb-half" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
|
||||||
|
<span class="button ~warning !normal mb-half" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
|
||||||
|
<span class="button ~critical !normal mb-half" id="accounts-delete-user">{{ .quantityStrings.deleteUser.Singular }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card ~neutral !normal accounts-header table-responsive mt-half">
|
<div class="card ~neutral !normal accounts-header table-responsive mt-half">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
"updates": "Updates",
|
"updates": "Updates",
|
||||||
"update": "Update",
|
"update": "Update",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
|
"search": "Search",
|
||||||
"lastActiveTime": "Last Active",
|
"lastActiveTime": "Last Active",
|
||||||
"from": "From",
|
"from": "From",
|
||||||
"user": "User",
|
"user": "User",
|
||||||
|
@ -181,10 +181,13 @@ export class accountsList {
|
|||||||
private _modifySettingsUser = document.getElementById("radio-use-user") as HTMLInputElement;
|
private _modifySettingsUser = document.getElementById("radio-use-user") as HTMLInputElement;
|
||||||
private _profileSelect = document.getElementById("modify-user-profiles") as HTMLSelectElement;
|
private _profileSelect = document.getElementById("modify-user-profiles") as HTMLSelectElement;
|
||||||
private _userSelect = document.getElementById("modify-user-users") as HTMLSelectElement;
|
private _userSelect = document.getElementById("modify-user-users") as HTMLSelectElement;
|
||||||
|
private _search = document.getElementById("accounts-search") as HTMLInputElement;
|
||||||
|
|
||||||
private _selectAll = document.getElementById("accounts-select-all") as HTMLInputElement;
|
private _selectAll = document.getElementById("accounts-select-all") as HTMLInputElement;
|
||||||
private _users: { [id: string]: user };
|
private _users: { [id: string]: user };
|
||||||
|
private _sortedByName: string[] = [];
|
||||||
private _checkCount: number = 0;
|
private _checkCount: number = 0;
|
||||||
|
private _inSearch = false;
|
||||||
|
|
||||||
private _addUserForm = document.getElementById("form-add-user") as HTMLFormElement;
|
private _addUserForm = document.getElementById("form-add-user") as HTMLFormElement;
|
||||||
private _addUserName = this._addUserForm.querySelector("input[type=text]") as HTMLInputElement;
|
private _addUserName = this._addUserForm.querySelector("input[type=text]") as HTMLInputElement;
|
||||||
@ -208,25 +211,94 @@ export class accountsList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
search = (query: string): string[] => {
|
||||||
|
query = query.toLowerCase()
|
||||||
|
let result: string[] = [];
|
||||||
|
if (query.includes(":")) { // Support admin:<true/false> and disabled:<true/false>
|
||||||
|
const words = query.split(" ");
|
||||||
|
query = "";
|
||||||
|
for (let word of words) {
|
||||||
|
if (word.includes(":")) {
|
||||||
|
const querySplit = word.split(":")
|
||||||
|
let state = false;
|
||||||
|
if (querySplit[1] == "true") {
|
||||||
|
state = true;
|
||||||
|
}
|
||||||
|
for (let id in this._users) {
|
||||||
|
const user = this._users[id];
|
||||||
|
let attrib: boolean;
|
||||||
|
if (querySplit[0] == "admin") { attrib = user.admin; }
|
||||||
|
else if (querySplit[0] == "disabled") { attrib = user.disabled; }
|
||||||
|
if (attrib == state) { result.push(id); }
|
||||||
|
}
|
||||||
|
} else { query += word + " "; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (query == "") { return result; }
|
||||||
|
for (let id in this._users) {
|
||||||
|
const user = this._users[id];
|
||||||
|
if (user.name.toLowerCase().includes(query)) {
|
||||||
|
result.push(id);
|
||||||
|
} else if (user.email.toLowerCase().includes(query)) {
|
||||||
|
result.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
get selectAll(): boolean { return this._selectAll.checked; }
|
get selectAll(): boolean { return this._selectAll.checked; }
|
||||||
set selectAll(state: boolean) {
|
set selectAll(state: boolean) {
|
||||||
|
let count = 0;
|
||||||
for (let id in this._users) {
|
for (let id in this._users) {
|
||||||
this._users[id].selected = state;
|
if (this._table.contains(this._users[id].asElement())) { // Only select visible elements
|
||||||
|
this._users[id].selected = state;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this._selectAll.checked = state;
|
this._selectAll.checked = state;
|
||||||
this._selectAll.indeterminate = false;
|
this._selectAll.indeterminate = false;
|
||||||
state ? this._checkCount = Object.keys(this._users).length : 0;
|
state ? this._checkCount = count : 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add = (u: User) => {
|
add = (u: User) => {
|
||||||
let domAccount = new user(u);
|
let domAccount = new user(u);
|
||||||
this._users[u.id] = domAccount;
|
this._users[u.id] = domAccount;
|
||||||
this._table.appendChild(domAccount.asElement());
|
this.unhide(u.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
unhide = (id: string) => {
|
||||||
|
const keys = Object.keys(this._users);
|
||||||
|
if (keys.length == 0) {
|
||||||
|
this._table.appendChild(this._users[id].asElement());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._sortedByName = keys.sort((a, b) => this._users[a].name.localeCompare(this._users[b].name));
|
||||||
|
let index = this._sortedByName.indexOf(id)+1;
|
||||||
|
if (index == this._sortedByName.length-1) {
|
||||||
|
this._table.appendChild(this._users[id].asElement());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (index < this._sortedByName.length) {
|
||||||
|
if (this._table.contains(this._users[this._sortedByName[index]].asElement())) {
|
||||||
|
this._table.insertBefore(this._users[id].asElement(), this._users[this._sortedByName[index]].asElement());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
this._table.appendChild(this._users[id].asElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
hide = (id: string) => {
|
||||||
|
const el = this._users[id].asElement();
|
||||||
|
if (this._table.contains(el)) {
|
||||||
|
this._table.removeChild(this._users[id].asElement());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _checkCheckCount = () => {
|
private _checkCheckCount = () => {
|
||||||
|
const list = this._collectUsers();
|
||||||
|
this._checkCount = list.length;
|
||||||
if (this._checkCount == 0) {
|
if (this._checkCount == 0) {
|
||||||
this._selectAll.indeterminate = false;
|
this._selectAll.indeterminate = false;
|
||||||
this._selectAll.checked = false;
|
this._selectAll.checked = false;
|
||||||
@ -237,7 +309,13 @@ export class accountsList {
|
|||||||
}
|
}
|
||||||
this._extendExpiry.classList.add("unfocused");
|
this._extendExpiry.classList.add("unfocused");
|
||||||
} else {
|
} else {
|
||||||
if (this._checkCount == Object.keys(this._users).length) {
|
let visibleCount = 0;
|
||||||
|
for (let id in this._users) {
|
||||||
|
if (this._table.contains(this._users[id].asElement())) {
|
||||||
|
visibleCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this._checkCount == visibleCount) {
|
||||||
this._selectAll.checked = true;
|
this._selectAll.checked = true;
|
||||||
this._selectAll.indeterminate = false;
|
this._selectAll.indeterminate = false;
|
||||||
} else {
|
} else {
|
||||||
@ -246,12 +324,11 @@ export class accountsList {
|
|||||||
}
|
}
|
||||||
this._modifySettings.classList.remove("unfocused");
|
this._modifySettings.classList.remove("unfocused");
|
||||||
this._deleteUser.classList.remove("unfocused");
|
this._deleteUser.classList.remove("unfocused");
|
||||||
this._deleteUser.textContent = window.lang.quantity("deleteUser", this._checkCount);
|
this._deleteUser.textContent = window.lang.quantity("deleteUser", list.length);
|
||||||
if (window.emailEnabled) {
|
if (window.emailEnabled) {
|
||||||
this._announceButton.classList.remove("unfocused");
|
this._announceButton.classList.remove("unfocused");
|
||||||
}
|
}
|
||||||
const list = this._collectUsers();
|
let anyNonExpiries = list.length == 0 ? true : false;
|
||||||
let anyNonExpiries = false;
|
|
||||||
for (let id of list) {
|
for (let id of list) {
|
||||||
if (!this._users[id].expiry) {
|
if (!this._users[id].expiry) {
|
||||||
anyNonExpiries = true;
|
anyNonExpiries = true;
|
||||||
@ -268,7 +345,7 @@ export class accountsList {
|
|||||||
private _collectUsers = (): string[] => {
|
private _collectUsers = (): string[] => {
|
||||||
let list: string[] = [];
|
let list: string[] = [];
|
||||||
for (let id in this._users) {
|
for (let id in this._users) {
|
||||||
if (this._users[id].selected) { list.push(id); }
|
if (this._table.contains(this._users[id].asElement()) && this._users[id].selected) { list.push(id); }
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@ -312,7 +389,7 @@ export class accountsList {
|
|||||||
|
|
||||||
announce = () => {
|
announce = () => {
|
||||||
const modalHeader = document.getElementById("header-announce");
|
const modalHeader = document.getElementById("header-announce");
|
||||||
modalHeader.textContent = window.lang.quantity("announceTo", this._checkCount);
|
modalHeader.textContent = window.lang.quantity("announceTo", this._collectUsers().length);
|
||||||
const form = document.getElementById("form-announce") as HTMLFormElement;
|
const form = document.getElementById("form-announce") as HTMLFormElement;
|
||||||
let list = this._collectUsers();
|
let list = this._collectUsers();
|
||||||
const button = form.querySelector("span.submit") as HTMLSpanElement;
|
const button = form.querySelector("span.submit") as HTMLSpanElement;
|
||||||
@ -345,7 +422,7 @@ export class accountsList {
|
|||||||
|
|
||||||
deleteUsers = () => {
|
deleteUsers = () => {
|
||||||
const modalHeader = document.getElementById("header-delete-user");
|
const modalHeader = document.getElementById("header-delete-user");
|
||||||
modalHeader.textContent = window.lang.quantity("deleteNUsers", this._checkCount);
|
modalHeader.textContent = window.lang.quantity("deleteNUsers", this._collectUsers().length);
|
||||||
let list = this._collectUsers();
|
let list = this._collectUsers();
|
||||||
const form = document.getElementById("form-delete-user") as HTMLFormElement;
|
const form = document.getElementById("form-delete-user") as HTMLFormElement;
|
||||||
const button = form.querySelector("span.submit") as HTMLSpanElement;
|
const button = form.querySelector("span.submit") as HTMLSpanElement;
|
||||||
@ -371,7 +448,7 @@ export class accountsList {
|
|||||||
}
|
}
|
||||||
window.notifications.customError("deleteUserError", errorMsg);
|
window.notifications.customError("deleteUserError", errorMsg);
|
||||||
} else {
|
} else {
|
||||||
window.notifications.customSuccess("deleteUserSuccess", window.lang.quantity("deletedUser", this._checkCount));
|
window.notifications.customSuccess("deleteUserSuccess", window.lang.quantity("deletedUser", this._collectUsers().length));
|
||||||
}
|
}
|
||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
@ -382,7 +459,7 @@ export class accountsList {
|
|||||||
|
|
||||||
modifyUsers = () => {
|
modifyUsers = () => {
|
||||||
const modalHeader = document.getElementById("header-modify-user");
|
const modalHeader = document.getElementById("header-modify-user");
|
||||||
modalHeader.textContent = window.lang.quantity("modifySettingsFor", this._checkCount)
|
modalHeader.textContent = window.lang.quantity("modifySettingsFor", this._collectUsers().length)
|
||||||
let list = this._collectUsers();
|
let list = this._collectUsers();
|
||||||
(() => {
|
(() => {
|
||||||
let innerHTML = "";
|
let innerHTML = "";
|
||||||
@ -439,7 +516,7 @@ export class accountsList {
|
|||||||
}
|
}
|
||||||
window.notifications.customError("modifySettingsError", errorMsg);
|
window.notifications.customError("modifySettingsError", errorMsg);
|
||||||
} else if (req.status == 200 || req.status == 204) {
|
} else if (req.status == 200 || req.status == 204) {
|
||||||
window.notifications.customSuccess("modifySettingsSuccess", window.lang.quantity("appliedSettings", this._checkCount));
|
window.notifications.customSuccess("modifySettingsSuccess", window.lang.quantity("appliedSettings", this._collectUsers().length));
|
||||||
}
|
}
|
||||||
this.reload();
|
this.reload();
|
||||||
window.modals.modifyUser.close();
|
window.modals.modifyUser.close();
|
||||||
@ -484,7 +561,9 @@ export class accountsList {
|
|||||||
this._populateNumbers();
|
this._populateNumbers();
|
||||||
this._users = {};
|
this._users = {};
|
||||||
this._selectAll.checked = false;
|
this._selectAll.checked = false;
|
||||||
this._selectAll.onchange = () => { this.selectAll = this._selectAll.checked };
|
this._selectAll.onchange = () => {
|
||||||
|
this.selectAll = this._selectAll.checked;
|
||||||
|
};
|
||||||
document.addEventListener("accountCheckEvent", () => { this._checkCount++; this._checkCheckCount(); });
|
document.addEventListener("accountCheckEvent", () => { this._checkCount++; this._checkCheckCount(); });
|
||||||
document.addEventListener("accountUncheckEvent", () => { this._checkCount--; this._checkCheckCount(); });
|
document.addEventListener("accountUncheckEvent", () => { this._checkCount--; this._checkCheckCount(); });
|
||||||
this._addUserButton.onclick = window.modals.addUser.toggle;
|
this._addUserButton.onclick = window.modals.addUser.toggle;
|
||||||
@ -538,6 +617,36 @@ export class accountsList {
|
|||||||
this._deleteNotify.parentElement.classList.add("unfocused");
|
this._deleteNotify.parentElement.classList.add("unfocused");
|
||||||
this._deleteNotify.checked = false;
|
this._deleteNotify.checked = false;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
const setVisibility = (users: string[], visible: boolean) => {
|
||||||
|
for (let id in this._users) {
|
||||||
|
if (users.indexOf(id) != -1) {
|
||||||
|
if (visible) {
|
||||||
|
this.unhide(id);
|
||||||
|
} else {
|
||||||
|
this.hide(id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (visible) {
|
||||||
|
this.hide(id);
|
||||||
|
} else {
|
||||||
|
this.unhide(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._search.oninput = () => {
|
||||||
|
const query = this._search.value;
|
||||||
|
if (!query) {
|
||||||
|
setVisibility(Object.keys(this._users), true);
|
||||||
|
this._inSearch = false;
|
||||||
|
} else {
|
||||||
|
this._inSearch = true;
|
||||||
|
setVisibility(this.search(query), true);
|
||||||
|
}
|
||||||
|
this._checkCheckCount();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
reload = () => _get("/users", null, (req: XMLHttpRequest) => {
|
reload = () => _get("/users", null, (req: XMLHttpRequest) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user