accounts: show table row when clicking into details, more usage of

RadioBasedTabs

when clicking a username in the accounts tab, the details comes up with
a copy of the row you clicked, so you can view logs and edit the user.
Also decided not to use a RadioBasedTab here, instead providing a link
to the activity tab with a search for the user (added the ability to do
that, ?user=username). FIXME: handle deleting the user or just generally
editing them.
This commit is contained in:
Harvey Tindall
2025-12-23 20:37:29 +00:00
parent c3bac6c51c
commit 748acc13c0
6 changed files with 140 additions and 142 deletions

View File

@@ -0,0 +1,24 @@
<thead id="accounts-table-header">
<tr>
<th><input type="checkbox" value="" id="accounts-select-all"></th>
<th class="table-inline my-2 grid gap-4 place-items-stretch accounts-header-username">{{ .strings.username }}</th>
{{ if .jellyfinLogin }}
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-access-jfa">{{ .strings.accessJFA }}</th>
{{ end }}
<th class="grid gap-4 place-items-stretch accounts-header-email">{{ .strings.emailAddress }}</th>
{{ if .telegramEnabled }}
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-telegram">Telegram</th>
{{ end }}
{{ if .matrixEnabled }}
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-matrix">Matrix</th>
{{ end }}
{{ if .discordEnabled }}
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-discord">Discord</th>
{{ end }}
{{ if .referralsEnabled }}
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-referrals">{{ .strings.referrals }}</th>
{{ end }}
<th class="grid gap-4 place-items-stretch accounts-header-expiry">{{ .strings.expiry }}</th>
<th class="grid gap-4 place-items-stretch accounts-header-last-active">{{ .strings.lastActiveTime }}</th>
</tr>
</thead>

View File

@@ -86,16 +86,7 @@
<span class="heading"><span id="header-modify-user"></span> <span class="modal-close">&times;</span></span> <span class="heading"><span id="header-modify-user"></span> <span class="modal-close">&times;</span></span>
<p class="content">{{ .strings.modifySettingsDescription }}</p> <p class="content">{{ .strings.modifySettingsDescription }}</p>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<div class="flex flex-row gap-2"> <div id="modify-user-profile-source"></div>
<label class="grow">
<input type="radio" name="modify-user-source" class="unfocused" id="radio-use-profile" checked>
<span class="button ~neutral @high supra full-width center">{{ .strings.profile }}</span>
</label>
<label class="grow">
<input type="radio" name="modify-user-source" class="unfocused" id="radio-use-user">
<span class="button ~neutral @low supra full-width center">{{ .strings.user }}</span>
</label>
</div>
<div class="select ~neutral @low"> <div class="select ~neutral @low">
<select id="modify-user-profiles"></select> <select id="modify-user-profiles"></select>
</div> </div>
@@ -134,16 +125,7 @@
<form class="card relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3 flex flex-col gap-4" id="form-enable-referrals-user" href=""> <form class="card relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3 flex flex-col gap-4" id="form-enable-referrals-user" href="">
<span class="heading"><span id="header-enable-referrals-user"></span> <span class="modal-close">&times;</span></span> <span class="heading"><span id="header-enable-referrals-user"></span> <span class="modal-close">&times;</span></span>
<p class="content">{{ .strings.enableReferralsDescription }}</p> <p class="content">{{ .strings.enableReferralsDescription }}</p>
<div class="flex flex-row gap-2"> <div id="enable-referrals-user-source"></div>
<label class="grow">
<input type="radio" name="enable-referrals-user-source" class="unfocused" id="radio-referrals-use-profile" checked>
<span class="button ~neutral @high supra full-width center">{{ .strings.profile }}</span>
</label>
<label class="grow">
<input type="radio" name="enable-referrals-user-source" class="unfocused" id="radio-referrals-use-invite">
<span class="button ~neutral @low supra full-width center">{{ .strings.invite }}</span>
</label>
</div>
<div class="select ~neutral @low"> <div class="select ~neutral @low">
<select id="enable-referrals-user-profiles"></select> <select id="enable-referrals-user-profiles"></select>
</div> </div>
@@ -804,30 +786,7 @@
</div> </div>
<div class="card @low accounts-header overflow-x-scroll transition-opacity transition-display" id="accounts-table"> <div class="card @low accounts-header overflow-x-scroll transition-opacity transition-display" id="accounts-table">
<table class="table text-base leading-5"> <table class="table text-base leading-5">
<thead> {{ template "accounts-table-header.txt" . }}
<tr>
<th><input type="checkbox" value="" id="accounts-select-all"></th>
<th class="table-inline my-2 grid gap-4 place-items-stretch accounts-header-username">{{ .strings.username }}</th>
{{ if .jellyfinLogin }}
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-access-jfa">{{ .strings.accessJFA }}</th>
{{ end }}
<th class="grid gap-4 place-items-stretch accounts-header-email">{{ .strings.emailAddress }}</th>
{{ if .telegramEnabled }}
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-telegram">Telegram</th>
{{ end }}
{{ if .matrixEnabled }}
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-matrix">Matrix</th>
{{ end }}
{{ if .discordEnabled }}
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-discord">Discord</th>
{{ end }}
{{ if .referralsEnabled }}
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-referrals">{{ .strings.referrals }}</th>
{{ end }}
<th class="grid gap-4 place-items-stretch accounts-header-expiry">{{ .strings.expiry }}</th>
<th class="grid gap-4 place-items-stretch accounts-header-last-active">{{ .strings.lastActiveTime }}</th>
</tr>
</thead>
<tbody id="accounts-list"></tbody> <tbody id="accounts-list"></tbody>
</table> </table>
<div id="accounts-loader"></div> <div id="accounts-loader"></div>

View File

@@ -7,6 +7,8 @@
"invite": "Invite", "invite": "Invite",
"accounts": "Accounts", "accounts": "Accounts",
"activity": "Activity", "activity": "Activity",
"activityFromJF": "Activity (from Jellyfin)",
"activityFromJfa": "Activity (from jfa-go)",
"settings": "Settings", "settings": "Settings",
"inviteMonths": "Months", "inviteMonths": "Months",
"inviteDays": "Days", "inviteDays": "Days",

View File

@@ -159,6 +159,7 @@ window.notifications = new notificationBox(document.getElementById("notification
// Determine if url references an invite or account // Determine if url references an invite or account
let isInviteURL = window.invites.isInviteURL(); let isInviteURL = window.invites.isInviteURL();
let isAccountURL = accounts.isAccountURL(); let isAccountURL = accounts.isAccountURL();
let isActivityURL = activity.isActivityURL();
// load tabs // load tabs
const tabs: { id: string; url: string; reloader: () => void; unloader?: () => void }[] = [ const tabs: { id: string; url: string; reloader: () => void; unloader?: () => void }[] = [
@@ -183,6 +184,8 @@ const tabs: { id: string; url: string; reloader: () => void; unloader?: () => vo
accounts.loadAccountURL(); accounts.loadAccountURL();
// Don't keep loading the same item on every tab refresh // Don't keep loading the same item on every tab refresh
isAccountURL = false; isAccountURL = false;
// Since accounts and activity accept ?user=x, wipe the other one.
isActivityURL = false;
} }
accounts.bindPageEvents(); accounts.bindPageEvents();
}), }),
@@ -192,7 +195,15 @@ const tabs: { id: string; url: string; reloader: () => void; unloader?: () => vo
id: "activity", id: "activity",
url: "activity", url: "activity",
reloader: () => { reloader: () => {
activity.reload(); activity.reload(() => {
if (isActivityURL) {
activity.loadActivityURL();
// Don't keep loading the same item on every tab refresh
isActivityURL = false;
// Since accounts and activity accept ?user=x, wipe the other one.
isAccountURL = false;
}
});
activity.bindPageEvents(); activity.bindPageEvents();
}, },
unloader: activity.unbindPageEvents, unloader: activity.unbindPageEvents,

View File

@@ -14,7 +14,7 @@ import { Marked } from "@ts-stack/markdown";
import { stripMarkdown } from "../modules/stripmd"; import { stripMarkdown } from "../modules/stripmd";
import { DiscordUser, newDiscordSearch } from "../modules/discord"; import { DiscordUser, newDiscordSearch } from "../modules/discord";
import { SearchConfiguration, QueryType, SearchableItem, SearchableItemDataAttribute } from "../modules/search"; import { SearchConfiguration, QueryType, SearchableItem, SearchableItemDataAttribute } from "../modules/search";
import { HiddenInputField } from "./ui"; import { HiddenInputField, RadioBasedTabSelector } from "./ui";
import { PaginatedList } from "./list"; import { PaginatedList } from "./list";
import { TableRow } from "./row"; import { TableRow } from "./row";
@@ -211,6 +211,8 @@ class User extends TableRow implements UserDTO, SearchableItem {
private _referralsEnabled: boolean; private _referralsEnabled: boolean;
private _referralsEnabledCheck: HTMLElement; private _referralsEnabledCheck: HTMLElement;
notInList: boolean = false;
focus = () => this._row.scrollIntoView({ behavior: "smooth", block: "center" }); focus = () => this._row.scrollIntoView({ behavior: "smooth", block: "center" });
lastNotifyMethod = (): string => { lastNotifyMethod = (): string => {
@@ -244,7 +246,7 @@ class User extends TableRow implements UserDTO, SearchableItem {
setSelected(state: boolean, dispatchEvent: boolean) { setSelected(state: boolean, dispatchEvent: boolean) {
this._selected = state; this._selected = state;
this._check.checked = state; this._check.checked = state;
if (dispatchEvent) if (dispatchEvent && !(this.notInList))
state ? document.dispatchEvent(this._checkEvent()) : document.dispatchEvent(this._uncheckEvent()); state ? document.dispatchEvent(this._checkEvent()) : document.dispatchEvent(this._uncheckEvent());
} }
@@ -931,7 +933,7 @@ class User extends TableRow implements UserDTO, SearchableItem {
}; };
remove = () => { remove = () => {
if (this.selected) { if (this.selected && !(this.notInList)) {
document.dispatchEvent(this._uncheckEvent()); document.dispatchEvent(this._uncheckEvent());
} }
super.remove(); super.remove();
@@ -984,11 +986,13 @@ export class accountsList extends PaginatedList {
private _enableExpiryNotify = document.getElementById("expiry-extend-enable") as HTMLInputElement; private _enableExpiryNotify = document.getElementById("expiry-extend-enable") as HTMLInputElement;
private _enableExpiryReason = document.getElementById("textarea-extend-enable") as HTMLTextAreaElement; private _enableExpiryReason = document.getElementById("textarea-extend-enable") as HTMLTextAreaElement;
private _modifySettings = document.getElementById("accounts-modify-user") as HTMLSpanElement; private _modifySettings = document.getElementById("accounts-modify-user") as HTMLSpanElement;
private _modifySettingsProfile = document.getElementById("radio-use-profile") as HTMLInputElement; /*private _modifySettingsProfile = document.getElementById("radio-use-profile") as HTMLInputElement;
private _modifySettingsUser = document.getElementById("radio-use-user") as HTMLInputElement; private _modifySettingsUser = document.getElementById("radio-use-user") as HTMLInputElement;*/
private _modifySettingsProfileSource: RadioBasedTabSelector;
private _enableReferrals = document.getElementById("accounts-enable-referrals") as HTMLSpanElement; private _enableReferrals = document.getElementById("accounts-enable-referrals") as HTMLSpanElement;
private _enableReferralsProfile = document.getElementById("radio-referrals-use-profile") as HTMLInputElement; /*private _enableReferralsProfile = document.getElementById("radio-referrals-use-profile") as HTMLInputElement;
private _enableReferralsInvite = document.getElementById("radio-referrals-use-invite") as HTMLInputElement; private _enableReferralsInvite = document.getElementById("radio-referrals-use-invite") as HTMLInputElement;*/
private _enableReferralsSource: RadioBasedTabSelector;
private _sendPWR = document.getElementById("accounts-send-pwr") as HTMLSpanElement; private _sendPWR = document.getElementById("accounts-send-pwr") as HTMLSpanElement;
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;
@@ -1052,8 +1056,7 @@ export class accountsList extends PaginatedList {
this.unbindPageEvents(); this.unbindPageEvents();
console.debug("Loading details for ", username, jfId); console.debug("Loading details for ", username, jfId);
this._details.load( this._details.load(
username, this.users.get(jfId),
jfId,
() => { () => {
this.unbindPageEvents(); this.unbindPageEvents();
this._inDetails = true; this._inDetails = true;
@@ -1164,9 +1167,6 @@ export class accountsList extends PaginatedList {
this.initSearch(searchConfig); this.initSearch(searchConfig);
// FIXME: Remove!
(window as any).accs = this;
this._selectAll.checked = false; this._selectAll.checked = false;
this._selectAllState = SelectAllState.None; this._selectAllState = SelectAllState.None;
this._selectAll.onchange = () => this.cycleSelectAll(); this._selectAll.onchange = () => this.cycleSelectAll();
@@ -1195,66 +1195,47 @@ export class accountsList extends PaginatedList {
this._modifySettings.onclick = this.modifyUsers; this._modifySettings.onclick = this.modifyUsers;
this._modifySettings.classList.add("unfocused"); this._modifySettings.classList.add("unfocused");
const checkSource = () => { this._modifySettingsProfileSource = new RadioBasedTabSelector(
const profileSpan = this._modifySettingsProfile.nextElementSibling as HTMLSpanElement; document.getElementById("modify-user-profile-source"),
const userSpan = this._modifySettingsUser.nextElementSibling as HTMLSpanElement; "modify-user-profile-source",
if (this._modifySettingsProfile.checked) { {
this._userSelect.parentElement.classList.add("unfocused"); name: window.lang.strings("profile"),
this._profileSelect.parentElement.classList.remove("unfocused"); id: "profile",
profileSpan.classList.add("@high"); content: this._profileSelect.parentElement,
profileSpan.classList.remove("@low"); onShow: () => {
userSpan.classList.remove("@high"); this._applyOmbi?.parentElement.classList.remove("unfocused");
userSpan.classList.add("@low"); this._applyJellyseerr?.parentElement.classList.remove("unfocused");
this._applyOmbi?.parentElement.classList.remove("unfocused"); },
this._applyJellyseerr?.parentElement.classList.remove("unfocused"); },
} else { {
this._userSelect.parentElement.classList.remove("unfocused"); name: window.lang.strings("user"),
this._profileSelect.parentElement.classList.add("unfocused"); id: "user",
userSpan.classList.add("@high"); content: this._userSelect.parentElement,
userSpan.classList.remove("@low"); onShow: () => {
profileSpan.classList.remove("@high"); this._applyOmbi?.parentElement.classList.add("unfocused");
profileSpan.classList.add("@low"); this._applyJellyseerr?.parentElement.classList.add("unfocused");
this._applyOmbi?.parentElement.classList.add("unfocused"); },
this._applyJellyseerr?.parentElement.classList.add("unfocused"); },
} )
};
this._modifySettingsProfile.onchange = checkSource;
this._modifySettingsUser.onchange = checkSource;
if (window.referralsEnabled) { if (window.referralsEnabled) {
const profileSpan = this._enableReferralsProfile.nextElementSibling as HTMLSpanElement; this._enableReferralsSource = new RadioBasedTabSelector(
const inviteSpan = this._enableReferralsInvite.nextElementSibling as HTMLSpanElement; document.getElementById("enable-referrals-user-source"),
const checkReferralSource = () => { "enable-referrals-user-source",
console.debug("States:", this._enableReferralsProfile.checked, this._enableReferralsInvite.checked); {
if (this._enableReferralsProfile.checked) { name: window.lang.strings("profile"),
this._referralsInviteSelect.parentElement.classList.add("unfocused"); id: "profile",
this._referralsProfileSelect.parentElement.classList.remove("unfocused"); content: this._referralsProfileSelect.parentElement,
profileSpan.classList.add("@high"); },
profileSpan.classList.remove("@low"); {
inviteSpan.classList.remove("@high"); name: window.lang.strings("invite"),
inviteSpan.classList.add("@low"); id: "invite",
} else { content: this._referralsInviteSelect.parentElement,
this._referralsInviteSelect.parentElement.classList.remove("unfocused"); },
this._referralsProfileSelect.parentElement.classList.add("unfocused"); );
inviteSpan.classList.add("@high");
inviteSpan.classList.remove("@low");
profileSpan.classList.remove("@high");
profileSpan.classList.add("@low");
}
};
profileSpan.onclick = () => {
this._enableReferralsProfile.checked = true;
this._enableReferralsInvite.checked = false;
checkReferralSource();
};
inviteSpan.onclick = () => {
this._enableReferralsInvite.checked = true;
this._enableReferralsProfile.checked = false;
checkReferralSource();
};
this._enableReferrals.onclick = () => { this._enableReferrals.onclick = () => {
this.enableReferrals(); this.enableReferrals();
profileSpan.onclick(null); this._enableReferralsSource.selected = 0;
}; };
} }
@@ -2125,8 +2106,7 @@ export class accountsList extends PaginatedList {
const form = document.getElementById("form-modify-user") as HTMLFormElement; const form = document.getElementById("form-modify-user") as HTMLFormElement;
const button = form.querySelector("span.submit") as HTMLSpanElement; const button = form.querySelector("span.submit") as HTMLSpanElement;
this._modifySettingsProfile.checked = true; this._modifySettingsProfileSource.selected = 0;
this._modifySettingsUser.checked = false;
form.onsubmit = (event: Event) => { form.onsubmit = (event: Event) => {
event.preventDefault(); event.preventDefault();
toggleLoader(button); toggleLoader(button);
@@ -2141,10 +2121,10 @@ export class accountsList extends PaginatedList {
if (window.jellyseerrEnabled) { if (window.jellyseerrEnabled) {
send["jellyseerr"] = this._applyJellyseerr.checked; send["jellyseerr"] = this._applyJellyseerr.checked;
} }
if (this._modifySettingsProfile.checked && !this._modifySettingsUser.checked) { if (this._modifySettingsProfileSource.selected == "profile") {
send["from"] = "profile"; send["from"] = "profile";
send["profile"] = this._profileSelect.value; send["profile"] = this._profileSelect.value;
} else if (this._modifySettingsUser.checked && !this._modifySettingsProfile.checked) { } else if (this._modifySettingsProfileSource.selected == "user") {
send["from"] = "user"; send["from"] = "user";
send["id"] = this._userSelect.value; send["id"] = this._userSelect.value;
} }
@@ -2216,12 +2196,11 @@ export class accountsList extends PaginatedList {
} }
innerHTML += `<option value="${inv.code}">${name}</option>`; innerHTML += `<option value="${inv.code}">${name}</option>`;
} }
this._enableReferralsInvite.checked = true; this._enableReferralsSource.selected = "invite";
} else { } else {
this._enableReferralsInvite.checked = false; this._enableReferralsSource.selected = "profile";
innerHTML += `<option>${window.lang.strings("inviteNoInvites")}</option>`; innerHTML += `<option>${window.lang.strings("inviteNoInvites")}</option>`;
} }
this._enableReferralsProfile.checked = !this._enableReferralsInvite.checked;
this._referralsInviteSelect.innerHTML = innerHTML; this._referralsInviteSelect.innerHTML = innerHTML;
// 2. Profiles // 2. Profiles
@@ -2243,10 +2222,10 @@ export class accountsList extends PaginatedList {
users: list, users: list,
}; };
// console.log("profile:", this._enableReferralsProfile.checked, this._enableReferralsInvite.checked); // console.log("profile:", this._enableReferralsProfile.checked, this._enableReferralsInvite.checked);
if (this._enableReferralsProfile.checked && !this._enableReferralsInvite.checked) { if (this._enableReferralsSource.selected == "profile") {
send["from"] = "profile"; send["from"] = "profile";
send["profile"] = this._referralsProfileSelect.value; send["profile"] = this._referralsProfileSelect.value;
} else if (this._enableReferralsInvite.checked && !this._enableReferralsProfile.checked) { } else if (this._enableReferralsSource.selected == "invite") {
send["from"] = "invite"; send["from"] = "invite";
send["id"] = this._referralsInviteSelect.value; send["id"] = this._referralsInviteSelect.value;
} }
@@ -2278,8 +2257,7 @@ export class accountsList extends PaginatedList {
}, },
); );
}; };
this._enableReferralsProfile.checked = true; this._enableReferralsSource.selected = 0;
this._enableReferralsInvite.checked = false;
this._referralsExpiry.checked = false; this._referralsExpiry.checked = false;
window.modals.enableReferralsUser.show(); window.modals.enableReferralsUser.show();
}; };
@@ -2856,7 +2834,9 @@ class UserInfo extends PaginatedList {
private _hidden: boolean = true; private _hidden: boolean = true;
private _table: HTMLElement; private _table: HTMLElement;
private _card: HTMLElement; private _card: HTMLElement;
private _rowArea: HTMLElement;
private _noResults: HTMLElement; private _noResults: HTMLElement;
private _link: HTMLAnchorElement;
get entries(): Map<string, ActivityLogEntry> { get entries(): Map<string, ActivityLogEntry> {
return this._search.items as Map<string, ActivityLogEntry>; return this._search.items as Map<string, ActivityLogEntry>;
} }
@@ -2867,20 +2847,14 @@ class UserInfo extends PaginatedList {
card.classList.add("unfocused"); card.classList.add("unfocused");
card.innerHTML = ` card.innerHTML = `
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<div class="flex flex-row gap-2 justify-start"> <table class="table text-base leading-5">
</div> <thead class="user-info-table-header"></thead>
<div class="flex flex-row gap-2"> <tbody class="user-info-row"></tbody>
</div> </table>
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-2">
<div class="flex flex-row gap-2"> <div class="jf-activity-source flex flex-row justify-between gap-2">
<label class="grow"> <h3 class="heading text-lg">${window.lang.strings("activityFromJF")}</h3>
<input type="radio" name="jf-activity-source" class="jf-activity-source-jellyfin unfocused" checked> <a role="link" tabindex="0" class="jf-activity-jfa-link hover:underline cursor-pointer button ~info @high flex flex-row gap-1 items-baseline">${window.lang.strings("activityFromJfa")}<i class="icon ri-external-link-line text-current"></i></a>
<span class="button ~neutral @high supra w-full text-center">${window.lang.strings("jellyfin")}</span>
</label>
<label class="grow">
<input type="radio" name="jf-activity-source" class="jf-activity-source-jfa-go unfocused">
<span class="button ~neutral @low supra w-full text-center">jfa-go</span>
</label>
</div> </div>
<!-- <h2 class="heading text-2xl">${window.lang.strings("activity")}</h2> --> <!-- <h2 class="heading text-2xl">${window.lang.strings("activity")}</h2> -->
<div class="card @low overflow-x-scroll jf-activity-table"> <div class="card @low overflow-x-scroll jf-activity-table">
@@ -2962,11 +2936,18 @@ class UserInfo extends PaginatedList {
}); });
this._hidden = true; this._hidden = true;
this._card = card; this._card = card;
this._rowArea = this._card.getElementsByClassName("user-info-row")[0] as HTMLElement;
const realHead = document.getElementById("accounts-table-header") as HTMLElement;
const cloneHead = realHead.cloneNode(true) as HTMLElement;
// Remove "select all" check from header
cloneHead.querySelector("input[type=checkbox]").remove();
const head = this._card.getElementsByClassName("user-info-table-header")[0] as HTMLElement;
head.replaceWith(cloneHead);
this._table = this._card.getElementsByClassName("jf-activity-table")[0] as HTMLElement; this._table = this._card.getElementsByClassName("jf-activity-table")[0] as HTMLElement;
this._container = this._table.getElementsByClassName("jf-activity-table-content")[0] as HTMLElement; this._container = this._table.getElementsByClassName("jf-activity-table-content")[0] as HTMLElement;
this._back = document.getElementById("user-details-back") as HTMLButtonElement; this._back = document.getElementById("user-details-back") as HTMLButtonElement;
this._noResults = this._card.getElementsByClassName("jf-activity-no-activity")[0] as HTMLElement; this._noResults = this._card.getElementsByClassName("jf-activity-no-activity")[0] as HTMLElement;
this._link = this._card.getElementsByClassName("jf-activity-jfa-link")[0] as HTMLAnchorElement;
let searchConfig: SearchConfiguration = { let searchConfig: SearchConfiguration = {
queries: {}, queries: {},
setVisibility: null, setVisibility: null,
@@ -2995,9 +2976,16 @@ class UserInfo extends PaginatedList {
this._reload(callback); this._reload(callback);
}; };
load = (username: string, jfId: string, onLoad?: () => void, onBack?: () => void) => { load = (user: User, onLoad?: () => void, onBack?: () => void) => {
this.username = username; this.username = user.name;
this.jfId = jfId; this.jfId = user.id;
const clone = new User(user);
clone.notInList = true;
clone.setSelected(true, false)
this._rowArea.replaceChildren(clone.asElement());
this._link.setAttribute("data-id", this.jfId)
this._link.href = `${window.pages.Base}${window.pages.Admin}/activity?user=${this.username}`
if (onBack) { if (onBack) {
this._back.classList.remove("unfocused"); this._back.classList.remove("unfocused");
this._back.onclick = () => onBack(); this._back.onclick = () => onBack();

View File

@@ -687,4 +687,18 @@ export class activityList extends PaginatedList {
this._keepSearchingDescription.classList.add("unfocused"); this._keepSearchingDescription.classList.add("unfocused");
} }
};*/ };*/
isActivityURL = () => {
const urlParams = new URLSearchParams(window.location.search);
const username = urlParams.get("user");
return Boolean(username);
};
loadActivityURL = () => {
const urlParams = new URLSearchParams(window.location.search);
const username = urlParams.get("user");
this._c.searchBox.value = `user:"${username}"`;
this._search.onSearchBoxChange();
this._search.onServerSearch();
};
} }