Added members view #130
This commit is contained in:
parent
f44f77d7e5
commit
85452c9a74
@ -180,12 +180,12 @@ class QueryABC(ObjectType):
|
|||||||
# @FilterABC.resolve_filter_annotation
|
# @FilterABC.resolve_filter_annotation
|
||||||
def _resolve_collection(self, collection: List, *_, filter: FilterABC = None, page: Page = None, sort: Sort = None):
|
def _resolve_collection(self, collection: List, *_, filter: FilterABC = None, page: Page = None, sort: Sort = None):
|
||||||
if filter is not None:
|
if filter is not None:
|
||||||
return filter.filter(collection)
|
collection = filter.filter(collection)
|
||||||
|
|
||||||
if page is not None:
|
if page is not None:
|
||||||
return page.filter(collection)
|
collection = page.filter(collection)
|
||||||
|
|
||||||
if sort is not None:
|
if sort is not None:
|
||||||
return sort.filter(collection)
|
collection = sort.filter(collection)
|
||||||
|
|
||||||
return collection
|
return collection
|
||||||
|
@ -25,7 +25,7 @@ class LevelFilter(FilterABC):
|
|||||||
if "server" in values:
|
if "server" in values:
|
||||||
from bot_graphql.filter.server_filter import ServerFilter
|
from bot_graphql.filter.server_filter import ServerFilter
|
||||||
|
|
||||||
self._server: ServerFilter = self._services.get_service(LevelFilter)
|
self._server: ServerFilter = self._services.get_service(ServerFilter)
|
||||||
self._server.from_dict(values["server"])
|
self._server.from_dict(values["server"])
|
||||||
|
|
||||||
def filter(self, query: List[Level]) -> List[Level]:
|
def filter(self, query: List[Level]) -> List[Level]:
|
||||||
|
@ -5,6 +5,7 @@ from cpl_discord.service import DiscordBotServiceABC
|
|||||||
from cpl_query.extension import List
|
from cpl_query.extension import List
|
||||||
|
|
||||||
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
||||||
|
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
|
||||||
from bot_data.model.user import User
|
from bot_data.model.user import User
|
||||||
from bot_graphql.abc.filter_abc import FilterABC
|
from bot_graphql.abc.filter_abc import FilterABC
|
||||||
from bot_graphql.filter.level_filter import LevelFilter
|
from bot_graphql.filter.level_filter import LevelFilter
|
||||||
@ -18,6 +19,7 @@ class UserFilter(FilterABC):
|
|||||||
bot: DiscordBotServiceABC,
|
bot: DiscordBotServiceABC,
|
||||||
client_utils: ClientUtilsABC,
|
client_utils: ClientUtilsABC,
|
||||||
levels: LevelService,
|
levels: LevelService,
|
||||||
|
user_joined_servers: UserJoinedServerRepositoryABC,
|
||||||
):
|
):
|
||||||
FilterABC.__init__(self)
|
FilterABC.__init__(self)
|
||||||
|
|
||||||
@ -25,6 +27,7 @@ class UserFilter(FilterABC):
|
|||||||
self._bot = bot
|
self._bot = bot
|
||||||
self._client_utils = client_utils
|
self._client_utils = client_utils
|
||||||
self._levels = levels
|
self._levels = levels
|
||||||
|
self._user_joined_servers = user_joined_servers
|
||||||
|
|
||||||
self._id = None
|
self._id = None
|
||||||
self._discord_id = None
|
self._discord_id = None
|
||||||
@ -34,6 +37,7 @@ class UserFilter(FilterABC):
|
|||||||
self._ontime = None
|
self._ontime = None
|
||||||
self._level: Optional[LevelFilter] = None
|
self._level: Optional[LevelFilter] = None
|
||||||
self._server = None
|
self._server = None
|
||||||
|
self._left_server = None
|
||||||
|
|
||||||
def from_dict(self, values: dict):
|
def from_dict(self, values: dict):
|
||||||
if "id" in values:
|
if "id" in values:
|
||||||
@ -64,18 +68,26 @@ class UserFilter(FilterABC):
|
|||||||
self._server: ServerFilter = self._services.get_service(ServerFilter)
|
self._server: ServerFilter = self._services.get_service(ServerFilter)
|
||||||
self._server.from_dict(values["server"])
|
self._server.from_dict(values["server"])
|
||||||
|
|
||||||
|
if "leftServer" in values:
|
||||||
|
self._left_server = values["leftServer"]
|
||||||
|
|
||||||
def filter(self, query: List[User]) -> List[User]:
|
def filter(self, query: List[User]) -> List[User]:
|
||||||
if self._id is not None:
|
if self._id is not None:
|
||||||
query = query.where(lambda x: x.user_id == self._id)
|
query = query.where(lambda x: x.user_id == self._id or str(self._id) in str(x.user_id))
|
||||||
|
|
||||||
if self._discord_id is not None:
|
if self._discord_id is not None:
|
||||||
query = query.where(lambda x: x.discord_id == self._discord_id)
|
query = query.where(
|
||||||
|
lambda x: x.discord_id == self._discord_id or str(self._discord_id) in str(x.discord_id)
|
||||||
|
)
|
||||||
|
|
||||||
if self._name is not None:
|
if self._name is not None:
|
||||||
query = query.where(
|
|
||||||
lambda x: self._bot.get_user(x.discord_id).name == self._name
|
def _get_member(user: User):
|
||||||
or self._name in self._bot.get_user(x.discord_id).name
|
guild = self._bot.get_guild(user.server.discord_server_id)
|
||||||
)
|
member = guild.get_member(user.discord_id)
|
||||||
|
return member is not None and (member.name == self._name or self._name in member.name)
|
||||||
|
|
||||||
|
query = query.where(_get_member)
|
||||||
|
|
||||||
if self._xp is not None:
|
if self._xp is not None:
|
||||||
query = query.where(lambda x: x.xp == self._xp)
|
query = query.where(lambda x: x.xp == self._xp)
|
||||||
@ -94,4 +106,12 @@ class UserFilter(FilterABC):
|
|||||||
servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.server_id)
|
servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.server_id)
|
||||||
query = query.where(lambda x: x.server.server_id in servers)
|
query = query.where(lambda x: x.server.server_id in servers)
|
||||||
|
|
||||||
|
if self._left_server is not None:
|
||||||
|
|
||||||
|
def _has_user_left_server(user: User):
|
||||||
|
active_join = self._user_joined_servers.find_active_user_joined_server_by_user_id(user.user_id)
|
||||||
|
return (active_join is None) == self._left_server
|
||||||
|
|
||||||
|
query = query.where(_has_user_left_server)
|
||||||
|
|
||||||
return query
|
return query
|
||||||
|
@ -17,6 +17,7 @@ type User implements TableQuery {
|
|||||||
userJoinedGameServers(filter: UserJoinedGameServerFilter, page: Page, sort: Sort): [UserJoinedGameServer]
|
userJoinedGameServers(filter: UserJoinedGameServerFilter, page: Page, sort: Sort): [UserJoinedGameServer]
|
||||||
|
|
||||||
server: Server
|
server: Server
|
||||||
|
leftServer: Boolean
|
||||||
|
|
||||||
createdAt: String
|
createdAt: String
|
||||||
modifiedAt: String
|
modifiedAt: String
|
||||||
@ -31,6 +32,7 @@ input UserFilter {
|
|||||||
ontime: Float
|
ontime: Float
|
||||||
level: LevelFilter
|
level: LevelFilter
|
||||||
server: ServerFilter
|
server: ServerFilter
|
||||||
|
leftServer: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserMutation {
|
type UserMutation {
|
||||||
@ -40,4 +42,5 @@ type UserMutation {
|
|||||||
input UserInput {
|
input UserInput {
|
||||||
id: ID
|
id: ID
|
||||||
xp: Int
|
xp: Int
|
||||||
|
levelId: ID
|
||||||
}
|
}
|
@ -1,10 +1,12 @@
|
|||||||
from cpl_core.database.context import DatabaseContextABC
|
from cpl_core.database.context import DatabaseContextABC
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
|
|
||||||
|
from bot_data.abc.level_repository_abc import LevelRepositoryABC
|
||||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
||||||
from bot_data.model.user_role_enum import UserRoleEnum
|
from bot_data.model.user_role_enum import UserRoleEnum
|
||||||
from bot_graphql.abc.query_abc import QueryABC
|
from bot_graphql.abc.query_abc import QueryABC
|
||||||
|
from modules.level.service.level_service import LevelService
|
||||||
from modules.permission.service.permission_service import PermissionService
|
from modules.permission.service.permission_service import PermissionService
|
||||||
|
|
||||||
|
|
||||||
@ -16,6 +18,8 @@ class UserMutation(QueryABC):
|
|||||||
bot: DiscordBotServiceABC,
|
bot: DiscordBotServiceABC,
|
||||||
db: DatabaseContextABC,
|
db: DatabaseContextABC,
|
||||||
permissions: PermissionService,
|
permissions: PermissionService,
|
||||||
|
levels: LevelRepositoryABC,
|
||||||
|
level_service: LevelService,
|
||||||
):
|
):
|
||||||
QueryABC.__init__(self, "UserMutation")
|
QueryABC.__init__(self, "UserMutation")
|
||||||
|
|
||||||
@ -24,6 +28,8 @@ class UserMutation(QueryABC):
|
|||||||
self._bot = bot
|
self._bot = bot
|
||||||
self._db = db
|
self._db = db
|
||||||
self._permissions = permissions
|
self._permissions = permissions
|
||||||
|
self._levels = levels
|
||||||
|
self._level_service = level_service
|
||||||
|
|
||||||
self.set_field("updateUser", self.resolve_update_user)
|
self.set_field("updateUser", self.resolve_update_user)
|
||||||
|
|
||||||
@ -33,8 +39,13 @@ class UserMutation(QueryABC):
|
|||||||
|
|
||||||
user.xp = input["xp"] if "xp" in input else user.xp
|
user.xp = input["xp"] if "xp" in input else user.xp
|
||||||
|
|
||||||
|
if "levelId" in input:
|
||||||
|
level = self._levels.get_level_by_id(input["levelId"])
|
||||||
|
user.xp = level.min_xp
|
||||||
|
|
||||||
self._users.update_user(user)
|
self._users.update_user(user)
|
||||||
self._db.save_changes()
|
self._db.save_changes()
|
||||||
|
self._level_service.set_level(user)
|
||||||
|
|
||||||
user = self._users.get_user_by_id(input["id"])
|
user = self._users.get_user_by_id(input["id"])
|
||||||
return user
|
return user
|
||||||
|
@ -57,6 +57,7 @@ class UserQuery(DataQueryABC):
|
|||||||
UserJoinedGameServerFilter,
|
UserJoinedGameServerFilter,
|
||||||
)
|
)
|
||||||
self.set_field("server", self.resolve_server)
|
self.set_field("server", self.resolve_server)
|
||||||
|
self.set_field("leftServer", self.resolve_left_server)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def resolve_id(user: User, *_):
|
def resolve_id(user: User, *_):
|
||||||
@ -88,3 +89,6 @@ class UserQuery(DataQueryABC):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def resolve_server(user: User, *_):
|
def resolve_server(user: User, *_):
|
||||||
return user.server
|
return user.server
|
||||||
|
|
||||||
|
def resolve_left_server(self, user: User, *_):
|
||||||
|
return self._ujs.find_active_user_joined_server_by_user_id(user.user_id) is None
|
||||||
|
17
kdb-web/src/app/models/data/level.model.ts
Normal file
17
kdb-web/src/app/models/data/level.model.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { Data } from "./data.model";
|
||||||
|
import { Server, ServerFilter } from "./server.model";
|
||||||
|
|
||||||
|
export interface Level extends Data {
|
||||||
|
id?: number;
|
||||||
|
name?: string;
|
||||||
|
color?: string;
|
||||||
|
minXp?: number;
|
||||||
|
permissions?: string;
|
||||||
|
server?: Server;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LevelFilter {
|
||||||
|
id?: number;
|
||||||
|
name?: String;
|
||||||
|
server?: ServerFilter;
|
||||||
|
}
|
@ -1,8 +1,10 @@
|
|||||||
import { Data } from "./data.model";
|
import { Data } from "./data.model";
|
||||||
|
import { User } from "./user.model";
|
||||||
|
import { Level } from "./level.model";
|
||||||
|
|
||||||
export interface Server extends Data {
|
export interface Server extends Data {
|
||||||
id?: number;
|
id?: number;
|
||||||
discordId?: number;
|
discordId?: String;
|
||||||
name?: string;
|
name?: string;
|
||||||
iconURL?: string;
|
iconURL?: string;
|
||||||
autoRoleCount?: number;
|
autoRoleCount?: number;
|
||||||
@ -10,7 +12,13 @@ export interface Server extends Data {
|
|||||||
clientCount?: number;
|
clientCount?: number;
|
||||||
clients?: [];
|
clients?: [];
|
||||||
levelCount?: number;
|
levelCount?: number;
|
||||||
levels?: [];
|
levels?: Level[];
|
||||||
userCount?: number;
|
userCount?: number;
|
||||||
users?: [];
|
users?: User[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServerFilter {
|
||||||
|
id?: number;
|
||||||
|
discordId?: String;
|
||||||
|
name?: String;
|
||||||
}
|
}
|
||||||
|
36
kdb-web/src/app/models/data/user.model.ts
Normal file
36
kdb-web/src/app/models/data/user.model.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { Data } from "./data.model";
|
||||||
|
import { Level, LevelFilter } from "./level.model";
|
||||||
|
import { Server, ServerFilter } from "./server.model";
|
||||||
|
|
||||||
|
export interface User extends Data {
|
||||||
|
id?: number;
|
||||||
|
discordId?: number;
|
||||||
|
name?: string;
|
||||||
|
xp?: number;
|
||||||
|
minecraftId?: number;
|
||||||
|
ontime?: number;
|
||||||
|
level?: Level;
|
||||||
|
server?: Server;
|
||||||
|
leftServer?: boolean;
|
||||||
|
|
||||||
|
joinedServerCount?: number;
|
||||||
|
joinedServers?: [];
|
||||||
|
|
||||||
|
joinedVoiceChannelCount?: number;
|
||||||
|
joinedVoiceChannels?: [];
|
||||||
|
|
||||||
|
userJoinedGameServerCount?: number;
|
||||||
|
userJoinedGameServers?: [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserFilter {
|
||||||
|
id?: number;
|
||||||
|
discordId?: number;
|
||||||
|
name?: string;
|
||||||
|
xp?: number;
|
||||||
|
minecraftId?: number;
|
||||||
|
ontime?: number;
|
||||||
|
level?: LevelFilter;
|
||||||
|
server?: ServerFilter;
|
||||||
|
leftServer?: boolean;
|
||||||
|
}
|
17
kdb-web/src/app/models/graphql/mutations.model.ts
Normal file
17
kdb-web/src/app/models/graphql/mutations.model.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export class Mutations {
|
||||||
|
static updateUser = `
|
||||||
|
mutation updateUser($id: ID, $xp: Int, $levelId: ID) {
|
||||||
|
user {
|
||||||
|
updateUser(input: { id: $id, xp: $xp, levelId: $levelId }) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
xp
|
||||||
|
level {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
@ -21,4 +21,61 @@ export class Queries {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
static levelQuery= `
|
||||||
|
query LevelsList($filter: LevelFilter, $page: Page, $sort: Sort) {
|
||||||
|
levelCount
|
||||||
|
levels(filter: $filter, page: $page, sort: $sort) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
color
|
||||||
|
minXp
|
||||||
|
permissions
|
||||||
|
server {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
static usersQuery= `
|
||||||
|
query UsersList($filter: UserFilter, $page: Page, $sort: Sort) {
|
||||||
|
userCount
|
||||||
|
users(filter: $filter, page: $page, sort: $sort) {
|
||||||
|
id
|
||||||
|
discordId
|
||||||
|
name
|
||||||
|
xp
|
||||||
|
ontime
|
||||||
|
level {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
leftServer
|
||||||
|
|
||||||
|
joinedServerCount
|
||||||
|
joinedServers {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
|
||||||
|
joinedVoiceChannelCount
|
||||||
|
joinedVoiceChannels {
|
||||||
|
id
|
||||||
|
channelId
|
||||||
|
channelName
|
||||||
|
}
|
||||||
|
|
||||||
|
userJoinedGameServerCount
|
||||||
|
userJoinedGameServers {
|
||||||
|
id
|
||||||
|
gameServer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
import { Server } from "../data/server.model";
|
import { Server } from "../data/server.model";
|
||||||
|
import { User } from "../data/user.model";
|
||||||
|
|
||||||
export interface Query {
|
export interface Query {
|
||||||
serverCount: number;
|
serverCount: number;
|
||||||
servers: Server[];
|
servers: Server[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UserListQuery {
|
||||||
|
userCount: number;
|
||||||
|
users: User[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LevelListQuery {
|
||||||
|
levelCount: number;
|
||||||
|
levels: User[];
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
import { Query } from "./query.model";
|
import { User } from "../data/user.model";
|
||||||
|
|
||||||
export interface QueryResult {
|
export interface QueryResult {
|
||||||
data: any;
|
data: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UpdateUserMutationResult {
|
||||||
|
user: {
|
||||||
|
updateUser: User
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
<th pSortableColumn="firstName">
|
<th pSortableColumn="firstName">
|
||||||
<div class="table-header-label">
|
<div class="table-header-label">
|
||||||
<div class="table-header-text">{{'admin.auth_users.headers.first_name' | translate}}</div>
|
<div class="table-header-text">{{'admin.auth_users.headers.first_name' | translate}}</div>
|
||||||
<p-sortIcon icon="sort" field="firstName" class="table-header-icon"></p-sortIcon>
|
<p-sortIcon field="firstName" class="table-header-icon"></p-sortIcon>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
@ -70,24 +70,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
<th class="table-header-small-dropdown">
|
|
||||||
<div class="table-header-label">
|
|
||||||
<div class="table-header-text">{{'admin.auth_users.headers.created_at' | translate}}</div>
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
|
|
||||||
<th class="table-header-small-dropdown">
|
|
||||||
<div class="table-header-label">
|
|
||||||
<div class="table-header-text">{{'admin.auth_users.headers.modified_at' | translate}}</div>
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
|
|
||||||
<th class="table-header-actions">
|
<th class="table-header-actions">
|
||||||
<div class="table-header-label">
|
<div class="table-header-label">
|
||||||
<div class="table-header-text">{{'admin.auth_users.headers.actions' | translate}}</div>
|
<div class="table-header-text">{{'admin.auth_users.headers.actions' | translate}}</div>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
@ -108,7 +95,7 @@
|
|||||||
<th></th>
|
<th></th>
|
||||||
<th>
|
<th>
|
||||||
<form [formGroup]="filterForm">
|
<form [formGroup]="filterForm">
|
||||||
<p-dropdown formControlName="authRole" [options]="authRoles"></p-dropdown>
|
<p-dropdown formControlName="authRole" [options]="authRoles" placeholder="{{'admin.auth_users.headers.auth_role' | translate}}"></p-dropdown>
|
||||||
</form>
|
</form>
|
||||||
</th>
|
</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
@ -223,7 +210,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template pTemplate="Invalidmessage">
|
<ng-template pTemplate="emptymessage">
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="7">{{'admin.auth_users.no_entries_found' | translate}}</td>
|
<td colspan="7">{{'admin.auth_users.no_entries_found' | translate}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -234,3 +221,4 @@
|
|||||||
</p-table>
|
</p-table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -0,0 +1,192 @@
|
|||||||
|
<h1>
|
||||||
|
{{'view.server.members.header' | translate}}
|
||||||
|
</h1>
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div class="content">
|
||||||
|
<p-table #dt [value]="members" dataKey="id" editMode="row" [rowHover]="true" [rows]="10"
|
||||||
|
[rowsPerPageOptions]="[10,25,50]" [paginator]="true" [loading]="loading" [totalRecords]="totalRecords"
|
||||||
|
[lazy]="true" (onLazyLoad)="nextPage($event)">
|
||||||
|
|
||||||
|
<ng-template pTemplate="caption">
|
||||||
|
<div class="table-caption">
|
||||||
|
<div class="table-caption-text">
|
||||||
|
<ng-container *ngIf="!loading">{{members.length}} {{'view.server.members.of' | translate}}
|
||||||
|
{{dt.totalRecords}}
|
||||||
|
</ng-container>
|
||||||
|
{{'view.server.members.members' | translate}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-caption-btn-wrapper btn-wrapper">
|
||||||
|
<button pButton label="{{'view.server.members.reset_filters' | translate}}" icon="pi pi-undo"
|
||||||
|
class="icon-btn btn" (click)="resetFilters()">
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="header">
|
||||||
|
<tr>
|
||||||
|
<th pSortableColumn="id">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.members.headers.id' | translate}}</div>
|
||||||
|
<p-sortIcon field="id" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th pSortableColumn="discordId">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.members.headers.discord_id' | translate}}</div>
|
||||||
|
<p-sortIcon field="discordId" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th pSortableColumn="name">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.members.headers.name' | translate}}</div>
|
||||||
|
<p-sortIcon field="name" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th pSortableColumn="xp">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.members.headers.xp' | translate}}</div>
|
||||||
|
<p-sortIcon field="xp" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th pSortableColumn="ontime">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.members.headers.ontime' | translate}}</div>
|
||||||
|
<p-sortIcon field="ontime" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th class="table-header-small-dropdown" pSortableColumn="level">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.members.headers.level' | translate}}</div>
|
||||||
|
<p-sortIcon field="level" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th class="table-header-actions">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.members.headers.actions' | translate}}</div>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<form [formGroup]="filterForm">
|
||||||
|
<input type="text" pInputText formControlName="id" placeholder="{{'view.server.members.headers.id' | translate}}">
|
||||||
|
</form>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<form [formGroup]="filterForm">
|
||||||
|
<input type="text" pInputText formControlName="discordId" placeholder="{{'view.server.members.headers.discord_id' | translate}}">
|
||||||
|
</form>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<form [formGroup]="filterForm">
|
||||||
|
<input type="text" pInputText formControlName="name" placeholder="{{'view.server.members.headers.name' | translate}}">
|
||||||
|
</form>
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
<th></th>
|
||||||
|
<th>
|
||||||
|
<form [formGroup]="filterForm">
|
||||||
|
<p-dropdown formControlName="level" [options]="levels" placeholder="{{'view.server.members.headers.level' | translate}}"></p-dropdown>
|
||||||
|
</form>
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="body" let-member let-editing="editing" let-ri="rowIndex">
|
||||||
|
<tr [pEditableRow]="member">
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{member.id}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{member.id}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{member.discordId}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{member.discordId}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{member.name}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{member.name}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
<input class="table-edit-input" pInputText type="number" [(ngModel)]="member.xp">
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{member.xp}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{member.ontime}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{member.ontime}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
<p-dropdown [options]="levels" [(ngModel)]="member.level" placeholder="{{'view.server.members.headers.level' | translate}}"></p-dropdown>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{member.level.name}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="btn-wrapper">
|
||||||
|
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil"
|
||||||
|
(click)="onRowEditInit(dt, member, ri)"></button>
|
||||||
|
|
||||||
|
<button *ngIf="editing" pButton pSaveEditableRow class="btn icon-btn"
|
||||||
|
icon="pi pi-check-circle" (click)="onRowEditSave(dt, member, ri)"></button>
|
||||||
|
<button *ngIf="editing" pButton pCancelEditableRow class="btn icon-btn danger-icon-btn"
|
||||||
|
icon="pi pi-times-circle" (click)="onRowEditCancel(member, ri)"></button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="emptymessage">
|
||||||
|
<tr></tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="7">{{'view.server.members.no_entries_found' | translate}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr></tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="paginatorleft">
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { MembersComponent } from './members.component';
|
||||||
|
|
||||||
|
describe('MembersComponent', () => {
|
||||||
|
let component: MembersComponent;
|
||||||
|
let fixture: ComponentFixture<MembersComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ MembersComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(MembersComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
235
kdb-web/src/app/modules/view/server/members/members.component.ts
Normal file
235
kdb-web/src/app/modules/view/server/members/members.component.ts
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
import { Component } from "@angular/core";
|
||||||
|
import { FormBuilder, FormControl, FormGroup } from "@angular/forms";
|
||||||
|
import { AuthService } from "../../../../services/auth/auth.service";
|
||||||
|
import { SpinnerService } from "../../../../services/spinner/spinner.service";
|
||||||
|
import { ToastService } from "../../../../services/toast/toast.service";
|
||||||
|
import { ConfirmationDialogService } from "../../../../services/confirmation-dialog/confirmation-dialog.service";
|
||||||
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { catchError, debounceTime } from "rxjs/operators";
|
||||||
|
import { LazyLoadEvent, MenuItem } from "primeng/api";
|
||||||
|
import { Table } from "primeng/table";
|
||||||
|
import { User, UserFilter } from "../../../../models/data/user.model";
|
||||||
|
import { Queries } from "../../../../models/graphql/queries.model";
|
||||||
|
import { LevelListQuery, UserListQuery } from "../../../../models/graphql/query.model";
|
||||||
|
import { DataService } from "../../../../services/data/data.service";
|
||||||
|
import { Page } from "../../../../models/graphql/filter/page.model";
|
||||||
|
import { Sort } from "../../../../models/graphql/filter/sort.model";
|
||||||
|
import { SidebarService } from "../../../../services/sidebar/sidebar.service";
|
||||||
|
import { Mutations } from "../../../../models/graphql/mutations.model";
|
||||||
|
import { throwError } from "rxjs";
|
||||||
|
import { UpdateUserMutationResult } from "../../../../models/graphql/result.model";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-members",
|
||||||
|
templateUrl: "./members.component.html",
|
||||||
|
styleUrls: ["./members.component.scss"]
|
||||||
|
})
|
||||||
|
export class MembersComponent {
|
||||||
|
members!: User[];
|
||||||
|
// levelsFilter!: MenuItem[];
|
||||||
|
levels!: MenuItem[];
|
||||||
|
loading = true;
|
||||||
|
|
||||||
|
clonedUsers: { [s: string]: User; } = {};
|
||||||
|
isEditingNew: boolean = false;
|
||||||
|
|
||||||
|
newUserTemplate: User = {
|
||||||
|
id: 0,
|
||||||
|
discordId: 0,
|
||||||
|
name: "",
|
||||||
|
xp: 0,
|
||||||
|
ontime: 0,
|
||||||
|
level: undefined,
|
||||||
|
server: undefined,
|
||||||
|
|
||||||
|
joinedServerCount: 0,
|
||||||
|
joinedServers: [],
|
||||||
|
|
||||||
|
joinedVoiceChannelCount: 0,
|
||||||
|
joinedVoiceChannels: [],
|
||||||
|
|
||||||
|
userJoinedGameServerCount: 0,
|
||||||
|
userJoinedGameServers: [],
|
||||||
|
|
||||||
|
createdAt: "",
|
||||||
|
modifiedAt: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
filterForm!: FormGroup<{
|
||||||
|
id: FormControl<number | null>,
|
||||||
|
discordId: FormControl<number | null>,
|
||||||
|
name: FormControl<string | null>,
|
||||||
|
level: FormControl<number | null>
|
||||||
|
}>;
|
||||||
|
|
||||||
|
filter: UserFilter = {
|
||||||
|
leftServer: false
|
||||||
|
};
|
||||||
|
page: Page = {
|
||||||
|
pageSize: undefined,
|
||||||
|
pageIndex: undefined
|
||||||
|
};
|
||||||
|
sort: Sort = {
|
||||||
|
sortColumn: undefined,
|
||||||
|
sortDirection: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
totalRecords!: number;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private authService: AuthService,
|
||||||
|
private spinner: SpinnerService,
|
||||||
|
private toastService: ToastService,
|
||||||
|
private confirmDialog: ConfirmationDialogService,
|
||||||
|
private fb: FormBuilder,
|
||||||
|
private translate: TranslateService,
|
||||||
|
private data: DataService,
|
||||||
|
private sidebar: SidebarService
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.spinner.showSpinner();
|
||||||
|
this.data.query<LevelListQuery>(Queries.levelQuery, {
|
||||||
|
filter: {
|
||||||
|
server: { id: this.sidebar.server$.value?.id }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).subscribe(data => {
|
||||||
|
this.levels = data.levels.map(level => {
|
||||||
|
return { label: level.name, value: level };
|
||||||
|
});
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setFilterForm();
|
||||||
|
this.loadNextPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
setFilterForm() {
|
||||||
|
this.filterForm = this.fb.group({
|
||||||
|
id: new FormControl<number | null>(null),
|
||||||
|
discordId: new FormControl<number | null>(null),
|
||||||
|
name: [""],
|
||||||
|
level: new FormControl<number | null>(null)
|
||||||
|
});
|
||||||
|
|
||||||
|
this.filterForm.valueChanges.pipe(
|
||||||
|
debounceTime(600)
|
||||||
|
).subscribe(changes => {
|
||||||
|
if (changes.id) {
|
||||||
|
this.filter.id = changes.id;
|
||||||
|
} else {
|
||||||
|
this.filter.id = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.discordId) {
|
||||||
|
this.filter.discordId = changes.discordId;
|
||||||
|
} else {
|
||||||
|
this.filter.discordId = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.name) {
|
||||||
|
this.filter.name = changes.name;
|
||||||
|
} else {
|
||||||
|
this.filter.name = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.level) {
|
||||||
|
this.filter.level = {
|
||||||
|
id: changes.level
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.filter.level = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.page.pageSize)
|
||||||
|
this.page.pageSize = 10;
|
||||||
|
|
||||||
|
if (this.page.pageIndex)
|
||||||
|
this.page.pageIndex = 0;
|
||||||
|
|
||||||
|
this.loadNextPage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadNextPage() {
|
||||||
|
this.loading = true;
|
||||||
|
this.data.query<UserListQuery>(Queries.usersQuery, {
|
||||||
|
filter: this.filter, page: this.page, sort: this.sort
|
||||||
|
}
|
||||||
|
).subscribe(data => {
|
||||||
|
this.totalRecords = data.userCount;
|
||||||
|
this.members = data.users;
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
nextPage(event: LazyLoadEvent) {
|
||||||
|
this.page.pageSize = event.rows ?? 0;
|
||||||
|
if (event.first != null && event.rows != null)
|
||||||
|
this.page.pageIndex = event.first / event.rows;
|
||||||
|
this.sort.sortColumn = event.sortField ?? undefined;
|
||||||
|
this.sort.sortDirection = event.sortOrder === 1 ? "asc" : event.sortOrder === -1 ? "desc" : "asc";
|
||||||
|
|
||||||
|
this.loadNextPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
resetFilters() {
|
||||||
|
this.filterForm.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
onRowEditInit(table: Table, user: User, index: number) {
|
||||||
|
this.clonedUsers[index] = { ...user };
|
||||||
|
}
|
||||||
|
|
||||||
|
onRowEditSave(table: Table, newUser: User, index: number) {
|
||||||
|
// const oldUser = this.clonedUsers[index];
|
||||||
|
// delete this.clonedUsers[index];
|
||||||
|
|
||||||
|
// if (JSON.stringify(oldUser) === JSON.stringify(newUser) && !this.isEditingNew) {
|
||||||
|
// console.log(1, oldUser, newUser, JSON.stringify(oldUser) === JSON.stringify(newUser), !this.isEditingNew);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (this.isEditingNew && JSON.stringify(newUser) === JSON.stringify(this.newUserTemplate)) {
|
||||||
|
this.isEditingNew = false;
|
||||||
|
this.members.splice(index, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newUser.id || !newUser.xp && !newUser.level?.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.spinner.showSpinner();
|
||||||
|
this.data.mutation<UpdateUserMutationResult>(Mutations.updateUser, {
|
||||||
|
id: newUser.id,
|
||||||
|
xp: newUser.xp,
|
||||||
|
levelId: newUser.level?.id
|
||||||
|
}
|
||||||
|
).pipe(catchError(err => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.error(this.translate.instant("view.server.members.message.user_change_failed"), this.translate.instant("view.server.members.message.user_change_failed_d", { name: newUser.name }));
|
||||||
|
return throwError(err);
|
||||||
|
})).subscribe(_ => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.success(this.translate.instant("view.server.members.message.user_changed"), this.translate.instant("view.server.members.message.user_changed_d", { name: newUser.name }));
|
||||||
|
this.loadNextPage();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onRowEditCancel(user: User, index: number) {
|
||||||
|
if (this.isEditingNew) {
|
||||||
|
this.members.splice(index, 1);
|
||||||
|
delete this.clonedUsers[index];
|
||||||
|
this.isEditingNew = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.members[index] = this.clonedUsers[index];
|
||||||
|
delete this.clonedUsers[index];
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,12 @@ import { NgModule } from "@angular/core";
|
|||||||
import { RouterModule, Routes } from "@angular/router";
|
import { RouterModule, Routes } from "@angular/router";
|
||||||
import { ServerDashboardComponent } from "./server-dashboard/server-dashboard.component";
|
import { ServerDashboardComponent } from "./server-dashboard/server-dashboard.component";
|
||||||
import { ProfileComponent } from "./profile/profile.component";
|
import { ProfileComponent } from "./profile/profile.component";
|
||||||
|
import { MembersComponent } from "./members/members.component";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: '', component: ServerDashboardComponent },
|
{ path: '', component: ServerDashboardComponent },
|
||||||
{ path: 'profile', component: ProfileComponent },
|
{ path: 'profile', component: ProfileComponent },
|
||||||
|
{ path: 'members', component: MembersComponent },
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -4,13 +4,15 @@ import { ServerDashboardComponent } from './server-dashboard/server-dashboard.co
|
|||||||
import { ServerRoutingModule } from './server-routing.module';
|
import { ServerRoutingModule } from './server-routing.module';
|
||||||
import { SharedModule } from '../../shared/shared.module';
|
import { SharedModule } from '../../shared/shared.module';
|
||||||
import { ProfileComponent } from './profile/profile.component';
|
import { ProfileComponent } from './profile/profile.component';
|
||||||
|
import { MembersComponent } from './members/members.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
ServerDashboardComponent,
|
ServerDashboardComponent,
|
||||||
ProfileComponent
|
ProfileComponent,
|
||||||
|
MembersComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
@ -37,4 +37,14 @@ export class DataService {
|
|||||||
.pipe(map((d) => f ? f(d) : d));
|
.pipe(map((d) => f ? f(d) : d));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public mutation<T>(query: string, variables?: object, f?: Function): Observable<T> {
|
||||||
|
return this.http
|
||||||
|
.post<{ data: T }>(`${this.appsettings.getApiURL()}/api/graphql`, {
|
||||||
|
query: query,
|
||||||
|
variables: variables
|
||||||
|
})
|
||||||
|
.pipe(map((d) => d.data))
|
||||||
|
.pipe(map((d) => f ? f(d) : d));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
"first_name": "Vorname",
|
"first_name": "Vorname",
|
||||||
"last_name": "Nachname",
|
"last_name": "Nachname",
|
||||||
"e_mail": "E-Mail",
|
"e_mail": "E-Mail",
|
||||||
|
"auth_role": "Rolle",
|
||||||
"active": "Aktiv",
|
"active": "Aktiv",
|
||||||
"role": "Rolle",
|
"role": "Rolle",
|
||||||
"password": "Passwort",
|
"password": "Passwort",
|
||||||
@ -160,6 +161,29 @@
|
|||||||
"header": "Server",
|
"header": "Server",
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
"header": "Server dashboard"
|
"header": "Server dashboard"
|
||||||
|
},
|
||||||
|
"members": {
|
||||||
|
"header": "Mitglieder",
|
||||||
|
"of": "von",
|
||||||
|
"add": "Hinzufügen",
|
||||||
|
"reset_filters": "Filter zurücksetzen",
|
||||||
|
"members": "Mitgliedern",
|
||||||
|
"headers": {
|
||||||
|
"id": "ID",
|
||||||
|
"discord_id": "Discord ID",
|
||||||
|
"name": "Name",
|
||||||
|
"xp": "XP",
|
||||||
|
"ontime": "Ontime",
|
||||||
|
"level": "Level",
|
||||||
|
"actions": "Aktionen"
|
||||||
|
},
|
||||||
|
"no_entries_found": "Keine Einträge gefunden",
|
||||||
|
"message": {
|
||||||
|
"user_changed": "Benutzer geändert",
|
||||||
|
"user_changed_d": "Benutzer {{name}} erfolgreich geändert",
|
||||||
|
"user_change_failed": "Benutzer änderung fehlgeschlagen",
|
||||||
|
"user_change_failed_d": "Benutzer {{name}} konnte nicht geändert werden!"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"user-list": {},
|
"user-list": {},
|
||||||
|
@ -60,7 +60,7 @@ header {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
margin: 0px 5px 0px 0px;
|
margin: 0 5px 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-menu-overlay {
|
.p-menu-overlay {
|
||||||
@ -122,7 +122,7 @@ header {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin: 1.5px 0px;
|
margin: 1.5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-column {
|
.content-column {
|
||||||
@ -147,7 +147,7 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content-divider {
|
.content-divider {
|
||||||
margin: 5px 0px;
|
margin: 5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-input-field {
|
.content-input-field {
|
||||||
@ -165,7 +165,7 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input-field-info-text {
|
.input-field-info-text {
|
||||||
margin: 15px 0px;
|
margin: 15px 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,6 +212,10 @@ header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-header-small {
|
||||||
|
width: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
.table-header-actions {
|
.table-header-actions {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
@ -260,7 +264,7 @@ header {
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
margin: 0px;
|
margin: 0;
|
||||||
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -287,7 +291,7 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.p-dialog-footer {
|
.p-dialog-footer {
|
||||||
padding: 0px 20px 20px 20px !important;
|
padding: 0 20px 20px 20px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-dialog-content {
|
.p-dialog-content {
|
||||||
@ -295,7 +299,7 @@ header {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin: 1.5px 0px;
|
margin: 1.5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-column {
|
.content-column {
|
||||||
@ -320,7 +324,7 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content-divider {
|
.content-divider {
|
||||||
margin: 5px 0px;
|
margin: 5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-input-field {
|
.content-input-field {
|
||||||
@ -332,7 +336,7 @@ header {
|
|||||||
footer {
|
footer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: $footerHeight;
|
height: $footerHeight;
|
||||||
padding: 0px 10px;
|
padding: 0 10px;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -347,7 +351,7 @@ footer {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
.version-divider {
|
.version-divider {
|
||||||
margin: 0px 5px;
|
margin: 0 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// .backend-version {
|
// .backend-version {
|
||||||
@ -394,7 +398,7 @@ footer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input-field-info-text {
|
.input-field-info-text {
|
||||||
margin: 15px 0px;
|
margin: 15px 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,7 +439,7 @@ footer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input-field {
|
.input-field {
|
||||||
margin: 15px 0px;
|
margin: 15px 0;
|
||||||
|
|
||||||
input,
|
input,
|
||||||
.p-password {
|
.p-password {
|
||||||
|
@ -11,15 +11,15 @@
|
|||||||
background: none !important;
|
background: none !important;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
width: auto !important;
|
width: auto !important;
|
||||||
border-radius: 0px !important;
|
border-radius: 0 !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
|
|
||||||
.p-menuitem-link,
|
.p-menuitem-link,
|
||||||
.p-panelmenu-header > a,
|
.p-panelmenu-header > a,
|
||||||
.p-panelmenu-content .p-menuitem .p-menuitem-link {
|
.p-panelmenu-content .p-menuitem .p-menuitem-link {
|
||||||
$distance: 10px;
|
$distance: 10px;
|
||||||
padding: $distance 0px $distance $distance !important;
|
padding: $distance 0 $distance $distance !important;
|
||||||
margin: 4px 0px 4px 6px !important;
|
margin: 4px 0 4px 6px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,8 +44,8 @@ header,
|
|||||||
|
|
||||||
.p-panelmenu-header > a {
|
.p-panelmenu-header > a {
|
||||||
border: none !important;
|
border: none !important;
|
||||||
border-radius: none !important;
|
border-radius: unset !important;
|
||||||
font-weight: none !important;
|
font-weight: unset !important;
|
||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,8 +71,12 @@ ui-menu .ui-menu-parent .ui-menu-child {
|
|||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-datatable > .p-datatable-wrapper {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
.p-password {
|
.p-password {
|
||||||
padding: 0px !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-paginator {
|
.p-paginator {
|
||||||
|
Loading…
Reference in New Issue
Block a user