diff --git a/kdb-bot/src/bot_graphql/graphql/server.gql b/kdb-bot/src/bot_graphql/graphql/server.gql
index 67da7455..6b29f0f9 100644
--- a/kdb-bot/src/bot_graphql/graphql/server.gql
+++ b/kdb-bot/src/bot_graphql/graphql/server.gql
@@ -35,6 +35,7 @@ type Server implements TableWithHistoryQuery {
shortRoleNames(filter: ShortRoleNameFilter, page: Page, sort: Sort): [ShortRoleName]
config: ServerConfig
+ hasFeatureFlag(flag: String): Boolean
createdAt: String
modifiedAt: String
diff --git a/kdb-bot/src/bot_graphql/queries/server_query.py b/kdb-bot/src/bot_graphql/queries/server_query.py
index 1e5606bf..3690c37f 100644
--- a/kdb-bot/src/bot_graphql/queries/server_query.py
+++ b/kdb-bot/src/bot_graphql/queries/server_query.py
@@ -1,6 +1,9 @@
+from cpl_core.configuration import ConfigurationABC
from cpl_core.database.context import DatabaseContextABC
from cpl_discord.service import DiscordBotServiceABC
+from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
+from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
from bot_data.abc.client_repository_abc import ClientRepositoryABC
@@ -12,6 +15,7 @@ from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepos
from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC
from bot_data.abc.user_repository_abc import UserRepositoryABC
from bot_data.model.server import Server
+from bot_data.model.server_config import ServerConfig
from bot_data.model.server_history import ServerHistory
from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC
from bot_graphql.filter.achievement_filter import AchievementFilter
@@ -25,6 +29,7 @@ from bot_graphql.filter.user_filter import UserFilter
class ServerQuery(DataQueryWithHistoryABC):
def __init__(
self,
+ config: ConfigurationABC,
bot: DiscordBotServiceABC,
db: DatabaseContextABC,
auto_roles: AutoRoleRepositoryABC,
@@ -40,6 +45,7 @@ class ServerQuery(DataQueryWithHistoryABC):
):
DataQueryWithHistoryABC.__init__(self, "Server", "ServersHistory", ServerHistory, db)
+ self._config = config
self._bot = bot
self._auto_roles = auto_roles
self._clients = clients
@@ -73,6 +79,9 @@ class ServerQuery(DataQueryWithHistoryABC):
ShortRoleNameFilter,
)
self.set_field("config", lambda server, *_: server_configs.get_server_config_by_server(server.id))
+ self.set_field(
+ "hasFeatureFlag", lambda server, *_, **kwargs: self._resolve_has_feature_flag(server, *_, **kwargs)
+ )
@staticmethod
def resolve_id(server: Server, *_):
@@ -89,3 +98,9 @@ class ServerQuery(DataQueryWithHistoryABC):
@staticmethod
def resolve_icon_url(server: Server, *_):
return server.icon_url
+
+ def _resolve_has_feature_flag(self, server: Server, *_, **kwargs):
+ settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{server.discord_id}")
+ if "flag" not in kwargs:
+ return False
+ return FeatureFlagsSettings.get_flag_from_dict(settings.feature_flags, FeatureFlagsEnum(kwargs["flag"]))
diff --git a/kdb-web/src/app/models/data/server.model.ts b/kdb-web/src/app/models/data/server.model.ts
index a045186d..fb2d2864 100644
--- a/kdb-web/src/app/models/data/server.model.ts
+++ b/kdb-web/src/app/models/data/server.model.ts
@@ -3,6 +3,7 @@ import {User} from "./user.model";
import {Level} from "./level.model";
import {Client} from "./client.model";
import { AutoRole } from "./auto_role.model";
+import { ServerConfig } from "../config/server-config.model";
export interface GameServer {
id?: number;
@@ -22,6 +23,8 @@ export interface Server extends Data {
levels?: Level[];
userCount?: number;
users?: User[];
+ config?: ServerConfig;
+ hasFeatureFlag?: boolean;
}
export interface ServerFilter {
diff --git a/kdb-web/src/app/models/graphql/queries.model.ts b/kdb-web/src/app/models/graphql/queries.model.ts
index 1014ec79..ec5702a9 100644
--- a/kdb-web/src/app/models/graphql/queries.model.ts
+++ b/kdb-web/src/app/models/graphql/queries.model.ts
@@ -82,6 +82,14 @@ export class Queries {
}
`;
+ static hasServerFeatureFlag = `
+ query HasServerFeatureFlag($filter: ServerFilter, $flag: String) {
+ servers(filter: $filter) {
+ hasFeatureFlag(flag: $flag)
+ }
+ }
+ `;
+
static gameServerQuery = `
query GameServersList($serverId: ID) {
servers(filter: {id: $serverId}) {
diff --git a/kdb-web/src/app/models/graphql/query.model.ts b/kdb-web/src/app/models/graphql/query.model.ts
index fe0c9683..403436b3 100644
--- a/kdb-web/src/app/models/graphql/query.model.ts
+++ b/kdb-web/src/app/models/graphql/query.model.ts
@@ -64,3 +64,7 @@ export interface PossibleFeatureFlagsQuery {
possibleFeatureFlags: string[];
}
+export interface HasServerFeatureFlagQuery {
+ hasFeatureFlag: boolean;
+}
+
diff --git a/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.ts b/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.ts
index ca1a2d00..aeeebd39 100644
--- a/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.ts
+++ b/kdb-web/src/app/modules/shared/components/history-btn/history-btn.component.ts
@@ -11,6 +11,7 @@ import { FormBuilder } from "@angular/forms";
import { TranslateService } from "@ngx-translate/core";
import { ActivatedRoute } from "@angular/router";
import { SidebarService } from "../../../../services/sidebar/sidebar.service";
+import { ServerService } from "../../../../services/server.service";
@Component({
selector: "app-history-btn",
@@ -37,12 +38,12 @@ export class HistoryBtnComponent implements OnInit {
private translate: TranslateService,
private data: DataService,
private route: ActivatedRoute,
- private sidebar: SidebarService
+ private serverService: ServerService
) {
}
public ngOnInit(): void {
- this.server = this.sidebar.server$.value ?? {};
+ this.server = this.serverService.server$.value ?? {};
}
private findVal(object: any, key: string) {
diff --git a/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts b/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts
index f28ae00b..bf1e7a72 100644
--- a/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts
+++ b/kdb-web/src/app/modules/view/dashboard/components/dashboard/dashboard.component.ts
@@ -14,6 +14,7 @@ import { Page } from "../../../../../models/graphql/filter/page.model";
import { Sort } from "../../../../../models/graphql/filter/sort.model";
import { Query } from "../../../../../models/graphql/query.model";
import { SidebarService } from "../../../../../services/sidebar/sidebar.service";
+import { ServerService } from "../../../../../services/server.service";
@Component({
selector: "app-dashboard",
@@ -44,12 +45,9 @@ export class DashboardComponent implements OnInit, OnDestroy {
constructor(
private data: DataService,
private spinnerService: SpinnerService,
- private toastService: ToastService,
- private confirmDialog: ConfirmationDialogService,
private fb: FormBuilder,
- private translate: TranslateService,
private router: Router,
- private sidebar: SidebarService
+ private serverService: ServerService,
) {
}
@@ -107,7 +105,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
}
selectServer(server: Server) {
- this.sidebar.setServer(server);
+ this.serverService.setServer(server);
this.router.navigate(["/server", server.id]);
}
diff --git a/kdb-web/src/app/modules/view/server/server-dashboard/server-dashboard.component.html b/kdb-web/src/app/modules/view/server/server-dashboard/server-dashboard.component.html
index 69fa157d..f8263f8d 100644
--- a/kdb-web/src/app/modules/view/server/server-dashboard/server-dashboard.component.html
+++ b/kdb-web/src/app/modules/view/server/server-dashboard/server-dashboard.component.html
@@ -14,22 +14,22 @@
-
+
- {{server.name}}
+ {{server ? server.name : ''}}
- {{server.userCount}}
+ {{server ? server.userCount : ''}}
{{'view.dashboard.server.member_count' | translate}}
+ *ngFor="let client of server?.clients">
diff --git a/kdb-web/src/app/modules/view/server/server-dashboard/server-dashboard.component.ts b/kdb-web/src/app/modules/view/server/server-dashboard/server-dashboard.component.ts
index 642e0f7c..04edbb08 100644
--- a/kdb-web/src/app/modules/view/server/server-dashboard/server-dashboard.component.ts
+++ b/kdb-web/src/app/modules/view/server/server-dashboard/server-dashboard.component.ts
@@ -4,6 +4,7 @@ import { Server } from "src/app/models/data/server.model";
import { DataService } from "src/app/services/data/data.service";
import { SpinnerService } from "src/app/services/spinner/spinner.service";
import { SidebarService } from "../../../../services/sidebar/sidebar.service";
+import { ServerService } from "../../../../services/server.service";
@Component({
selector: "app-server-dashboard",
@@ -20,7 +21,7 @@ export class ServerDashboardComponent implements OnInit {
private router: Router,
private data: DataService,
private spinner: SpinnerService,
- private sidebar: SidebarService
+ private serverService: ServerService
) {
}
@@ -29,7 +30,7 @@ export class ServerDashboardComponent implements OnInit {
this.server = server;
});
- this.sidebar.server$.subscribe(server => {
+ this.serverService.server$.subscribe(server => {
if (!server) {
return;
}
diff --git a/kdb-web/src/app/modules/view/server/server-routing.module.ts b/kdb-web/src/app/modules/view/server/server-routing.module.ts
index b0e09575..505aa609 100644
--- a/kdb-web/src/app/modules/view/server/server-routing.module.ts
+++ b/kdb-web/src/app/modules/view/server/server-routing.module.ts
@@ -17,8 +17,9 @@ const routes: Routes = [
data: { memberRole: MemberRoles.Moderator }
},
{ path: "levels", loadChildren: () => import("./levels/levels.module").then(m => m.LevelsModule), canActivate: [AuthGuard], data: { memberRole: MemberRoles.Moderator } },
- { path: "achievements", loadChildren: () => import("./achievements/achievements.module").then(m => m.AchievementsModule), data: { memberRole: MemberRoles.Moderator } },
- { path: "config", loadChildren: () => import("./config/config.module").then(m => m.ConfigModule), data: { memberRole: MemberRoles.Admin } }
+ { path: "achievements", loadChildren: () => import("./achievements/achievements.module").then(m => m.AchievementsModule), canActivate: [AuthGuard], data: { memberRole: MemberRoles.Moderator } },
+ { path: "short-role-names", loadChildren: () => import("./short-role-name/short-role-name.module").then(m => m.ShortRoleNameModule), canActivate: [AuthGuard], data: { memberRole: MemberRoles.Moderator } },
+ { path: "config", loadChildren: () => import("./config/config.module").then(m => m.ConfigModule), canActivate: [AuthGuard], data: { memberRole: MemberRoles.Admin } }
];
@NgModule({
diff --git a/kdb-web/src/app/modules/view/server/server.module.ts b/kdb-web/src/app/modules/view/server/server.module.ts
index 1e4b2a8a..6a04b47f 100644
--- a/kdb-web/src/app/modules/view/server/server.module.ts
+++ b/kdb-web/src/app/modules/view/server/server.module.ts
@@ -14,7 +14,7 @@ import { ClientComponent } from './server-dashboard/components/client/client.com
ServerDashboardComponent,
ProfileComponent,
MembersComponent,
- ClientComponent
+ ClientComponent,
],
imports: [
CommonModule,
diff --git a/kdb-web/src/app/modules/view/server/short-role-name/components/short-role-names/short-role-names.component.html b/kdb-web/src/app/modules/view/server/short-role-name/components/short-role-names/short-role-names.component.html
new file mode 100644
index 00000000..5a75a1f6
--- /dev/null
+++ b/kdb-web/src/app/modules/view/server/short-role-name/components/short-role-names/short-role-names.component.html
@@ -0,0 +1 @@
+
short-role-names works!
diff --git a/kdb-web/src/app/modules/view/server/short-role-name/components/short-role-names/short-role-names.component.scss b/kdb-web/src/app/modules/view/server/short-role-name/components/short-role-names/short-role-names.component.scss
new file mode 100644
index 00000000..e69de29b
diff --git a/kdb-web/src/app/modules/view/server/short-role-name/components/short-role-names/short-role-names.component.spec.ts b/kdb-web/src/app/modules/view/server/short-role-name/components/short-role-names/short-role-names.component.spec.ts
new file mode 100644
index 00000000..2a09af96
--- /dev/null
+++ b/kdb-web/src/app/modules/view/server/short-role-name/components/short-role-names/short-role-names.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ShortRoleNamesComponent } from './short-role-names.component';
+
+describe('ShortRoleNamesComponent', () => {
+ let component: ShortRoleNamesComponent;
+ let fixture: ComponentFixture
;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ ShortRoleNamesComponent ]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(ShortRoleNamesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/kdb-web/src/app/modules/view/server/short-role-name/components/short-role-names/short-role-names.component.ts b/kdb-web/src/app/modules/view/server/short-role-name/components/short-role-names/short-role-names.component.ts
new file mode 100644
index 00000000..b22c1ae9
--- /dev/null
+++ b/kdb-web/src/app/modules/view/server/short-role-name/components/short-role-names/short-role-names.component.ts
@@ -0,0 +1,39 @@
+import { Component, OnInit } from "@angular/core";
+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 { FormBuilder } from "@angular/forms";
+import { TranslateService } from "@ngx-translate/core";
+import { DataService } from "../../../../../../services/data/data.service";
+import { SidebarService } from "../../../../../../services/sidebar/sidebar.service";
+import { ActivatedRoute } from "@angular/router";
+import { Server } from "../../../../../../models/data/server.model";
+
+@Component({
+ selector: 'app-short-role-names',
+ templateUrl: './short-role-names.component.html',
+ styleUrls: ['./short-role-names.component.scss']
+})
+export class ShortRoleNamesComponent implements OnInit {
+ private server: Server = {};
+
+ public 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,
+ private route: ActivatedRoute
+ ) {
+ }
+
+ public ngOnInit(): void {
+ this.data.getServerFromRoute(this.route).then(async server => {
+ this.server = server;
+ });
+ }
+}
diff --git a/kdb-web/src/app/modules/view/server/short-role-name/short-role-name-routing.module.ts b/kdb-web/src/app/modules/view/server/short-role-name/short-role-name-routing.module.ts
new file mode 100644
index 00000000..bd806f29
--- /dev/null
+++ b/kdb-web/src/app/modules/view/server/short-role-name/short-role-name-routing.module.ts
@@ -0,0 +1,14 @@
+import { NgModule } from "@angular/core";
+import { RouterModule, Routes } from "@angular/router";
+import { ShortRoleNamesComponent } from "./components/short-role-names/short-role-names.component";
+
+const routes: Routes = [
+ { path: "", component: ShortRoleNamesComponent },
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class ShortRoleNameRoutingModule {
+}
diff --git a/kdb-web/src/app/modules/view/server/short-role-name/short-role-name.module.ts b/kdb-web/src/app/modules/view/server/short-role-name/short-role-name.module.ts
new file mode 100644
index 00000000..f35bd9ec
--- /dev/null
+++ b/kdb-web/src/app/modules/view/server/short-role-name/short-role-name.module.ts
@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { ShortRoleNamesComponent } from './components/short-role-names/short-role-names.component';
+import { ShortRoleNameRoutingModule } from "./short-role-name-routing.module";
+
+
+
+@NgModule({
+ declarations: [
+ ShortRoleNamesComponent,
+ ],
+ imports: [
+ CommonModule,
+ ShortRoleNameRoutingModule
+ ]
+})
+export class ShortRoleNameModule { }
diff --git a/kdb-web/src/app/services/data/data.service.ts b/kdb-web/src/app/services/data/data.service.ts
index 9d7d13b3..99d09b83 100644
--- a/kdb-web/src/app/services/data/data.service.ts
+++ b/kdb-web/src/app/services/data/data.service.ts
@@ -7,11 +7,11 @@ import { ActivatedRoute, Router } from "@angular/router";
import { Server } from "../../models/data/server.model";
import { Queries } from "../../models/graphql/queries.model";
import { Query } from "../../models/graphql/query.model";
-import { SidebarService } from "../sidebar/sidebar.service";
import { SpinnerService } from "../spinner/spinner.service";
import { GraphQLResult } from "../../models/graphql/result.model";
import { ToastService } from "../toast/toast.service";
import { TranslateService } from "@ngx-translate/core";
+import { ServerService } from "../server.service";
@Injectable({
providedIn: "root"
@@ -21,7 +21,7 @@ export class DataService {
constructor(
private appsettings: SettingsService,
private http: HttpClient,
- private sidebar: SidebarService,
+ private server: ServerService,
private spinner: SpinnerService,
private router: Router,
private toast: ToastService,
@@ -45,7 +45,7 @@ export class DataService {
return data.servers.length > 0 ? data.servers[0] : null;
}
).subscribe(server => {
- this.sidebar.setServer(server);
+ this.server.setServer(server);
this.spinner.hideSpinner();
resolve(server);
});
diff --git a/kdb-web/src/app/services/server.service.spec.ts b/kdb-web/src/app/services/server.service.spec.ts
new file mode 100644
index 00000000..906c1601
--- /dev/null
+++ b/kdb-web/src/app/services/server.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { ServerService } from './server.service';
+
+describe('ServerService', () => {
+ let service: ServerService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(ServerService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/kdb-web/src/app/services/server.service.ts b/kdb-web/src/app/services/server.service.ts
new file mode 100644
index 00000000..b01a608a
--- /dev/null
+++ b/kdb-web/src/app/services/server.service.ts
@@ -0,0 +1,36 @@
+import { Injectable } from "@angular/core";
+import { BehaviorSubject } from "rxjs";
+import { Server } from "../models/data/server.model";
+import { NavigationEnd, Router } from "@angular/router";
+
+@Injectable({
+ providedIn: "root"
+})
+export class ServerService {
+
+
+ server$ = new BehaviorSubject(null);
+
+ constructor(
+ private router: Router
+ ) {
+ this.router.events.subscribe(event => {
+ if (!(event instanceof NavigationEnd)) {
+ return;
+ }
+ if (!event.url.startsWith("/server/") && this.server$.value) {
+ this.setServer(null);
+ }
+ });
+ }
+
+ setServer(server: Server | null) {
+ if (!server) {
+ this.server$.next(server);
+ return;
+ }
+ if (server.id != this.server$.value?.id) {
+ this.server$.next(server);
+ }
+ }
+}
diff --git a/kdb-web/src/app/services/sidebar/sidebar.service.ts b/kdb-web/src/app/services/sidebar/sidebar.service.ts
index c4d1a102..a2e05f05 100644
--- a/kdb-web/src/app/services/sidebar/sidebar.service.ts
+++ b/kdb-web/src/app/services/sidebar/sidebar.service.ts
@@ -8,6 +8,7 @@ import { NavigationEnd, Router } from "@angular/router";
import { ThemeService } from "../theme/theme.service";
import { Server } from "../../models/data/server.model";
import { UserDTO } from "../../models/auth/auth-user.dto";
+import { ServerService } from "../server.service";
@Injectable({
providedIn: "root"
@@ -16,7 +17,7 @@ export class SidebarService {
isSidebarOpen: boolean = true;
menuItems$ = new BehaviorSubject