fixed pagination on the sessions tab (#20865)

* fixed pagination on the sessions tab

fixes: #20835

* changed to use steam
This commit is contained in:
Erik Jan de Wit 2023-06-14 10:25:27 +02:00 committed by GitHub
parent 30a0c31153
commit c0ac409974
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 19 deletions

View file

@ -146,6 +146,7 @@ export default function SessionsSection() {
key={key} key={key}
loader={loader} loader={loader}
isSearching={filterType !== "ALL"} isSearching={filterType !== "ALL"}
isPaginated
filter={ filter={
<SessionFilter <SessionFilter
filterType={filterType} filterType={filterType}

View file

@ -42,6 +42,7 @@ export type SessionsTableProps = {
logoutUser?: string; logoutUser?: string;
filter?: ReactNode; filter?: ReactNode;
isSearching?: boolean; isSearching?: boolean;
isPaginated?: boolean;
}; };
const UsernameCell = (row: UserSessionRepresentation) => { const UsernameCell = (row: UserSessionRepresentation) => {
@ -75,6 +76,7 @@ export default function SessionsTable({
logoutUser, logoutUser,
filter, filter,
isSearching, isSearching,
isPaginated,
}: SessionsTableProps) { }: SessionsTableProps) {
const { realm } = useRealm(); const { realm } = useRealm();
const { whoAmI } = useWhoAmI(); const { whoAmI } = useWhoAmI();
@ -153,6 +155,7 @@ export default function SessionsTable({
loader={loader} loader={loader}
ariaLabelKey="sessions:title" ariaLabelKey="sessions:title"
searchPlaceholderKey="sessions:searchForSession" searchPlaceholderKey="sessions:searchForSession"
isPaginated={isPaginated}
isSearching={isSearching} isSearching={isSearching}
searchTypeComponent={filter} searchTypeComponent={filter}
toolbarItem={ toolbarItem={

View file

@ -21,6 +21,7 @@ import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
import jakarta.ws.rs.Produces; import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.QueryParam;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -62,41 +63,36 @@ public class SessionsResource {
@DefaultValue("0") int first, @QueryParam("max") @DefaultValue("10") int max) { @DefaultValue("0") int first, @QueryParam("max") @DefaultValue("10") int max) {
auth.realm().requireViewRealm(); auth.realm().requireViewRealm();
Stream<SessionId> clientIds = Stream.<SessionId>builder().build(); Stream<SessionId> sessionIdStream = Stream.<SessionId>builder().build();
long clientSessionsCount = 0L;
if (type == ALL || type == REGULAR) { if (type == ALL || type == REGULAR) {
final Map<String, Long> clientSessionStats = session.sessions().getActiveClientSessionStats(realm, false); final Map<String, Long> clientSessionStats = session.sessions().getActiveClientSessionStats(realm, false);
clientSessionsCount = clientSessionStats.values().stream().reduce(0L, Long::sum); sessionIdStream = Stream.concat(sessionIdStream, clientSessionStats
clientIds = Stream.concat(clientIds, clientSessionStats
.keySet().stream().map(i -> new SessionId(i, REGULAR))); .keySet().stream().map(i -> new SessionId(i, REGULAR)));
} }
if (type == ALL || type == OFFLINE) { if (type == ALL || type == OFFLINE) {
clientIds = Stream.concat(clientIds, session.sessions().getActiveClientSessionStats(realm, true) sessionIdStream = Stream.concat(sessionIdStream, session.sessions().getActiveClientSessionStats(realm, true)
.keySet().stream().map(i -> new SessionId(i, OFFLINE))); .keySet().stream().map(i -> new SessionId(i, OFFLINE)));
} }
Stream<SessionRepresentation> result = sessionIdStream.flatMap((sessionId) -> {
final List<SessionId> sessionIds = clientIds.skip(first).limit(max).collect(Collectors.toList());
Stream<SessionRepresentation> result = Stream.<SessionRepresentation>builder().build();
for (SessionId sessionId : sessionIds) {
ClientModel clientModel = realm.getClientById(sessionId.getClientId()); ClientModel clientModel = realm.getClientById(sessionId.getClientId());
switch (sessionId.getType()) { switch (sessionId.getType()) {
case REGULAR: case REGULAR:
result = Stream.concat(result, session.sessions().getUserSessionsStream(realm, clientModel) return session.sessions().getUserSessionsStream(realm, clientModel)
.map(s -> toUserSessionRepresentation(s, sessionId.getClientId(), REGULAR))).distinct(); .map(s -> toUserSessionRepresentation(s, sessionId.getClientId(), REGULAR));
break;
case OFFLINE: case OFFLINE:
result = Stream.concat(result, session.sessions() return session.sessions()
.getOfflineUserSessionsStream(realm, clientModel, Math.max((int) (first - clientSessionsCount), 0), max) .getOfflineUserSessionsStream(realm, clientModel, null, null)
.map(s -> toUserSessionRepresentation(s, sessionId.getClientId(), OFFLINE))).distinct(); .map(s -> toUserSessionRepresentation(s, sessionId.getClientId(), OFFLINE));
break;
}
} }
return Stream.<SessionRepresentation>builder().build();
}).distinct();
if (!search.equals("")) { if (!search.equals("")) {
return result.filter(s -> s.getUsername().contains(search) || s.getIpAddress().contains(search)); result = result.filter(s -> s.getUsername().contains(search) || s.getIpAddress().contains(search)
|| s.getClients().values().stream().anyMatch(c -> c.contains(search)));
} }
return result; return result.skip(first).limit(max);
} }
private SessionRepresentation toUserSessionRepresentation(final UserSessionModel userSession, String clientId, SessionType type) { private SessionRepresentation toUserSessionRepresentation(final UserSessionModel userSession, String clientId, SessionType type) {