Add punishment details and history retrieval functionality
This commit introduces a new `DetailsComponent` for displaying detailed punishment data and establishes a route to view punishment history by ID and type. It also updates the API to support fetching individual punishment records and refines database mappings for improved data handling.
This commit is contained in:
parent
a1912b96d8
commit
3babde5513
|
|
@ -3,11 +3,11 @@ package com.alttd.altitudeweb.controllers.history;
|
|||
import com.alttd.altitudeweb.api.HistoryApi;
|
||||
import com.alttd.altitudeweb.controllers.limits.RateLimit;
|
||||
import com.alttd.altitudeweb.model.HistoryCountDto;
|
||||
import com.alttd.altitudeweb.model.PunishmentHistoryListDto;
|
||||
import com.alttd.altitudeweb.setup.Connection;
|
||||
import com.alttd.altitudeweb.database.Databases;
|
||||
import com.alttd.altitudeweb.database.litebans.*;
|
||||
import com.alttd.altitudeweb.model.PunishmentHistoryDto;
|
||||
import com.alttd.altitudeweb.model.PunishmentHistoryInnerDto;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
|
@ -23,15 +23,15 @@ import java.util.concurrent.TimeUnit;
|
|||
public class HistoryApiController implements HistoryApi {
|
||||
|
||||
@Override
|
||||
public ResponseEntity<PunishmentHistoryDto> getHistoryForAll(String userType, String type, Integer page) {
|
||||
public ResponseEntity<PunishmentHistoryListDto> getHistoryForAll(String userType, String type, Integer page) {
|
||||
return getHistoryForUsers(userType, type, "", page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<PunishmentHistoryDto> getHistoryForUsers(String userType, String type, String user, Integer page) {
|
||||
public ResponseEntity<PunishmentHistoryListDto> getHistoryForUsers(String userType, String type, String user, Integer page) {
|
||||
UserType userTypeEnum = UserType.getUserType(userType);
|
||||
HistoryType historyTypeEnum = HistoryType.getHistoryType(type);
|
||||
PunishmentHistoryDto punishmentHistory = new PunishmentHistoryDto();
|
||||
PunishmentHistoryListDto punishmentHistoryList = new PunishmentHistoryListDto();
|
||||
CompletableFuture<List<HistoryRecord>> historyRecords = new CompletableFuture<>();
|
||||
|
||||
Connection.getConnection(Databases.LITE_BANS)
|
||||
|
|
@ -46,14 +46,14 @@ public class HistoryApiController implements HistoryApi {
|
|||
historyRecords.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return mapPunishmentHistory(punishmentHistory, historyRecords);
|
||||
return mapPunishmentHistory(punishmentHistoryList, historyRecords);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<PunishmentHistoryDto> getHistoryForUuid(String userType, String type, String uuid, Integer page) {
|
||||
public ResponseEntity<PunishmentHistoryListDto> getHistoryForUuid(String userType, String type, String uuid, Integer page) {
|
||||
UserType userTypeEnum = UserType.getUserType(userType);
|
||||
HistoryType historyTypeEnum = HistoryType.getHistoryType(type);
|
||||
PunishmentHistoryDto punishmentHistory = new PunishmentHistoryDto();
|
||||
PunishmentHistoryListDto punishmentHistoryList = new PunishmentHistoryListDto();
|
||||
CompletableFuture<List<HistoryRecord>> historyRecords = new CompletableFuture<>();
|
||||
|
||||
Connection.getConnection(Databases.LITE_BANS)
|
||||
|
|
@ -68,7 +68,7 @@ public class HistoryApiController implements HistoryApi {
|
|||
historyRecords.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return mapPunishmentHistory(punishmentHistory, historyRecords);
|
||||
return mapPunishmentHistory(punishmentHistoryList, historyRecords);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -153,6 +153,26 @@ public class HistoryApiController implements HistoryApi {
|
|||
return ResponseEntity.ok().body(searchResultCountCompletableFuture.join());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<PunishmentHistoryDto> getHistoryById(String type, Integer id) {
|
||||
HistoryType historyTypeEnum = HistoryType.getHistoryType(type);
|
||||
CompletableFuture<HistoryRecord> historyRecordCompletableFuture = new CompletableFuture<>();
|
||||
|
||||
Connection.getConnection(Databases.LITE_BANS)
|
||||
.runQuery(sqlSession -> {
|
||||
log.debug("Loading history by id");
|
||||
try {
|
||||
HistoryRecord punishment = sqlSession.getMapper(IdHistoryMapper.class)
|
||||
.getRecentHistory(historyTypeEnum, id);
|
||||
historyRecordCompletableFuture.complete(punishment);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to load history count", e);
|
||||
historyRecordCompletableFuture.completeExceptionally(e);
|
||||
}
|
||||
});
|
||||
return ResponseEntity.ok().body(mapPunishmentHistory(historyRecordCompletableFuture.join()));
|
||||
}
|
||||
|
||||
private ResponseEntity<HistoryCountDto> mapHistoryCount(HistoryCount historyCount) {
|
||||
HistoryCountDto historyCountDto = new HistoryCountDto();
|
||||
historyCountDto.setBans(historyCount.getBans());
|
||||
|
|
@ -162,28 +182,33 @@ public class HistoryApiController implements HistoryApi {
|
|||
return ResponseEntity.ok().body(historyCountDto);
|
||||
}
|
||||
|
||||
private ResponseEntity<PunishmentHistoryDto> mapPunishmentHistory(PunishmentHistoryDto punishmentHistory, CompletableFuture<List<HistoryRecord>> historyRecords) {
|
||||
private ResponseEntity<PunishmentHistoryListDto> mapPunishmentHistory(PunishmentHistoryListDto punishmentHistoryList, CompletableFuture<List<HistoryRecord>> historyRecords) {
|
||||
historyRecords.join().forEach(historyRecord -> {
|
||||
PunishmentHistoryInnerDto.TypeEnum type = switch (historyRecord.getType().toLowerCase()) {
|
||||
case "ban" -> PunishmentHistoryInnerDto.TypeEnum.BAN;
|
||||
case "mute" -> PunishmentHistoryInnerDto.TypeEnum.MUTE;
|
||||
case "warn" -> PunishmentHistoryInnerDto.TypeEnum.WARN;
|
||||
case "kick" -> PunishmentHistoryInnerDto.TypeEnum.KICK;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + historyRecord.getType());
|
||||
};
|
||||
PunishmentHistoryInnerDto innerDto = new PunishmentHistoryInnerDto()
|
||||
.uuid(historyRecord.getUuid())
|
||||
.username(historyRecord.getPunishedName())
|
||||
.reason(historyRecord.getReason())
|
||||
.punishedByUuid(historyRecord.getBannedByUuid())
|
||||
.punishedBy(historyRecord.getBannedByName())
|
||||
.removedBy(historyRecord.getRemovedByName())
|
||||
.punishmentTime(historyRecord.getTime())
|
||||
.expiryTime(historyRecord.getUntil())
|
||||
.removedReason(historyRecord.getRemovedByReason())
|
||||
.type(type);
|
||||
punishmentHistory.add(innerDto);
|
||||
PunishmentHistoryDto innerDto = mapPunishmentHistory(historyRecord);
|
||||
punishmentHistoryList.add(innerDto);
|
||||
});
|
||||
return ResponseEntity.ok().body(punishmentHistory);
|
||||
return ResponseEntity.ok().body(punishmentHistoryList);
|
||||
}
|
||||
|
||||
private static PunishmentHistoryDto mapPunishmentHistory(HistoryRecord historyRecord) {
|
||||
PunishmentHistoryDto.TypeEnum type = switch (historyRecord.getType().toLowerCase()) {
|
||||
case "ban" -> PunishmentHistoryDto.TypeEnum.BAN;
|
||||
case "mute" -> PunishmentHistoryDto.TypeEnum.MUTE;
|
||||
case "warn" -> PunishmentHistoryDto.TypeEnum.WARN;
|
||||
case "kick" -> PunishmentHistoryDto.TypeEnum.KICK;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + historyRecord.getType());
|
||||
};
|
||||
return new PunishmentHistoryDto()
|
||||
.uuid(historyRecord.getUuid())
|
||||
.username(historyRecord.getPunishedName())
|
||||
.reason(historyRecord.getReason())
|
||||
.punishedByUuid(historyRecord.getBannedByUuid())
|
||||
.punishedBy(historyRecord.getBannedByName())
|
||||
.removedBy(historyRecord.getRemovedByName())
|
||||
.punishmentTime(historyRecord.getTime())
|
||||
.expiryTime(historyRecord.getUntil())
|
||||
.removedReason(historyRecord.getRemovedByReason())
|
||||
.type(type)
|
||||
.id(historyRecord.getId());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ dependencies {
|
|||
implementation("org.mybatis:mybatis:3.5.13")
|
||||
compileOnly("org.slf4j:slf4j-api:2.0.17")
|
||||
compileOnly("org.slf4j:slf4j-simple:2.0.17")
|
||||
compileOnly("org.jetbrains:annotations:26.0.2")
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import lombok.Data;
|
|||
@Data
|
||||
public class HistoryRecord {
|
||||
private String uuid;
|
||||
private int id;
|
||||
private String punishedName;
|
||||
private String reason;
|
||||
private String bannedByUuid;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
package com.alttd.altitudeweb.database.litebans;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Result;
|
||||
import org.apache.ibatis.annotations.Results;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
public interface IdHistoryMapper {
|
||||
@Results({
|
||||
@Result(property = "id", column = "id"),
|
||||
@Result(property = "uuid", column = "uuid"),
|
||||
@Result(property = "punishedName", column = "punished_name"),
|
||||
@Result(property = "reason", column = "reason"),
|
||||
@Result(property = "bannedByUuid", column = "banned_by_uuid"),
|
||||
@Result(property = "bannedByName", column = "banned_by_name"),
|
||||
@Result(property = "removedByName", column = "removed_by_name"),
|
||||
@Result(property = "time", column = "time"),
|
||||
@Result(property = "until", column = "until"),
|
||||
@Result(property = "removedByReason", column = "removed_by_reason")
|
||||
})
|
||||
@Select("""
|
||||
SELECT punishment.id,
|
||||
punishment.uuid,
|
||||
user_lookup.name AS punished_name,
|
||||
punishment.reason,
|
||||
punishment.banned_by_uuid,
|
||||
punishment.banned_by_name,
|
||||
punishment.removed_by_name,
|
||||
punishment.time,
|
||||
punishment.until,
|
||||
punishment.removed_by_reason
|
||||
FROM (SELECT *
|
||||
FROM ${table_name} AS punishment
|
||||
WHERE punishment.id = #{id})
|
||||
AS punishment
|
||||
INNER JOIN user_lookup
|
||||
ON user_lookup.uuid = punishment.uuid
|
||||
""")
|
||||
HistoryRecord getHistoryForId(@Param("table_name") String tableName,
|
||||
@Param("type") String type,
|
||||
@Param("id") int id);
|
||||
|
||||
default HistoryRecord getRecentHistory(HistoryType historyType, int id) {
|
||||
HistoryRecord historyRecord = switch (historyType) {
|
||||
case ALL -> throw new IllegalArgumentException("HistoryType.ALL is not supported");
|
||||
case BAN -> getHistoryForId("litebans_bans", "ban", id);
|
||||
case MUTE -> getHistoryForId("litebans_mutes", "mute", id);
|
||||
case KICK -> getHistoryForId("litebans_kicks", "kick", id);
|
||||
case WARN -> getHistoryForId("litebans_warnings", "warn", id);
|
||||
};
|
||||
historyRecord.setType(historyType.name().toLowerCase());
|
||||
return historyRecord;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import org.apache.ibatis.annotations.Param;
|
|||
import org.apache.ibatis.annotations.Result;
|
||||
import org.apache.ibatis.annotations.Results;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -24,6 +25,7 @@ public interface NameHistoryMapper {
|
|||
* order
|
||||
*/
|
||||
@Results({
|
||||
@Result(property = "id", column = "id"),
|
||||
@Result(property = "uuid", column = "uuid"),
|
||||
@Result(property = "punishedName", column = "punished_name"),
|
||||
@Result(property = "reason", column = "reason"),
|
||||
|
|
@ -36,7 +38,8 @@ public interface NameHistoryMapper {
|
|||
@Result(property = "type", column = "type")
|
||||
})
|
||||
@Select("""
|
||||
SELECT all_punishments.uuid,
|
||||
SELECT id,
|
||||
all_punishments.uuid,
|
||||
user_lookup.name AS punished_name,
|
||||
reason,
|
||||
banned_by_uuid,
|
||||
|
|
@ -62,7 +65,6 @@ public interface NameHistoryMapper {
|
|||
* Retrieves a list of all types of recent punishment history records sorted
|
||||
* in descending time order. This result does NOT contain kicks history
|
||||
*
|
||||
* @param nameColumn the column name in the database indicating the name to use for filtering
|
||||
* @param limit the maximum number of records to fetch
|
||||
* @param offset the starting offset position of the result set
|
||||
*
|
||||
|
|
@ -70,6 +72,7 @@ public interface NameHistoryMapper {
|
|||
* order
|
||||
*/
|
||||
@Results({
|
||||
@Result(property = "id", column = "id"),
|
||||
@Result(property = "uuid", column = "uuid"),
|
||||
@Result(property = "punishedName", column = "punished_name"),
|
||||
@Result(property = "reason", column = "reason"),
|
||||
|
|
@ -82,17 +85,19 @@ public interface NameHistoryMapper {
|
|||
@Result(property = "type", column = "type")
|
||||
})
|
||||
@Select("""
|
||||
SELECT punishments.uuid,
|
||||
SELECT punishment.id,
|
||||
punishment.uuid,
|
||||
user_lookup.name AS punished_name,
|
||||
punishments.reason,
|
||||
punishments.banned_by_uuid,
|
||||
punishments.banned_by_name,
|
||||
punishments.removed_by_name,
|
||||
punishments.time,
|
||||
punishments.until,
|
||||
punishments.removed_by_reason,
|
||||
punishments.type
|
||||
punishment.reason,
|
||||
punishment.banned_by_uuid,
|
||||
punishment.banned_by_name,
|
||||
punishment.removed_by_name,
|
||||
punishment.time,
|
||||
punishment.until,
|
||||
punishment.removed_by_reason,
|
||||
punishment.type
|
||||
FROM (SELECT uuid,
|
||||
id,
|
||||
reason,
|
||||
banned_by_uuid,
|
||||
banned_by_name,
|
||||
|
|
@ -103,9 +108,9 @@ public interface NameHistoryMapper {
|
|||
type
|
||||
FROM all_punishments
|
||||
ORDER BY time DESC
|
||||
LIMIT #{limit} OFFSET #{offset}) AS punishments
|
||||
LIMIT #{limit} OFFSET #{offset}) AS punishment
|
||||
INNER JOIN user_lookup
|
||||
ON user_lookup.uuid = punishments.uuid;
|
||||
ON user_lookup.uuid = punishment.uuid;
|
||||
""")
|
||||
List<HistoryRecord> getRecentAllHistory(@Param("limit") int limit,
|
||||
@Param("offset") int offset);
|
||||
|
|
@ -124,6 +129,7 @@ public interface NameHistoryMapper {
|
|||
* order
|
||||
*/
|
||||
@Results({
|
||||
@Result(property = "id", column = "id"),
|
||||
@Result(property = "uuid", column = "uuid"),
|
||||
@Result(property = "punishedName", column = "punished_name"),
|
||||
@Result(property = "reason", column = "reason"),
|
||||
|
|
@ -135,7 +141,8 @@ public interface NameHistoryMapper {
|
|||
@Result(property = "removedByReason", column = "removed_by_reason")
|
||||
})
|
||||
@Select("""
|
||||
SELECT punishment.uuid,
|
||||
SELECT punishment.id,
|
||||
punishment.uuid,
|
||||
user_lookup.name AS punished_name,
|
||||
punishment.reason,
|
||||
punishment.banned_by_uuid,
|
||||
|
|
@ -162,8 +169,6 @@ public interface NameHistoryMapper {
|
|||
* parameters. The records are sorted in descending order by time and limited to a specified range.
|
||||
*
|
||||
* @param tableName the name of the database table to query the history records from
|
||||
* @param partialName a partial or complete name of the user to filter the records, case-insensitive
|
||||
* @param nameColumn the column name in the database indicating the name to use for filtering
|
||||
* @param limit the maximum number of records to fetch
|
||||
* @param offset the starting offset position of the result set
|
||||
*
|
||||
|
|
@ -171,6 +176,7 @@ public interface NameHistoryMapper {
|
|||
* order
|
||||
*/
|
||||
@Results({
|
||||
@Result(property = "id", column = "id"),
|
||||
@Result(property = "uuid", column = "uuid"),
|
||||
@Result(property = "punishedName", column = "punished_name"),
|
||||
@Result(property = "reason", column = "reason"),
|
||||
|
|
@ -182,7 +188,8 @@ public interface NameHistoryMapper {
|
|||
@Result(property = "removedByReason", column = "removed_by_reason")
|
||||
})
|
||||
@Select("""
|
||||
SELECT punishment.uuid,
|
||||
SELECT punishment.id,
|
||||
punishment.uuid,
|
||||
user_lookup.name AS punished_name,
|
||||
punishment.reason,
|
||||
punishment.banned_by_uuid,
|
||||
|
|
@ -192,7 +199,8 @@ public interface NameHistoryMapper {
|
|||
punishment.until,
|
||||
punishment.removed_by_reason
|
||||
FROM (
|
||||
SELECT uuid,
|
||||
SELECT id,
|
||||
uuid,
|
||||
reason,
|
||||
banned_by_uuid,
|
||||
banned_by_name,
|
||||
|
|
@ -254,23 +262,23 @@ public interface NameHistoryMapper {
|
|||
}
|
||||
}
|
||||
|
||||
private List<HistoryRecord> getRecentBans(UserType userType, String partialName, int page) {
|
||||
private @NotNull List<HistoryRecord> getRecentBans(UserType userType, String partialName, int page) {
|
||||
return addType(getRecent("litebans_bans", userType, partialName, page), "ban");
|
||||
}
|
||||
|
||||
private List<HistoryRecord> getRecentKicks(UserType userType, String partialName, int page) {
|
||||
private @NotNull List<HistoryRecord> getRecentKicks(UserType userType, String partialName, int page) {
|
||||
return addType(getRecent("litebans_kicks", userType, partialName, page), "kick");
|
||||
}
|
||||
|
||||
private List<HistoryRecord> getRecentMutes(UserType userType, String partialName, int page) {
|
||||
private @NotNull List<HistoryRecord> getRecentMutes(UserType userType, String partialName, int page) {
|
||||
return addType(getRecent("litebans_mutes", userType, partialName, page), "mute");
|
||||
}
|
||||
|
||||
private List<HistoryRecord> getRecentWarns(UserType userType, String partialName, int page) {
|
||||
private @NotNull List<HistoryRecord> getRecentWarns(UserType userType, String partialName, int page) {
|
||||
return addType(getRecent("litebans_warnings", userType, partialName, page), "warn");
|
||||
}
|
||||
|
||||
private List<HistoryRecord> addType(List<HistoryRecord> historyRecords, String type) {
|
||||
private @NotNull List<HistoryRecord> addType(@NotNull List<HistoryRecord> historyRecords, String type) {
|
||||
historyRecords.forEach(historyRecord -> historyRecord.setType(type));
|
||||
return historyRecords;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
package com.alttd.altitudeweb.database.litebans;
|
||||
|
||||
import com.alttd.altitudeweb.type_handler.UUIDTypeHandler;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Result;
|
||||
import org.apache.ibatis.annotations.Results;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
|
@ -14,10 +15,11 @@ public interface UUIDHistoryMapper {
|
|||
int PAGE_SIZE = 10;
|
||||
|
||||
@Results({
|
||||
@Result(property = "uuid", column = "uuid", javaType = UUID.class, typeHandler = UUIDTypeHandler.class),
|
||||
@Result(property = "id", column = "id"),
|
||||
@Result(property = "uuid", column = "uuid"),
|
||||
@Result(property = "punishedName", column = "punished_name"),
|
||||
@Result(property = "reason", column = "reason"),
|
||||
@Result(property = "bannedByUuid", column = "banned_by_uuid", javaType = UUID.class, typeHandler = UUIDTypeHandler.class),
|
||||
@Result(property = "bannedByUuid", column = "banned_by_uuid"),
|
||||
@Result(property = "bannedByName", column = "banned_by_name"),
|
||||
@Result(property = "removedByName", column = "removed_by_name"),
|
||||
@Result(property = "time", column = "time"),
|
||||
|
|
@ -26,7 +28,7 @@ public interface UUIDHistoryMapper {
|
|||
@Result(property = "type", column = "type")
|
||||
})
|
||||
@Select("""
|
||||
SELECT all_punishments.uuid, user_lookup.name AS punished_name, reason, banned_by_uuid, banned_by_name,
|
||||
SELECT id, all_punishments.uuid, user_lookup.name AS punished_name, reason, banned_by_uuid, banned_by_name,
|
||||
removed_by_name, time, until, removed_by_reason, type
|
||||
FROM all_punishments
|
||||
INNER JOIN user_lookup
|
||||
|
|
@ -41,10 +43,11 @@ public interface UUIDHistoryMapper {
|
|||
@Param("offset") int offset);
|
||||
|
||||
@Results({
|
||||
@Result(property = "uuid", column = "uuid", javaType = UUID.class, typeHandler = UUIDTypeHandler.class),
|
||||
@Result(property = "id", column = "id"),
|
||||
@Result(property = "uuid", column = "uuid"),
|
||||
@Result(property = "punishedName", column = "punished_name"),
|
||||
@Result(property = "reason", column = "reason"),
|
||||
@Result(property = "bannedByUuid", column = "banned_by_uuid", javaType = UUID.class, typeHandler = UUIDTypeHandler.class),
|
||||
@Result(property = "bannedByUuid", column = "banned_by_uuid"),
|
||||
@Result(property = "bannedByName", column = "banned_by_name"),
|
||||
@Result(property = "removedByName", column = "removed_by_name"),
|
||||
@Result(property = "time", column = "time"),
|
||||
|
|
@ -52,7 +55,7 @@ public interface UUIDHistoryMapper {
|
|||
@Result(property = "removedByReason", column = "removed_by_reason")
|
||||
})
|
||||
@Select("""
|
||||
SELECT punishment.uuid, user_lookup.name AS punished_name, reason, banned_by_uuid, banned_by_name,
|
||||
SELECT punishment.id, punishment.uuid, user_lookup.name AS punished_name, reason, banned_by_uuid, banned_by_name,
|
||||
removed_by_name, time, until, removed_by_reason
|
||||
FROM ${tableName} AS punishment
|
||||
INNER JOIN user_lookup ON user_lookup.uuid = punishment.uuid
|
||||
|
|
@ -66,7 +69,8 @@ public interface UUIDHistoryMapper {
|
|||
@Param("limit") int limit,
|
||||
@Param("offset") int offset);
|
||||
|
||||
default List<HistoryRecord> getRecent(HistoryType historyType, UserType userType, UUID uuid, int page) {
|
||||
default List<HistoryRecord> getRecent(@NotNull HistoryType historyType, @NotNull UserType userType,
|
||||
@NotNull UUID uuid, int page) {
|
||||
return switch (historyType) {
|
||||
case ALL -> getRecentAll(userType, uuid, page);
|
||||
case BAN -> getRecentBans(userType, uuid, page);
|
||||
|
|
@ -76,7 +80,8 @@ public interface UUIDHistoryMapper {
|
|||
};
|
||||
}
|
||||
|
||||
private List<HistoryRecord> getRecent(String tableName, UserType userType, UUID uuid, int page) {
|
||||
private List<HistoryRecord> getRecent(@NotNull String tableName, @NotNull UserType userType,
|
||||
@NotNull UUID uuid, int page) {
|
||||
int offset = page * PAGE_SIZE;
|
||||
int limit = PAGE_SIZE;
|
||||
return switch (userType) {
|
||||
|
|
@ -85,7 +90,7 @@ public interface UUIDHistoryMapper {
|
|||
};
|
||||
}
|
||||
|
||||
private List<HistoryRecord> getRecentAll(UserType userType, UUID uuid, int page) {
|
||||
private List<HistoryRecord> getRecentAll(@NotNull UserType userType, @NotNull UUID uuid, int page) {
|
||||
int offset = page * PAGE_SIZE;
|
||||
int limit = PAGE_SIZE;
|
||||
return switch (userType) {
|
||||
|
|
@ -96,23 +101,24 @@ public interface UUIDHistoryMapper {
|
|||
};
|
||||
}
|
||||
|
||||
private List<HistoryRecord> getRecentBans(UserType userType, UUID uuid, int page) {
|
||||
private @NotNull List<HistoryRecord> getRecentBans(@NotNull UserType userType, @NotNull UUID uuid, int page) {
|
||||
return addType(getRecent("litebans_bans", userType, uuid, page), "ban");
|
||||
}
|
||||
|
||||
private List<HistoryRecord> getRecentKicks(UserType userType, UUID uuid, int page) {
|
||||
private @NotNull List<HistoryRecord> getRecentKicks(@NotNull UserType userType, @NotNull UUID uuid, int page) {
|
||||
return addType(getRecent("litebans_kicks", userType, uuid, page), "kick");
|
||||
}
|
||||
|
||||
private List<HistoryRecord> getRecentMutes(UserType userType, UUID uuid, int page) {
|
||||
private @NotNull List<HistoryRecord> getRecentMutes(@NotNull UserType userType, @NotNull UUID uuid, int page) {
|
||||
return addType(getRecent("litebans_mutes", userType, uuid, page), "mute");
|
||||
}
|
||||
|
||||
private List<HistoryRecord> getRecentWarns(UserType userType, UUID uuid, int page) {
|
||||
private @NotNull List<HistoryRecord> getRecentWarns(@NotNull UserType userType, @NotNull UUID uuid, int page) {
|
||||
return addType(getRecent("litebans_warnings", userType, uuid, page), "warn");
|
||||
}
|
||||
|
||||
private List<HistoryRecord> addType(List<HistoryRecord> historyRecords, String type) {
|
||||
@Contract("_, _ -> param1")
|
||||
private @NotNull List<HistoryRecord> addType(@NotNull List<HistoryRecord> historyRecords, @NotNull String type) {
|
||||
historyRecords.forEach(historyRecord -> historyRecord.setType(type));
|
||||
return historyRecords;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public class InitializeLiteBans {
|
|||
configuration.addMapper(NameHistoryMapper.class);
|
||||
configuration.addMapper(UUIDHistoryMapper.class);
|
||||
configuration.addMapper(HistoryCountMapper.class);
|
||||
configuration.addMapper(IdHistoryMapper.class);
|
||||
}).join()
|
||||
.runQuery(sqlSession -> {
|
||||
createAllPunishmentsView(sqlSession);
|
||||
|
|
@ -29,15 +30,15 @@ public class InitializeLiteBans {
|
|||
private static void createAllPunishmentsView(SqlSession sqlSession) {
|
||||
String query = """
|
||||
CREATE VIEW IF NOT EXISTS all_punishments AS
|
||||
SELECT uuid, reason, banned_by_uuid, banned_by_name, removed_by_name, time, until, removed_by_reason,
|
||||
SELECT id, uuid, reason, banned_by_uuid, banned_by_name, removed_by_name, time, until, removed_by_reason,
|
||||
'ban' as type
|
||||
FROM litebans_bans
|
||||
UNION ALL
|
||||
SELECT uuid, reason, banned_by_uuid, banned_by_name, removed_by_name, time, until, removed_by_reason,
|
||||
SELECT id, uuid, reason, banned_by_uuid, banned_by_name, removed_by_name, time, until, removed_by_reason,
|
||||
'mute' as type
|
||||
FROM litebans_mutes
|
||||
UNION ALL
|
||||
SELECT uuid, reason, banned_by_uuid, banned_by_name, removed_by_name, time, until, removed_by_reason,
|
||||
SELECT id, uuid, reason, banned_by_uuid, banned_by_name, removed_by_name, time, until, removed_by_reason,
|
||||
'warn' as type
|
||||
FROM litebans_warnings
|
||||
ORDER BY time DESC;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ export const routes: Routes = [
|
|||
path: 'bans',
|
||||
loadComponent: () => import('./bans/bans.component').then(m => m.BansComponent)
|
||||
},
|
||||
{
|
||||
path: 'bans/:type/:id',
|
||||
loadComponent: () => import('./bans/details/details.component').then(m => m.DetailsComponent)
|
||||
},
|
||||
{
|
||||
path: 'economy',
|
||||
loadComponent: () => import('./economy/economy.component').then(m => m.EconomyComponent)
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@
|
|||
</div>
|
||||
<div class="historyTable">
|
||||
<app-history [userType]="userType" [punishmentType]="punishmentType"
|
||||
[page]="page" [searchTerm]="finalSearchTerm" (pageChange)="updatePageSize($event)">
|
||||
[page]="page" [searchTerm]="finalSearchTerm" (pageChange)="updatePageSize($event)"
|
||||
(selectItem)="setSearch($event)">
|
||||
</app-history>
|
||||
</div>
|
||||
<div class="changePageButtons">
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import {HistoryCount, HistoryService} from '../../api';
|
|||
import {NgClass, NgForOf, NgIf} from '@angular/common';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {catchError, map, Observable} from 'rxjs';
|
||||
import {SearchParams} from './search-terms';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bans',
|
||||
|
|
@ -210,4 +211,11 @@ export class BansComponent implements OnInit {
|
|||
this.actualPage = this.page;
|
||||
}
|
||||
}
|
||||
|
||||
public setSearch(searchParams: SearchParams) {
|
||||
this.userType = searchParams.userType
|
||||
this.searchTerm = searchParams.searchTerm
|
||||
this.punishmentType = searchParams.punishmentType
|
||||
this.search();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
62
frontend/src/app/bans/details/details.component.html
Normal file
62
frontend/src/app/bans/details/details.component.html
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<ng-container>
|
||||
<app-header [current_page]="'bans'" height="200px" background_image="/public/img/backgrounds/staff.png"
|
||||
[overlay_gradient]="0.5">>
|
||||
<div class="title" header-content>
|
||||
<h1>Minecraft Punishments</h1>
|
||||
</div>
|
||||
</app-header>
|
||||
|
||||
<ng-container *ngIf="punishment === undefined">
|
||||
<p>Loading...</p>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="punishment">
|
||||
<table [cellSpacing]="0">
|
||||
<div>
|
||||
<p>type: {{ this.historyFormat.getType(punishment) }}</p>
|
||||
<p>is active: {{ this.historyFormat.isActive(punishment) }}</p>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Player</td>
|
||||
<td>
|
||||
<div class="playerContainer">
|
||||
<img class="avatar" [ngSrc]="this.historyFormat.getAvatarUrl(punishment.uuid)" width="25" height="25"
|
||||
alt="{{punishment.username}}'s Minecraft skin">
|
||||
<span class="username">{{ punishment.username }}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Moderator</td>
|
||||
<td>
|
||||
<div class="playerContainer">
|
||||
<img class="avatar" [ngSrc]="this.historyFormat.getAvatarUrl(punishment.punishedByUuid)" width="25"
|
||||
height="25"
|
||||
alt="{{punishment.punishedBy}}'s Minecraft skin">
|
||||
<span class="username">{{ punishment.punishedBy }}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Reason</td>
|
||||
<td>{{ punishment.reason | removeTrailingPeriod }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Date</td>
|
||||
<td>{{ this.historyFormat.getPunishmentTime(punishment) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Expires</td>
|
||||
<td>{{ this.historyFormat.getExpiredTime(punishment) }}</td>
|
||||
</tr>
|
||||
<ng-container *ngIf="punishment.removedBy !== undefined && punishment.removedBy.length > 0">
|
||||
<tr>
|
||||
<td>Un{{ this.historyFormat.getType(punishment).toLocaleLowerCase() }} reason</td>
|
||||
<td>{{ punishment.removedReason == null ? 'No reason specified' : punishment.removedReason }}</td>
|
||||
</tr>
|
||||
</ng-container>
|
||||
</tbody>
|
||||
</div>
|
||||
</table>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
23
frontend/src/app/bans/details/details.component.spec.ts
Normal file
23
frontend/src/app/bans/details/details.component.spec.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DetailsComponent } from './details.component';
|
||||
|
||||
describe('DetailsComponent', () => {
|
||||
let component: DetailsComponent;
|
||||
let fixture: ComponentFixture<DetailsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [DetailsComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(DetailsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
69
frontend/src/app/bans/details/details.component.ts
Normal file
69
frontend/src/app/bans/details/details.component.ts
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
import {HistoryService, PunishmentHistory} from '../../../api';
|
||||
import {NgIf, NgOptimizedImage} from '@angular/common';
|
||||
import {RemoveTrailingPeriodPipe} from '../../util/RemoveTrailingPeriodPipe';
|
||||
import {HistoryFormatService} from '../history-format.service';
|
||||
import {ActivatedRoute} from '@angular/router';
|
||||
import {catchError, map} from 'rxjs';
|
||||
import {HeaderComponent} from '../../header/header.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-details',
|
||||
imports: [
|
||||
NgIf,
|
||||
NgOptimizedImage,
|
||||
RemoveTrailingPeriodPipe,
|
||||
HeaderComponent
|
||||
],
|
||||
templateUrl: './details.component.html',
|
||||
styleUrl: './details.component.scss'
|
||||
})
|
||||
export class DetailsComponent implements OnInit {
|
||||
type: 'all' | 'ban' | 'mute' | 'kick' | 'warn' = 'all';
|
||||
id: number = -1;
|
||||
punishment: PunishmentHistory | undefined;
|
||||
|
||||
constructor(private route: ActivatedRoute,
|
||||
private historyApi: HistoryService,
|
||||
public historyFormat: HistoryFormatService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.route.paramMap.subscribe(params => {
|
||||
switch (params.get('type')) {
|
||||
case 'ban':
|
||||
this.type = 'ban';
|
||||
break;
|
||||
case 'mute':
|
||||
this.type = 'mute';
|
||||
break;
|
||||
case 'kick':
|
||||
this.type = 'kick';
|
||||
break;
|
||||
case 'warn':
|
||||
this.type = 'warn';
|
||||
break;
|
||||
default:
|
||||
throw new Error("Invalid type");
|
||||
}
|
||||
this.id = Number(params.get('id') || '-1');
|
||||
this.loadPunishmentData();
|
||||
});
|
||||
}
|
||||
|
||||
private loadPunishmentData() {
|
||||
if (!this.type || this.type === 'all' || this.id < 0 || isNaN(this.id)) {
|
||||
console.error("Invalid type or id");
|
||||
return;
|
||||
}
|
||||
this.historyApi.getHistoryById(this.type, this.id).pipe(
|
||||
map(punishment => {
|
||||
this.punishment = punishment;
|
||||
}),
|
||||
catchError(err => {
|
||||
console.error(err);
|
||||
return [];
|
||||
})
|
||||
).subscribe();
|
||||
}
|
||||
}
|
||||
16
frontend/src/app/bans/history-format.service.spec.ts
Normal file
16
frontend/src/app/bans/history-format.service.spec.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HistoryFormatService } from './history-format.service';
|
||||
|
||||
describe('HistoryFormatService', () => {
|
||||
let service: HistoryFormatService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(HistoryFormatService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
58
frontend/src/app/bans/history-format.service.ts
Normal file
58
frontend/src/app/bans/history-format.service.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import {Injectable} from '@angular/core';
|
||||
import {PunishmentHistory} from '../../api';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class HistoryFormatService {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public getPunishmentTime(entry: PunishmentHistory) {
|
||||
const date = new Date(entry.punishmentTime);
|
||||
return date.toLocaleString(navigator.language, {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
});
|
||||
}
|
||||
|
||||
public isActive(entry: PunishmentHistory): boolean {
|
||||
return entry.expiryTime > Date.now();
|
||||
}
|
||||
|
||||
public getType(entry: PunishmentHistory): string {
|
||||
return entry.type.charAt(0).toUpperCase() + entry.type.slice(1);
|
||||
}
|
||||
|
||||
public getExpiredTime(entry: PunishmentHistory): string {
|
||||
let suffix: string = '';
|
||||
if (entry.removedBy !== null && entry.removedBy !== undefined) {
|
||||
suffix = '(' + entry.removedBy + ')';
|
||||
}
|
||||
if (entry.expiryTime <= 0) {
|
||||
return "Permanent " + this.getType(entry) + " " + suffix;
|
||||
}
|
||||
const date = new Date(entry.expiryTime);
|
||||
return date.toLocaleString(navigator.language, {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
}) + " " + suffix;
|
||||
}
|
||||
|
||||
public getAvatarUrl(entry: string): string {
|
||||
let uuid = entry.replace('-', '');
|
||||
if (uuid === 'C') {
|
||||
uuid = "f78a4d8dd51b4b3998a3230f2de0c670"
|
||||
}
|
||||
return `https://crafatar.com/avatars/${uuid}?size=25&overlay`;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,24 +19,32 @@
|
|||
<div>
|
||||
<tbody>
|
||||
<tr class="historyPlayerRow" *ngFor="let entry of history">
|
||||
<td class="historyType">{{ getType(entry) }}</td>
|
||||
<td class="historyPlayer">
|
||||
<td class="historyType" (click)="showDetailedPunishment(entry)">
|
||||
{{ this.historyFormat.getType(entry) }}
|
||||
</td>
|
||||
<td class="historyPlayer" (click)="setSearch(entry.type, entry.username, 'player')">
|
||||
<div class="playerContainer">
|
||||
<img class="avatar" [ngSrc]="getAvatarUrl(entry.uuid)" width="25" height="25"
|
||||
<img class="avatar" [ngSrc]="this.historyFormat.getAvatarUrl(entry.uuid)" width="25" height="25"
|
||||
alt="{{entry.username}}'s Minecraft skin">
|
||||
<span class="username">{{ entry.username }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="historyPlayer">
|
||||
<td class="historyPlayer" (click)="setSearch(entry.type, entry.punishedBy, 'staff')">
|
||||
<div class="playerContainer">
|
||||
<img class="avatar" [ngSrc]="getAvatarUrl(entry.punishedByUuid)" width="25" height="25"
|
||||
<img class="avatar" [ngSrc]="this.historyFormat.getAvatarUrl(entry.punishedByUuid)" width="25" height="25"
|
||||
alt="{{entry.punishedBy}}'s Minecraft skin">
|
||||
<span>{{ entry.punishedBy }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="historyReason">{{ entry.reason | removeTrailingPeriod }}</td>
|
||||
<td class="historyDate">{{ getPunishmentTime(entry) }}</td>
|
||||
<td class="historyDate">{{ getExpiredTime(entry) }}</td>
|
||||
<td class="historyReason" (click)="showDetailedPunishment(entry)">
|
||||
{{ entry.reason | removeTrailingPeriod }}
|
||||
</td>
|
||||
<td class="historyDate" (click)="showDetailedPunishment(entry)">
|
||||
{{ this.historyFormat.getPunishmentTime(entry) }}
|
||||
</td>
|
||||
<td class="historyDate" (click)="showDetailedPunishment(entry)">
|
||||
{{ this.historyFormat.getExpiredTime(entry) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ table tr td {
|
|||
|
||||
.historyPlayerRow:hover {
|
||||
background-color: var(--history-table-row-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.historyTableHead {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
|
||||
import {BASE_PATH, HistoryService, PunishmentHistoryInner} from '../../../api';
|
||||
import {BASE_PATH, HistoryService, PunishmentHistory} from '../../../api';
|
||||
import {catchError, map, Observable, shareReplay} from 'rxjs';
|
||||
import {NgForOf, NgIf, NgOptimizedImage} from '@angular/common';
|
||||
import {CookieService} from 'ngx-cookie-service';
|
||||
import {RemoveTrailingPeriodPipe} from '../../util/RemoveTrailingPeriodPipe';
|
||||
import {HttpErrorResponse} from '@angular/common/http';
|
||||
import {environment} from '../../../environments/environment';
|
||||
import {HistoryFormatService} from '../history-format.service';
|
||||
import {SearchParams} from '../search-terms';
|
||||
import {Router} from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-history',
|
||||
|
|
@ -30,12 +33,13 @@ export class HistoryComponent implements OnInit, OnChanges {
|
|||
@Input() searchTerm: string = '';
|
||||
|
||||
@Output() pageChange = new EventEmitter<number>();
|
||||
@Output() selectItem = new EventEmitter<SearchParams>();
|
||||
|
||||
private uuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
||||
|
||||
public history: PunishmentHistoryInner[] = []
|
||||
public history: PunishmentHistory[] = []
|
||||
|
||||
constructor(private historyApi: HistoryService) {
|
||||
constructor(private historyApi: HistoryService, public historyFormat: HistoryFormatService, private router: Router) {
|
||||
}
|
||||
|
||||
ngOnChanges(): void {
|
||||
|
|
@ -47,7 +51,7 @@ export class HistoryComponent implements OnInit, OnChanges {
|
|||
}
|
||||
|
||||
private reloadHistory(): void {
|
||||
let historyObservable: Observable<PunishmentHistoryInner[]>;
|
||||
let historyObservable: Observable<PunishmentHistory[]>;
|
||||
if (this.searchTerm.length === 0) {
|
||||
historyObservable = this.historyApi.getHistoryForAll(this.userType, this.punishmentType, this.page);
|
||||
} else {
|
||||
|
|
@ -89,42 +93,31 @@ export class HistoryComponent implements OnInit, OnChanges {
|
|||
).subscribe();
|
||||
}
|
||||
|
||||
public getPunishmentTime(entry: PunishmentHistoryInner) {
|
||||
const date = new Date(entry.punishmentTime);
|
||||
return date.toLocaleString(navigator.language, {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
});
|
||||
}
|
||||
|
||||
public getType(entry: PunishmentHistoryInner) {
|
||||
return entry.type.charAt(0).toUpperCase() + entry.type.slice(1);
|
||||
}
|
||||
|
||||
public getExpiredTime(entry: PunishmentHistoryInner) {
|
||||
if (entry.expiryTime <= 0) {
|
||||
return "Permanent " + this.getType(entry);
|
||||
setSearch(type: PunishmentHistory.TypeEnum, name: string, userType: 'player' | 'staff') {
|
||||
let punishmentType: 'all' | 'ban' | 'mute' | 'kick' | 'warn' = 'all';
|
||||
switch (type) {
|
||||
case 'ban':
|
||||
punishmentType = 'ban';
|
||||
break;
|
||||
case 'mute':
|
||||
punishmentType = 'mute';
|
||||
break;
|
||||
case 'kick':
|
||||
punishmentType = 'kick';
|
||||
break;
|
||||
case 'warn':
|
||||
punishmentType = 'warn';
|
||||
break;
|
||||
}
|
||||
const date = new Date(entry.expiryTime);
|
||||
return date.toLocaleString(navigator.language, {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
});
|
||||
let searchParams: SearchParams = {
|
||||
userType: userType,
|
||||
punishmentType: punishmentType,
|
||||
searchTerm: name
|
||||
}
|
||||
this.selectItem.emit(searchParams);
|
||||
}
|
||||
|
||||
public getAvatarUrl(entry: string): string {
|
||||
let uuid = entry.replace('-', '');
|
||||
if (uuid === 'C') {
|
||||
uuid = "f78a4d8dd51b4b3998a3230f2de0c670"
|
||||
}
|
||||
return `https://crafatar.com/avatars/${uuid}?size=25&overlay`;
|
||||
public showDetailedPunishment(entry: PunishmentHistory) {
|
||||
this.router.navigate([`bans/${entry.type}/${entry.id}`]).then();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
5
frontend/src/app/bans/search-terms.ts
Normal file
5
frontend/src/app/bans/search-terms.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export interface SearchParams {
|
||||
userType: 'player' | 'staff';
|
||||
searchTerm: string;
|
||||
punishmentType: 'all' | 'ban' | 'mute' | 'kick' | 'warn';
|
||||
}
|
||||
|
|
@ -26,6 +26,8 @@ paths:
|
|||
$ref: './schemas/bans/bans.yml#/getTotalResultsForUuidSearch'
|
||||
/history/{userType}/search-results/user/{type}/{user}:
|
||||
$ref: './schemas/bans/bans.yml#/getTotalResultsForUserSearch'
|
||||
/history/single/{type}/{id}:
|
||||
$ref: './schemas/bans/bans.yml#/getHistoryById'
|
||||
/history/total:
|
||||
$ref: './schemas/bans/bans.yml#/getTotalPunishments'
|
||||
/appeal/update-mail:
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ getHistoryForUsers:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PunishmentHistory'
|
||||
$ref: '#/components/schemas/PunishmentHistoryList'
|
||||
default:
|
||||
description: Unexpected error
|
||||
content:
|
||||
|
|
@ -70,7 +70,7 @@ getHistoryForAll:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PunishmentHistory'
|
||||
$ref: '#/components/schemas/PunishmentHistoryList'
|
||||
default:
|
||||
description: Unexpected error
|
||||
content:
|
||||
|
|
@ -97,7 +97,7 @@ getHistoryForUuid:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PunishmentHistory'
|
||||
$ref: '#/components/schemas/PunishmentHistoryList'
|
||||
default:
|
||||
description: Unexpected error
|
||||
content:
|
||||
|
|
@ -172,6 +172,29 @@ getTotalResultsForUuidSearch:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: '../generic/errors.yml#/components/schemas/ApiError'
|
||||
getHistoryById:
|
||||
get:
|
||||
tags:
|
||||
- history
|
||||
summary: Gets history for specified id
|
||||
description: Retrieves a specific history record
|
||||
operationId: getHistoryById
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/HistoryType'
|
||||
- $ref: '#/components/parameters/Id'
|
||||
responses:
|
||||
'200':
|
||||
description: Successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PunishmentHistory'
|
||||
default:
|
||||
description: Unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '../generic/errors.yml#/components/schemas/ApiError'
|
||||
components:
|
||||
parameters:
|
||||
HistoryType:
|
||||
|
|
@ -211,57 +234,70 @@ components:
|
|||
schema:
|
||||
type: integer
|
||||
description: The page that should be retrieved
|
||||
Id:
|
||||
name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
description: The id of the punishment that should be retrieved
|
||||
schemas:
|
||||
SearchResults:
|
||||
type: integer
|
||||
description: A number representing the total count of results for the search query
|
||||
PunishmentHistory:
|
||||
PunishmentHistoryList:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- username
|
||||
- uuid
|
||||
- reason
|
||||
- type
|
||||
- punishmentTime
|
||||
- expiryTime
|
||||
- punishedBy
|
||||
- punishedByUuid
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
description: The username of the user
|
||||
uuid:
|
||||
type: string
|
||||
description: The UUID of the user
|
||||
reason:
|
||||
type: string
|
||||
description: The reason for the punishment
|
||||
type:
|
||||
type: string
|
||||
description: The type of punishment
|
||||
enum: [ ban, mute, kick, warn ]
|
||||
punishmentTime:
|
||||
type: integer
|
||||
format: int64
|
||||
description: The time when the punishment was given
|
||||
expiryTime:
|
||||
type: integer
|
||||
format: int64
|
||||
description: The time when the punishment expires
|
||||
punishedBy:
|
||||
type: string
|
||||
description: The username of the punishment issuer
|
||||
punishedByUuid:
|
||||
type: string
|
||||
description: The UUID of the punishment issuer
|
||||
removedBy:
|
||||
type: string
|
||||
description: The name of the staff member who removed the punishment
|
||||
removedReason:
|
||||
type: string
|
||||
description: The reason why the punishment was removed
|
||||
$ref: '#/components/schemas/PunishmentHistory'
|
||||
PunishmentHistory:
|
||||
type: object
|
||||
required:
|
||||
- username
|
||||
- uuid
|
||||
- reason
|
||||
- type
|
||||
- punishmentTime
|
||||
- expiryTime
|
||||
- punishedBy
|
||||
- punishedByUuid
|
||||
- id
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
description: The username of the user
|
||||
uuid:
|
||||
type: string
|
||||
description: The UUID of the user
|
||||
reason:
|
||||
type: string
|
||||
description: The reason for the punishment
|
||||
type:
|
||||
type: string
|
||||
description: The type of punishment
|
||||
enum: [ ban, mute, kick, warn ]
|
||||
punishmentTime:
|
||||
type: integer
|
||||
format: int64
|
||||
description: The time when the punishment was given
|
||||
expiryTime:
|
||||
type: integer
|
||||
format: int64
|
||||
description: The time when the punishment expires
|
||||
punishedBy:
|
||||
type: string
|
||||
description: The username of the punishment issuer
|
||||
punishedByUuid:
|
||||
type: string
|
||||
description: The UUID of the punishment issuer
|
||||
removedBy:
|
||||
type: string
|
||||
description: The name of the staff member who removed the punishment
|
||||
removedReason:
|
||||
type: string
|
||||
description: The reason why the punishment was removed
|
||||
id:
|
||||
type: integer
|
||||
description: Id of the punishment
|
||||
Player:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user