Guild & Level can be null
All checks were successful
Deploy prod on push / pre-build (push) Successful in 2s
Deploy prod on push / build-bot (push) Successful in 3m19s
Deploy prod on push / build-web (push) Successful in 1m58s
Deploy prod on push / deploy (push) Successful in 23s

This commit is contained in:
Sven Heidemann 2024-09-06 19:39:50 +02:00
parent b361a7b685
commit e785bddf2e
17 changed files with 250 additions and 195 deletions

View File

@ -1,4 +1,5 @@
from datetime import datetime from datetime import datetime
from typing import Optional
from cpl_core.database import TableABC from cpl_core.database import TableABC
from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.dependency_injection import ServiceProviderABC
@ -48,8 +49,10 @@ class AutoRoleRule(TableABC):
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def role_name(self, bot: DiscordBotServiceABC) -> str: def role_name(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self.auto_role.server.discord_id) guild = bot.get_guild(self.auto_role.server.discord_id)
if guild is None:
return None
return guild.get_role(self.role_id).name return guild.get_role(self.role_id).name
@role_id.setter @role_id.setter

View File

@ -1,3 +1,5 @@
from typing import Optional
from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.dependency_injection import ServiceProviderABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
@ -43,6 +45,8 @@ class AutoRoleRuleHistory(HistoryTableABC):
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def role_name(self, bot: DiscordBotServiceABC) -> str: def role_name(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self.auto_role.server.discord_id) guild = bot.get_guild(self.auto_role.server.discord_id)
if guild is None:
return None
return guild.get_role(self.role_id).name return guild.get_role(self.role_id).name

View File

@ -39,8 +39,10 @@ class Level(TableABC):
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def icon_url(self, bot: DiscordBotServiceABC) -> str: def icon_url(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self.server.discord_id) guild = bot.get_guild(self.server.discord_id)
if guild is None:
return None
role = List(Role, guild.roles).where(lambda x: x.name == self._name).first_or_default() role = List(Role, guild.roles).where(lambda x: x.name == self._name).first_or_default()
return None if role is None else role.icon return None if role is None else role.icon

View File

@ -1,4 +1,5 @@
from datetime import datetime from datetime import datetime
from typing import Optional
from cpl_core.database import TableABC from cpl_core.database import TableABC
from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.dependency_injection import ServiceProviderABC
@ -30,14 +31,18 @@ class Server(TableABC):
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def name(self, bot: DiscordBotServiceABC) -> str: def name(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self.discord_id) guild = bot.get_guild(self.discord_id)
if guild is None:
return None
return None if guild is None else guild.name return None if guild is None else guild.name
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def icon_url(self, bot: DiscordBotServiceABC) -> str: def icon_url(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self.discord_id) guild = bot.get_guild(self.discord_id)
if guild is None:
return None
return None if guild is None else guild.icon.url return None if guild is None else guild.icon.url
@staticmethod @staticmethod

View File

@ -1,3 +1,5 @@
from typing import Optional
from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.dependency_injection import ServiceProviderABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
@ -32,12 +34,16 @@ class ServerHistory(HistoryTableABC):
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def name(self, bot: DiscordBotServiceABC) -> str: def name(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self.discord_id) guild = bot.get_guild(self.discord_id)
if guild is None:
return None
return None if guild is None else guild.name return None if guild is None else guild.name
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def icon_url(self, bot: DiscordBotServiceABC) -> str: def icon_url(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self.discord_id) guild = bot.get_guild(self.discord_id)
if guild is None:
return None
return None if guild is None else guild.icon.url return None if guild is None else guild.icon.url

View File

@ -1,4 +1,5 @@
from datetime import datetime from datetime import datetime
from typing import Optional
from cpl_core.database import TableABC from cpl_core.database import TableABC
from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.dependency_injection import ServiceProviderABC
@ -51,8 +52,10 @@ class ShortRoleName(TableABC):
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def role_name(self, bot: DiscordBotServiceABC) -> str: def role_name(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self._server.discord_id) guild = bot.get_guild(self._server.discord_id)
if guild is None:
return None
return guild.get_role(self.role_id).name return guild.get_role(self.role_id).name
@property @property

View File

@ -1,3 +1,5 @@
from typing import Optional
from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.dependency_injection import ServiceProviderABC
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
@ -47,8 +49,10 @@ class ShortRoleNameHistory(HistoryTableABC):
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def role_name(self, bot: DiscordBotServiceABC) -> str: def role_name(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self._server.discord_id) guild = bot.get_guild(self._server.discord_id)
if guild is None:
return None
return guild.get_role(self.role_id).name return guild.get_role(self.role_id).name
@property @property

View File

@ -53,15 +53,19 @@ class User(TableABC):
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def name(self, bot: DiscordBotServiceABC) -> str: def name(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self.server.discord_id) guild = bot.get_guild(self.server.discord_id)
if guild is None:
return None
user = guild.get_member(self.discord_id) user = guild.get_member(self.discord_id)
return None if user is None else user.name return None if user is None else user.name
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def icon_url(self, bot: DiscordBotServiceABC) -> str: def icon_url(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self.server.discord_id) guild = bot.get_guild(self.server.discord_id)
if guild is None:
return None
user = guild.get_member(self.discord_id) user = guild.get_member(self.discord_id)
return None if user is None else user.display_icon return None if user is None else user.display_icon
@ -137,7 +141,7 @@ class User(TableABC):
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def level(self, services: ServiceProviderABC) -> Level: def level(self, services: ServiceProviderABC) -> Optional[Level]:
from modules.level.service.level_service import LevelService from modules.level.service.level_service import LevelService
levels: LevelService = services.get_service(LevelService) levels: LevelService = services.get_service(LevelService)
@ -175,8 +179,10 @@ class User(TableABC):
@property @property
@ServiceProviderABC.inject @ServiceProviderABC.inject
def profile_picture_url(self, bot: DiscordBotServiceABC) -> str: def profile_picture_url(self, bot: DiscordBotServiceABC) -> Optional[str]:
guild = bot.get_guild(self.server.discord_id) guild = bot.get_guild(self.server.discord_id)
if guild is None:
return None
user = guild.get_member(self._discord_id) user = guild.get_member(self._discord_id)
return None if user is None or user.avatar is None else user.avatar.url return None if user is None or user.avatar is None else user.avatar.url

View File

@ -51,6 +51,8 @@ class AutoRoleRuleFilter(FilterABC):
def get_role_name(x: AutoRoleRule): def get_role_name(x: AutoRoleRule):
guild = self._bot.get_guild(x.auto_role.server.discord_id) guild = self._bot.get_guild(x.auto_role.server.discord_id)
if guild is None:
return False
name = guild.get_role(x.role_id).name name = guild.get_role(x.role_id).name
return name == self._role_name or self._role_name in name return name == self._role_name or self._role_name in name

View File

@ -57,6 +57,8 @@ class ShortRoleNameFilter(FilterABC):
def get_role_name(x: ShortRoleName): def get_role_name(x: ShortRoleName):
guild = self._bot.get_guild(x.server.discord_id) guild = self._bot.get_guild(x.server.discord_id)
if guild is None:
return False
name = guild.get_role(x.role_id).name name = guild.get_role(x.role_id).name
return name == self._role_name or self._role_name in name return name == self._role_name or self._role_name in name

View File

@ -80,6 +80,8 @@ class UserFilter(FilterABC):
def _get_member(user: User): def _get_member(user: User):
guild = self._bot.get_guild(user.server.discord_id) guild = self._bot.get_guild(user.server.discord_id)
if guild is None:
return False
member = guild.get_member(user.discord_id) member = guild.get_member(user.discord_id)
return member is not None and (member.name == self._name or self._name in member.name) return member is not None and (member.name == self._name or self._name in member.name)

View File

@ -8,7 +8,6 @@ from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
from bot_data.abc.client_repository_abc import ClientRepositoryABC from bot_data.abc.client_repository_abc import ClientRepositoryABC
from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC
from bot_data.abc.level_repository_abc import LevelRepositoryABC
from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC
@ -31,6 +30,7 @@ from bot_graphql.filter.short_role_name_filter import ShortRoleNameFilter
from bot_graphql.filter.user_filter import UserFilter from bot_graphql.filter.user_filter import UserFilter
from bot_graphql.filter.user_warning_filter import UserWarningFilter from bot_graphql.filter.user_warning_filter import UserWarningFilter
from bot_graphql.model.server_statistics import ServerStatistics from bot_graphql.model.server_statistics import ServerStatistics
from modules.level.service.level_service import LevelService
class ServerQuery(DataQueryWithHistoryABC): class ServerQuery(DataQueryWithHistoryABC):
@ -41,7 +41,7 @@ class ServerQuery(DataQueryWithHistoryABC):
db: DatabaseContextABC, db: DatabaseContextABC,
auto_roles: AutoRoleRepositoryABC, auto_roles: AutoRoleRepositoryABC,
clients: ClientRepositoryABC, clients: ClientRepositoryABC,
levels: LevelRepositoryABC, levels: LevelService,
game_servers: GameServerRepositoryABC, game_servers: GameServerRepositoryABC,
users: UserRepositoryABC, users: UserRepositoryABC,
ujs: UserJoinedServerRepositoryABC, ujs: UserJoinedServerRepositoryABC,

View File

@ -1,9 +1,12 @@
from typing import Optional
import discord import discord
from cpl_core.configuration import ConfigurationABC from cpl_core.configuration import ConfigurationABC
from cpl_core.database.context import DatabaseContextABC from cpl_core.database.context import DatabaseContextABC
from cpl_core.logging import LoggerABC from cpl_core.logging import LoggerABC
from cpl_discord.container import Guild, Role, Member from cpl_discord.container import Guild, Role, Member
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
from cpl_query.extension import List
from cpl_translation import TranslatePipe from cpl_translation import TranslatePipe
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
@ -40,13 +43,26 @@ class LevelService:
self._message_service = message_service self._message_service = message_service
self._t = t self._t = t
def _check_for_feature(self, user: User): def _check_for_feature(self, discord_id: int):
server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{user.server.discord_id}") server_config: ServerConfig = self._config.get_configuration(f"ServerConfig_{discord_id}")
if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module): if not FeatureFlagsSettings.get_flag_from_dict(server_config.feature_flags, FeatureFlagsEnum.level_module):
raise Exception(f"Feature {FeatureFlagsEnum.level_module.value} disabled") raise Exception(f"Feature {FeatureFlagsEnum.level_module.value} disabled")
def get_level(self, user: User) -> Level: def get_levels_by_server_id(self, server_id: int) -> List[Level]:
self._check_for_feature(user) try:
self._check_for_feature(self._servers.get_server_by_id(server_id).discord_id)
except Exception as e:
self._logger.warn(__name__, f"Feature {FeatureFlagsEnum.level_module.value} disabled\n{e}")
return List(Level)
return self._levels.get_levels()
def get_level(self, user: User) -> Optional[Level]:
try:
self._check_for_feature(user.server.discord_id)
except Exception as e:
self._logger.warn(__name__, f"Feature {FeatureFlagsEnum.level_module.value} disabled\n{e}")
return None
levels_by_server = self._levels.get_levels_by_server_id(user.server.id) levels_by_server = self._levels.get_levels_by_server_id(user.server.id)
if user.xp < 0: if user.xp < 0:
@ -60,7 +76,7 @@ class LevelService:
return levels.last() return levels.last()
async def set_level(self, user: User): async def set_level(self, user: User):
self._check_for_feature(user) self._check_for_feature(user.server.discord_id)
level_names = self._levels.get_levels_by_server_id(user.server.id).select(lambda l: l.name) level_names = self._levels.get_levels_by_server_id(user.server.id).select(lambda l: l.name)
guild: Guild = self._bot.guilds.where(lambda g: g.id == user.server.discord_id).single() guild: Guild = self._bot.guilds.where(lambda g: g.id == user.server.discord_id).single()
member: Member = guild.members.where(lambda m: m.id == user.discord_id).single() member: Member = guild.members.where(lambda m: m.id == user.discord_id).single()

View File

@ -1,56 +1,56 @@
{ {
"name": "web", "name": "web",
"version": "1.2.7", "version": "1.2.7",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"update-version": "ts-node update-version.ts", "update-version": "ts-node update-version.ts",
"prestart": "npm run update-version", "prestart": "npm run update-version",
"start": "ng serve", "start": "ng serve",
"prebuild": "npm run update-version", "prebuild": "npm run update-version",
"build": "ng build", "build": "ng build",
"watch": "ng build --watch --configuration development", "watch": "ng build --watch --configuration development",
"test": "ng test", "test": "ng test",
"gv": "echo $npm_package_version", "gv": "echo $npm_package_version",
"predocker-build": "npm run update-version", "predocker-build": "npm run update-version",
"docker-build": "export VERSION=$npm_package_version; ng build; docker build -t sh-edraft.de/sdb-web:$VERSION .", "docker-build": "export VERSION=$npm_package_version; ng build; docker build -t sh-edraft.de/sdb-web:$VERSION .",
"docker-build-dev": "export VERSION=$npm_package_version; ng build --configuration development; docker build -t sh-edraft.de/sdb-web:$VERSION .", "docker-build-dev": "export VERSION=$npm_package_version; ng build --configuration development; docker build -t sh-edraft.de/sdb-web:$VERSION .",
"docker-build-stage": "export VERSION=$npm_package_version; ng build --configuration staging; docker build -t sh-edraft.de/sdb-web:$VERSION ." "docker-build-stage": "export VERSION=$npm_package_version; ng build --configuration staging; docker build -t sh-edraft.de/sdb-web:$VERSION ."
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "^15.1.4", "@angular/animations": "^15.1.4",
"@angular/common": "^15.1.4", "@angular/common": "^15.1.4",
"@angular/compiler": "^15.1.4", "@angular/compiler": "^15.1.4",
"@angular/core": "^15.1.4", "@angular/core": "^15.1.4",
"@angular/forms": "^15.1.4", "@angular/forms": "^15.1.4",
"@angular/platform-browser": "^15.1.4", "@angular/platform-browser": "^15.1.4",
"@angular/platform-browser-dynamic": "^15.1.4", "@angular/platform-browser-dynamic": "^15.1.4",
"@angular/router": "^15.1.4", "@angular/router": "^15.1.4",
"@auth0/angular-jwt": "^5.1.0", "@auth0/angular-jwt": "^5.1.0",
"@microsoft/signalr": "^6.0.9", "@microsoft/signalr": "^6.0.9",
"@ngx-translate/core": "^14.0.0", "@ngx-translate/core": "^14.0.0",
"@ngx-translate/http-loader": "^7.0.0", "@ngx-translate/http-loader": "^7.0.0",
"@types/socket.io-client": "^3.0.0", "@types/socket.io-client": "^3.0.0",
"moment": "^2.29.4", "moment": "^2.29.4",
"primeicons": "^6.0.1", "primeicons": "^6.0.1",
"primeng": "^15.2.0", "primeng": "^15.2.0",
"rxjs": "~7.5.0", "rxjs": "~7.5.0",
"socket.io-client": "^4.5.3", "socket.io-client": "^4.5.3",
"zone.js": "~0.11.4" "zone.js": "~0.11.4"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "^15.1.5", "@angular-devkit/build-angular": "^15.1.5",
"@angular/cli": "~15.1.5", "@angular/cli": "~15.1.5",
"@angular/compiler-cli": "^15.1.4", "@angular/compiler-cli": "^15.1.4",
"@types/jasmine": "~4.0.0", "@types/jasmine": "~4.0.0",
"@types/node": "^18.11.9", "@types/node": "^18.11.9",
"jasmine-core": "~4.1.0", "jasmine-core": "~4.1.0",
"karma": "~6.3.0", "karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0", "karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.2.0", "karma-coverage": "~2.2.0",
"karma-jasmine": "~5.0.0", "karma-jasmine": "~5.0.0",
"karma-jasmine-html-reporter": "~1.7.0", "karma-jasmine-html-reporter": "~1.7.0",
"tslib": "^2.4.1", "tslib": "^2.4.1",
"typescript": "~4.9.5" "typescript": "~4.9.5"
} }
} }

View File

@ -1,5 +1,5 @@
<h1> <h1>
{{'view.server.members.header' | translate}} {{ 'view.server.members.header' | translate }}
</h1> </h1>
<div class="content-wrapper"> <div class="content-wrapper">
<div class="content"> <div class="content">
@ -12,10 +12,10 @@
<div class="table-caption"> <div class="table-caption">
<div class="table-caption-table-info"> <div class="table-caption-table-info">
<div class="table-caption-text"> <div class="table-caption-text">
<ng-container *ngIf="!loading">{{members.length}} {{'common.of' | translate}} <ng-container *ngIf="!loading">{{ members.length }} {{ 'common.of' | translate }}
{{dt.totalRecords}} {{ dt.totalRecords }}
</ng-container> </ng-container>
{{'view.server.members.members' | translate}} {{ 'view.server.members.members' | translate }}
</div> </div>
<app-multi-select-columns [table]="name" [columns]="columns" <app-multi-select-columns [table]="name" [columns]="columns"
@ -34,82 +34,82 @@
<tr> <tr>
<th hideable-th="id" [parent]="this" [sortable]="true"> <th hideable-th="id" [parent]="this" [sortable]="true">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.id' | translate}}</div> <div class="table-header-text">{{ 'common.id' | translate }}</div>
<p-sortIcon field="id" class="table-header-icon"></p-sortIcon> <p-sortIcon field="id" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th hideable-th="discord_id" [parent]="this" [sortable]="true"> <th hideable-th="discord_id" [parent]="this" [sortable]="true">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.discord_id' | translate}}</div> <div class="table-header-text">{{ 'common.discord_id' | translate }}</div>
<p-sortIcon field="discordId" class="table-header-icon"></p-sortIcon> <p-sortIcon field="discordId" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th hideable-th="name" [parent]="this" [sortable]="true"> <th hideable-th="name" [parent]="this" [sortable]="true">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.name' | translate}}</div> <div class="table-header-text">{{ 'common.name' | translate }}</div>
<p-sortIcon field="name" class="table-header-icon"></p-sortIcon> <p-sortIcon field="name" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th hideable-th="xp" [parent]="this" [sortable]="true"> <th hideable-th="xp" [parent]="this" [sortable]="true">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.xp' | translate}}</div> <div class="table-header-text">{{ 'common.xp' | translate }}</div>
<p-sortIcon field="xp" class="table-header-icon"></p-sortIcon> <p-sortIcon field="xp" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th hideable-th="ontime" [parent]="this" [sortable]="true"> <th hideable-th="ontime" [parent]="this" [sortable]="true">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.ontime' | translate}}</div> <div class="table-header-text">{{ 'common.ontime' | translate }}</div>
<p-sortIcon field="ontime" class="table-header-icon"></p-sortIcon> <p-sortIcon field="ontime" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th hideable-th="game_ontime" [parent]="this" [sortable]="true"> <th hideable-th="game_ontime" [parent]="this" [sortable]="true">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.game_ontime' | translate}}</div> <div class="table-header-text">{{ 'common.game_ontime' | translate }}</div>
<p-sortIcon field="game_ontime" class="table-header-icon"></p-sortIcon> <p-sortIcon field="game_ontime" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th hideable-th="activity" [parent]="this" [sortable]="true"> <th hideable-th="activity" [parent]="this" [sortable]="true">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.activity' | translate}}</div> <div class="table-header-text">{{ 'common.activity' | translate }}</div>
<p-sortIcon field="activityScore" class="table-header-icon"></p-sortIcon> <p-sortIcon field="activityScore" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th hideable-th="left_server" [parent]="this" [sortable]="true"> <th hideable-th="left_server" [parent]="this" [sortable]="true">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.left_server' | translate}}</div> <div class="table-header-text">{{ 'common.left_server' | translate }}</div>
<p-sortIcon field="leftServer" class="table-header-icon"></p-sortIcon> <p-sortIcon field="leftServer" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th hideable-th="level" subColumn="level.min_xp" [parent]="this" [sortable]="true"> <th hideable-th="level" subColumn="level.min_xp" [parent]="this" [sortable]="true">
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.level' | translate}}</div> <div class="table-header-text">{{ 'common.level' | translate }}</div>
<p-sortIcon field="level" class="table-header-icon"></p-sortIcon> <p-sortIcon field="level" class="table-header-icon"></p-sortIcon>
</div> </div>
</th> </th>
<th> <th>
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.created_at' | translate}}</div> <div class="table-header-text">{{ 'common.created_at' | translate }}</div>
</div> </div>
</th> </th>
<th> <th>
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.modified_at' | translate}}</div> <div class="table-header-text">{{ 'common.modified_at' | translate }}</div>
</div> </div>
</th> </th>
<th> <th>
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.actions' | translate}}</div> <div class="table-header-text">{{ 'common.actions' | translate }}</div>
</div> </div>
</th> </th>
</tr> </tr>
@ -156,124 +156,124 @@
<ng-template pTemplate="body" let-member let-editing="editing" let-ri="rowIndex"> <ng-template pTemplate="body" let-member let-editing="editing" let-ri="rowIndex">
<tr [pEditableRow]="member"> <tr [pEditableRow]="member">
<td hideable-th="id" [parent]="this"> <td hideable-th="id" [parent]="this">
<span class="p-column-title">{{'common.id' | translate}}:</span> <span class="p-column-title">{{ 'common.id' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
{{member.id}} {{ member.id }}
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{member.id}} {{ member.id }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td hideable-th="discord_id" [parent]="this"> <td hideable-th="discord_id" [parent]="this">
<span class="p-column-title">{{'common.discord_id' | translate}}:</span> <span class="p-column-title">{{ 'common.discord_id' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
{{member.discordId}} {{ member.discordId }}
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{member.discordId}} {{ member.discordId }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td hideable-th="name" [parent]="this"> <td hideable-th="name" [parent]="this">
<span class="p-column-title">{{'common.name' | translate}}:</span> <span class="p-column-title">{{ 'common.name' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
{{member.name}} {{ member.name }}
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{member.name}} {{ member.name }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td hideable-th="xp" [parent]="this"> <td hideable-th="xp" [parent]="this">
<span class="p-column-title">{{'common.xp' | translate}}:</span> <span class="p-column-title">{{ 'common.xp' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
<input class="table-edit-input" pInputText min="0" type="number" [(ngModel)]="member.xp"> <input class="table-edit-input" pInputText min="0" type="number" [(ngModel)]="member.xp">
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{member.xp}} {{ member.xp }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td hideable-th="ontime" [parent]="this"> <td hideable-th="ontime" [parent]="this">
<span class="p-column-title">{{'common.ontime' | translate}}:</span> <span class="p-column-title">{{ 'common.ontime' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
{{member.ontime}} {{ member.ontime }}
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{member.ontime}} {{ member.ontime }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td hideable-th="game_ontime" [parent]="this"> <td hideable-th="game_ontime" [parent]="this">
<span class="p-column-title">{{'common.game_ontime' | translate}}:</span> <span class="p-column-title">{{ 'common.game_ontime' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
{{member.gameOntime}} {{ member.gameOntime }}
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{member.gameOntime}} {{ member.gameOntime }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td hideable-th="activity" [parent]="this"> <td hideable-th="activity" [parent]="this">
<span class="p-column-title">{{'common.activity' | translate}}:</span> <span class="p-column-title">{{ 'common.activity' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
{{member.activityScore}} {{ member.activityScore }}
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{member.activityScore}} {{ member.activityScore }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td hideable-th="left_server" [parent]="this"> <td hideable-th="left_server" [parent]="this">
<span class="p-column-title">{{'common.left_server' | translate}}:</span> <span class="p-column-title">{{ 'common.left_server' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
{{!member.leftServer | bool}} {{ !member.leftServer | bool }}
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{!member.leftServer | bool}} {{ !member.leftServer | bool }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td hideable-th="level" [parent]="this"> <td hideable-th="level" [parent]="this">
<span class="p-column-title">{{'common.level' | translate}}:</span> <span class="p-column-title">{{ 'common.level' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
<p-dropdown [options]="levels" [(ngModel)]="member.level" dataKey="id" <p-dropdown [options]="levels" [(ngModel)]="member.level" dataKey="id"
placeholder="{{'common.level' | translate}}"></p-dropdown> placeholder="{{'common.level' | translate}}"></p-dropdown>
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{member.level.name}} {{ member.level?.name }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td> <td>
<span class="p-column-title">{{'common.created_at' | translate}}:</span> <span class="p-column-title">{{ 'common.created_at' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
{{member.createdAt | date:'dd.MM.yy HH:mm'}} {{ member.createdAt | date:'dd.MM.yy HH:mm' }}
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{member.createdAt | date:'dd.MM.yy HH:mm'}} {{ member.createdAt | date:'dd.MM.yy HH:mm' }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td> <td>
<span class="p-column-title">{{'common.modified_at' | translate}}:</span> <span class="p-column-title">{{ 'common.modified_at' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
{{member.modifiedAt | date:'dd.MM.yy HH:mm'}} {{ member.modifiedAt | date:'dd.MM.yy HH:mm' }}
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{member.modifiedAt | date:'dd.MM.yy HH:mm'}} {{ member.modifiedAt | date:'dd.MM.yy HH:mm' }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
@ -298,7 +298,7 @@
<ng-template pTemplate="emptymessage"> <ng-template pTemplate="emptymessage">
<tr></tr> <tr></tr>
<tr> <tr>
<td colspan="10">{{'common.no_entries_found' | translate}}</td> <td colspan="10">{{ 'common.no_entries_found' | translate }}</td>
</tr> </tr>
<tr></tr> <tr></tr>
</ng-template> </ng-template>

View File

@ -1,5 +1,5 @@
<h1> <h1>
{{'view.server.profile.header' | translate}} {{ 'view.server.profile.header' | translate }}
</h1> </h1>
<div class="content-wrapper"> <div class="content-wrapper">
<div class="content"> <div class="content">
@ -11,27 +11,27 @@
</div> </div>
<div class="content"> <div class="content">
<div class="content-column"> <div class="content-column">
<h1>{{user.name}}</h1> <h1>{{ user.name }}</h1>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.id' | translate}}:</div> <div class="content-data-name">{{ 'common.id' | translate }}:</div>
<div class="content-data-value">{{user.id}}</div> <div class="content-data-value">{{ user.id }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.discord_id' | translate}}:</div> <div class="content-data-name">{{ 'common.discord_id' | translate }}:</div>
<div class="content-data-value">{{user.discordId}}</div> <div class="content-data-value">{{ user.discordId }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'view.server.profile.message_count' | translate}}:</div> <div class="content-data-name">{{ 'view.server.profile.message_count' | translate }}:</div>
<div class="content-data-value">{{user.messageCount}}</div> <div class="content-data-value">{{ user.messageCount }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'view.server.profile.reaction_count' | translate}}:</div> <div class="content-data-name">{{ 'view.server.profile.reaction_count' | translate }}:</div>
<div class="content-data-value">{{user.reactionCount}}</div> <div class="content-data-value">{{ user.reactionCount }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'view.server.profile.birthday' | translate}}:</div> <div class="content-data-name">{{ 'view.server.profile.birthday' | translate }}:</div>
<div *ngIf="!isEditing" class="content-data-value">{{user.birthday}}</div> <div *ngIf="!isEditing" class="content-data-value">{{ user.birthday }}</div>
<div *ngIf="isEditing" class="content-data-value"> <div *ngIf="isEditing" class="content-data-value">
<p-calendar [(ngModel)]="user.birthday" dateFormat="dd.mm.yy" <p-calendar [(ngModel)]="user.birthday" dateFormat="dd.mm.yy"
[showIcon]="true"></p-calendar> [showIcon]="true"></p-calendar>
@ -39,16 +39,16 @@
</div> </div>
<div class="content-divider"></div> <div class="content-divider"></div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'view.server.profile.left_server' | translate}}:</div> <div class="content-data-name">{{ 'view.server.profile.left_server' | translate }}:</div>
<div class="content-data-value">{{user.leftServer | bool}}</div> <div class="content-data-value">{{ user.leftServer | bool }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.created_at' | translate}}:</div> <div class="content-data-name">{{ 'common.created_at' | translate }}:</div>
<div class="content-data-value">{{user.createdAt | date:'dd.MM.yyyy HH:mm:ss'}}</div> <div class="content-data-value">{{ user.createdAt | date:'dd.MM.yyyy HH:mm:ss' }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.modified_at' | translate}}:</div> <div class="content-data-name">{{ 'common.modified_at' | translate }}:</div>
<div class="content-data-value">{{user.modifiedAt | date:'dd.MM.yyyy HH:mm:ss'}}</div> <div class="content-data-value">{{ user.modifiedAt | date:'dd.MM.yyyy HH:mm:ss' }}</div>
</div> </div>
</div> </div>
<div class="content"> <div class="content">
@ -68,22 +68,22 @@
[readonly]="isModerator && !isEditing"></p-knob> [readonly]="isModerator && !isEditing"></p-knob>
<div *ngIf="user.level"> <div *ngIf="user.level">
{{user.level.name}} {{ user.level.name }}
</div> </div>
</div> </div>
</div> </div>
<div class="content-divider"></div> <div class="content-divider"></div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.ontime' | translate}}:</div> <div class="content-data-name">{{ 'common.ontime' | translate }}:</div>
<div class="content-data-value">{{user.ontime}}</div> <div class="content-data-value">{{ user.ontime }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.game_ontime' | translate}}:</div> <div class="content-data-name">{{ 'common.game_ontime' | translate }}:</div>
<div class="content-data-value">{{user.gameOntime}}</div> <div class="content-data-value">{{ user.gameOntime }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.activity' | translate}}:</div> <div class="content-data-name">{{ 'common.activity' | translate }}:</div>
<div class="content-data-value">{{user.activityScore}}</div> <div class="content-data-value">{{ user.activityScore }}</div>
</div> </div>
</div> </div>
</div> </div>
@ -99,7 +99,7 @@
<div class="table-caption"> <div class="table-caption">
<div class="table-caption-table-info"> <div class="table-caption-table-info">
<div class="table-caption-text"> <div class="table-caption-text">
<h3>{{'common.user_warnings' | translate}}</h3> <h3>{{ 'common.user_warnings' | translate }}</h3>
</div> </div>
</div> </div>
<div class="table-caption-btn-wrapper btn-wrapper"> <div class="table-caption-btn-wrapper btn-wrapper">
@ -113,25 +113,25 @@
<tr> <tr>
<th> <th>
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.description' | translate}}</div> <div class="table-header-text">{{ 'common.description' | translate }}</div>
</div> </div>
</th> </th>
<th> <th>
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.author' | translate}}</div> <div class="table-header-text">{{ 'common.author' | translate }}</div>
</div> </div>
</th> </th>
<th> <th>
<div class="table-header-label"> <div class="table-header-label">
<div class="table-header-text">{{'common.created_at' | translate}}</div> <div class="table-header-text">{{ 'common.created_at' | translate }}</div>
</div> </div>
</th> </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">{{'common.actions' | translate}}</div> <div class="table-header-text">{{ 'common.actions' | translate }}</div>
</div> </div>
</th> </th>
</tr> </tr>
@ -144,29 +144,29 @@
<input class="table-edit-input" pInputText type="text" [(ngModel)]="value.description"> <input class="table-edit-input" pInputText type="text" [(ngModel)]="value.description">
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{value.description}} {{ value.description }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td> <td>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
{{value.author?.name}} {{ value.author?.name }}
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{value.author?.name}} {{ value.author?.name }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
<td> <td>
<span class="p-column-title">{{'common.created_at' | translate}}:</span> <span class="p-column-title">{{ 'common.created_at' | translate }}:</span>
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
{{value.createdAt | date:'dd.MM.yy HH:mm'}} {{ value.createdAt | date:'dd.MM.yy HH:mm' }}
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{value.createdAt | date:'dd.MM.yy HH:mm'}} {{ value.createdAt | date:'dd.MM.yy HH:mm' }}
</ng-template> </ng-template>
</p-cellEditor> </p-cellEditor>
</td> </td>
@ -196,18 +196,18 @@
<div *ngFor="let achievement of user.achievements;"> <div *ngFor="let achievement of user.achievements;">
<div class="content-row"> <div class="content-row">
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.name' | translate}}:</div> <div class="content-data-name">{{ 'common.name' | translate }}:</div>
<div class="content-data-value">{{achievement.name}}</div> <div class="content-data-value">{{ achievement.name }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.description' | translate}}:</div> <div class="content-data-name">{{ 'common.description' | translate }}:</div>
<div class="content-data-value">{{achievement.description}}</div> <div class="content-data-value">{{ achievement.description }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'view.server.profile.achievements.time' | translate}}:</div> <div class="content-data-name">{{ 'view.server.profile.achievements.time' | translate }}:</div>
<div class="content-data-value">{{achievement.createdAt | date:'dd.MM.yyyy HH:mm:ss'}}</div> <div class="content-data-value">{{ achievement.createdAt | date:'dd.MM.yyyy HH:mm:ss' }}</div>
</div> </div>
</div> </div>
</div> </div>
@ -219,30 +219,30 @@
<div *ngFor="let join of user.joinedVoiceChannels;"> <div *ngFor="let join of user.joinedVoiceChannels;">
<div class="content-row"> <div class="content-row">
<div class="content-column" style="flex: 0.3;"> <div class="content-column" style="flex: 0.3;">
<div class="content-data-name">{{'common.id' | translate}}:</div> <div class="content-data-name">{{ 'common.id' | translate }}:</div>
<div class="content-data-value">{{join.id}}</div> <div class="content-data-value">{{ join.id }}</div>
</div> </div>
<div class="content-column" style="flex: 0.75;"> <div class="content-column" style="flex: 0.75;">
<div class="content-data-name" <div class="content-data-name"
style="flex: 0.35;">{{'view.server.profile.joined_voice_channel.time' | translate}}: style="flex: 0.35;">{{ 'view.server.profile.joined_voice_channel.time' | translate }}:
</div> </div>
<div class="content-data-value">{{join.time}} {{'general.hours' | translate}}</div> <div class="content-data-value">{{ join.time }} {{ 'general.hours' | translate }}</div>
</div> </div>
<div class="content-column" style="flex: 1;"> <div class="content-column" style="flex: 1;">
<div class="content-data-name">{{'view.server.profile.joined_voice_channel.channel' | translate}}:</div> <div class="content-data-name">{{ 'view.server.profile.joined_voice_channel.channel' | translate }}:</div>
<div class="content-data-value">{{join.channelName}}</div> <div class="content-data-value">{{ join.channelName }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.joined_at' | translate}}:</div> <div class="content-data-name">{{ 'common.joined_at' | translate }}:</div>
<div class="content-data-value">{{join.joinedOn | date:'dd.MM.yyyy HH:mm:ss'}}</div> <div class="content-data-value">{{ join.joinedOn | date:'dd.MM.yyyy HH:mm:ss' }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.leaved_at' | translate}}:</div> <div class="content-data-name">{{ 'common.leaved_at' | translate }}:</div>
<div class="content-data-value">{{join.leavedOn | date:'dd.MM.yyyy HH:mm:ss'}}</div> <div class="content-data-value">{{ join.leavedOn | date:'dd.MM.yyyy HH:mm:ss' }}</div>
</div> </div>
</div> </div>
</div> </div>
@ -254,30 +254,30 @@
<div *ngFor="let join of user.userJoinedGameServers;"> <div *ngFor="let join of user.userJoinedGameServers;">
<div class="content-row"> <div class="content-row">
<div class="content-column" style="flex: 0.3;"> <div class="content-column" style="flex: 0.3;">
<div class="content-data-name">{{'common.id' | translate}}:</div> <div class="content-data-name">{{ 'common.id' | translate }}:</div>
<div class="content-data-value">{{join.id}}</div> <div class="content-data-value">{{ join.id }}</div>
</div> </div>
<div class="content-column" style="flex: 0.75;"> <div class="content-column" style="flex: 0.75;">
<div class="content-data-name" <div class="content-data-name"
style="flex: 0.35;">{{'view.server.profile.joined_game_server.time' | translate}}: style="flex: 0.35;">{{ 'view.server.profile.joined_game_server.time' | translate }}:
</div> </div>
<div class="content-data-value">{{join.time}} {{'general.hours' | translate}}</div> <div class="content-data-value">{{ join.time }} {{ 'general.hours' | translate }}</div>
</div> </div>
<div class="content-column" style="flex: 1;"> <div class="content-column" style="flex: 1;">
<div class="content-data-name">{{'view.server.profile.joined_game_server.name' | translate}}:</div> <div class="content-data-name">{{ 'view.server.profile.joined_game_server.name' | translate }}:</div>
<div class="content-data-value">{{join.gameServer}}</div> <div class="content-data-value">{{ join.gameServer }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.joined_at' | translate}}:</div> <div class="content-data-name">{{ 'common.joined_at' | translate }}:</div>
<div class="content-data-value">{{join.joinedOn | date:'dd.MM.yyyy HH:mm:ss'}}</div> <div class="content-data-value">{{ join.joinedOn | date:'dd.MM.yyyy HH:mm:ss' }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.leaved_at' | translate}}:</div> <div class="content-data-name">{{ 'common.leaved_at' | translate }}:</div>
<div class="content-data-value">{{join.leavedOn | date:'dd.MM.yyyy HH:mm:ss'}}</div> <div class="content-data-value">{{ join.leavedOn | date:'dd.MM.yyyy HH:mm:ss' }}</div>
</div> </div>
</div> </div>
</div> </div>
@ -287,13 +287,13 @@
<div *ngFor="let join of user.joinedServers;"> <div *ngFor="let join of user.joinedServers;">
<div class="content-row"> <div class="content-row">
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.joined_at' | translate}}:</div> <div class="content-data-name">{{ 'common.joined_at' | translate }}:</div>
<div class="content-data-value">{{join.joinedOn | date:'dd.MM.yyyy HH:mm:ss'}}</div> <div class="content-data-value">{{ join.joinedOn | date:'dd.MM.yyyy HH:mm:ss' }}</div>
</div> </div>
<div class="content-column"> <div class="content-column">
<div class="content-data-name">{{'common.leaved_at' | translate}}:</div> <div class="content-data-name">{{ 'common.leaved_at' | translate }}:</div>
<div class="content-data-value">{{join.leavedOn | date:'dd.MM.yyyy HH:mm:ss'}}</div> <div class="content-data-value">{{ join.leavedOn | date:'dd.MM.yyyy HH:mm:ss' }}</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,7 +1,7 @@
{ {
"WebVersion": { "WebVersion": {
"Major": "1", "Major": "1",
"Minor": "2", "Minor": "2",
"Micro": "7" "Micro": "7"
} }
} }