Fixed feature flag handling #393

This commit is contained in:
Sven Heidemann 2023-10-03 10:51:40 +02:00
parent 9e12d84ba0
commit 75adc2285e
27 changed files with 243 additions and 232 deletions

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "", "Author": "",
"AuthorEmail": "", "AuthorEmail": "",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -26,7 +26,7 @@ class FeatureFlagsSettings(ConfigurationModelABC):
FeatureFlagsEnum.game_server.value: False, # 25.09.2023 #366 FeatureFlagsEnum.game_server.value: False, # 25.09.2023 #366
FeatureFlagsEnum.sync_xp.value: False, # 25.09.2023 #366 FeatureFlagsEnum.sync_xp.value: False, # 25.09.2023 #366
FeatureFlagsEnum.short_role_name.value: False, # 28.09.2023 #378 FeatureFlagsEnum.short_role_name.value: False, # 28.09.2023 #378
FeatureFlagsEnum.technician_full_access.value: False, # 28.09.2023 #393 FeatureFlagsEnum.technician_full_access.value: False, # 03.10.2023 #393
} }
def __init__(self, **kwargs: dict): def __init__(self, **kwargs: dict):

View File

@ -7,7 +7,6 @@ from bot_data.abc.technician_config_repository_abc import TechnicianConfigReposi
from bot_data.model.server import Server from bot_data.model.server import Server
from bot_data.model.technician_config import TechnicianConfig from bot_data.model.technician_config import TechnicianConfig
from bot_data.service.server_config_seeder import ServerConfigSeeder from bot_data.service.server_config_seeder import ServerConfigSeeder
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
class ConfigService: class ConfigService:
@ -17,7 +16,6 @@ class ConfigService:
services: ServiceProviderABC, services: ServiceProviderABC,
technician_config_repo: TechnicianConfigRepositoryABC, technician_config_repo: TechnicianConfigRepositoryABC,
server_config_repo: ServerConfigRepositoryABC, server_config_repo: ServerConfigRepositoryABC,
tech_seeder: TechnicianConfigSeeder,
server_seeder: ServerConfigSeeder, server_seeder: ServerConfigSeeder,
): ):
self._config = config self._config = config
@ -25,13 +23,9 @@ class ConfigService:
self._technician_config_repo = technician_config_repo self._technician_config_repo = technician_config_repo
self._server_config_repo = server_config_repo self._server_config_repo = server_config_repo
self._tech_seeder = tech_seeder
self._server_seeder = server_seeder self._server_seeder = server_seeder
async def reload_technician_config(self): def reload_technician_config(self):
if not self._technician_config_repo.does_technician_config_exists():
await self._tech_seeder.seed()
technician_config = self._technician_config_repo.get_technician_config() technician_config = self._technician_config_repo.get_technician_config()
self._config.add_configuration(TechnicianConfig, technician_config) self._config.add_configuration(TechnicianConfig, technician_config)
self._config.add_configuration(FeatureFlagsSettings, FeatureFlagsSettings(**technician_config.feature_flags)) self._config.add_configuration(FeatureFlagsSettings, FeatureFlagsSettings(**technician_config.feature_flags))

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -11,6 +11,7 @@ from bot_data.model.technician_config import TechnicianConfig
from bot_data.model.technician_id_config import TechnicianIdConfig from bot_data.model.technician_id_config import TechnicianIdConfig
from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig from bot_data.model.technician_ping_url_config import TechnicianPingUrlConfig
from bot_data.model.user_role_enum import UserRoleEnum from bot_data.model.user_role_enum import UserRoleEnum
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
from bot_graphql.abc.query_abc import QueryABC from bot_graphql.abc.query_abc import QueryABC
@ -23,6 +24,7 @@ class TechnicianConfigMutation(QueryABC):
technician_configs: TechnicianConfigRepositoryABC, technician_configs: TechnicianConfigRepositoryABC,
db: DatabaseContextABC, db: DatabaseContextABC,
config_service: ConfigService, config_service: ConfigService,
tech_seeder: TechnicianConfigSeeder,
): ):
QueryABC.__init__(self, "TechnicianConfigMutation") QueryABC.__init__(self, "TechnicianConfigMutation")
@ -32,10 +34,14 @@ class TechnicianConfigMutation(QueryABC):
self._technician_configs = technician_configs self._technician_configs = technician_configs
self._db = db self._db = db
self._config_service = config_service self._config_service = config_service
self._tech_seeder = tech_seeder
self.set_field("updateTechnicianConfig", self.resolve_update_technician_config) self.set_field("updateTechnicianConfig", self.resolve_update_technician_config)
def resolve_update_technician_config(self, *_, input: dict): def resolve_update_technician_config(self, *_, input: dict):
if not self._technician_configs.does_technician_config_exists():
self._bot.loop.create_task(self._tech_seeder.seed())
technician_config = self._technician_configs.get_technician_config() technician_config = self._technician_configs.get_technician_config()
self._can_user_mutate_data(Route.get_user().users[0].server, UserRoleEnum.technician) self._can_user_mutate_data(Route.get_user().users[0].server, UserRoleEnum.technician)
@ -53,11 +59,16 @@ class TechnicianConfigMutation(QueryABC):
technician_config.cache_max_messages = ( technician_config.cache_max_messages = (
input["cacheMaxMessages"] if "cacheMaxMessages" in input else technician_config.cache_max_messages input["cacheMaxMessages"] if "cacheMaxMessages" in input else technician_config.cache_max_messages
) )
old_feature_flags = technician_config.feature_flags
technician_config.feature_flags = ( technician_config.feature_flags = (
dict(zip([x["key"] for x in input["featureFlags"]], [x["value"] for x in input["featureFlags"]])) dict(zip([x["key"] for x in input["featureFlags"]], [x["value"] for x in input["featureFlags"]]))
if "featureFlags" in input if "featureFlags" in input
else technician_config.feature_flags else technician_config.feature_flags
) )
for old_flag in old_feature_flags:
if old_flag not in technician_config.feature_flags:
technician_config.feature_flags[old_flag] = False
technician_config.ping_urls = ( technician_config.ping_urls = (
List(str, input["pingURLs"]) if "pingURLs" in input else technician_config.ping_urls List(str, input["pingURLs"]) if "pingURLs" in input else technician_config.ping_urls
) )
@ -75,6 +86,7 @@ class TechnicianConfigMutation(QueryABC):
self._update_technician_ids(technician_config) self._update_technician_ids(technician_config)
self._db.save_changes() self._db.save_changes()
self._config_service.reload_technician_config()
return technician_config return technician_config
def _update_ping_urls(self, new_config: TechnicianConfig): def _update_ping_urls(self, new_config: TechnicianConfig):
@ -109,5 +121,3 @@ class TechnicianConfigMutation(QueryABC):
continue continue
self._technician_configs.add_technician_id_config(TechnicianIdConfig(technician_id)) self._technician_configs.add_technician_id_config(TechnicianIdConfig(technician_id))
self._bot.loop.create_task(self._config_service.reload_technician_config())

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "", "Author": "",
"AuthorEmail": "", "AuthorEmail": "",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "", "Author": "",
"AuthorEmail": "", "AuthorEmail": "",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "", "Author": "",
"AuthorEmail": "", "AuthorEmail": "",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "", "Author": "",
"AuthorEmail": "", "AuthorEmail": "",

View File

@ -19,4 +19,4 @@ class ConfigExtension(ApplicationExtensionABC):
logger: LoggerABC = services.get_service(LoggerABC) logger: LoggerABC = services.get_service(LoggerABC)
logger.debug(__name__, "Config extension started") logger.debug(__name__, "Config extension started")
config: ConfigService = services.get_service(ConfigService) config: ConfigService = services.get_service(ConfigService)
await config.reload_technician_config() config.reload_technician_config()

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "", "Author": "",
"AuthorEmail": "", "AuthorEmail": "",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "", "Author": "",
"AuthorEmail": "", "AuthorEmail": "",

View File

@ -29,10 +29,11 @@ class PermissionService(PermissionServiceABC):
self._technician_configs = technician_configs self._technician_configs = technician_configs
def _has_member_role(self, member: discord.Member, team_member_type: TeamMemberTypeEnum) -> bool: def _has_member_role(self, member: discord.Member, team_member_type: TeamMemberTypeEnum) -> bool:
self._logger.debug(__name__, f"Checking permissions for {member.name}")
if member is None or member.guild is None: if member is None or member.guild is None:
return False return False
self._logger.debug(__name__, f"Checking is member {member.name} {team_member_type.value}")
try: try:
server = self._servers.get_server_by_discord_id(member.guild.id) server = self._servers.get_server_by_discord_id(member.guild.id)
config = self._server_configs.get_server_config_by_server(server.id) config = self._server_configs.get_server_config_by_server(server.id)
@ -58,10 +59,11 @@ class PermissionService(PermissionServiceABC):
) )
def is_member_technician(self, member: discord.Member) -> bool: def is_member_technician(self, member: discord.Member) -> bool:
self._logger.debug(__name__, f"Checking is member {member.name} technician")
if member is None or member.guild is None: if member is None or member.guild is None:
return False return False
self._logger.debug(__name__, f"Checking is member {member.name} technician")
try: try:
tech_config = self._technician_configs.get_technician_config() tech_config = self._technician_configs.get_technician_config()
if member.id in tech_config.technician_ids: if member.id in tech_config.technician_ids:

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "", "Author": "",
"AuthorEmail": "", "AuthorEmail": "",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -4,7 +4,7 @@
"Version": { "Version": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
}, },
"Author": "Sven Heidemann", "Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de", "AuthorEmail": "sven.heidemann@sh-edraft.de",

View File

@ -1,6 +1,6 @@
{ {
"name": "kdb-web", "name": "kdb-web",
"version": "1.1.9", "version": "1.1.10",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"update-version": "ts-node update-version.ts", "update-version": "ts-node update-version.ts",

View File

@ -34,11 +34,11 @@ export class AuthGuard implements CanActivate {
const role = route.data["role"]; const role = route.data["role"];
const memberRole = route.data["memberRole"]; const memberRole = route.data["memberRole"];
const authUser = await this.authService.getLoggedInUser();
const isTechnician = (authUser?.users?.map(u => u.isTechnician).filter(u => u) ?? []).length > 0;
if (role !== undefined) { if (role !== undefined) {
this.authService.hasUserPermission(role).then(async hasPermission => { this.authService.hasUserPermission(role).then(async hasPermission => {
let authUser = await this.authService.getLoggedInUser();
let isTechnician = authUser?.users?.map(u => u.isTechnician).filter(u => u) ?? [];
if (!hasPermission && !isTechnician) { if (!hasPermission && !isTechnician) {
this.router.navigate(["/dashboard"]); this.router.navigate(["/dashboard"]);
return false; return false;
@ -49,12 +49,15 @@ export class AuthGuard implements CanActivate {
if (memberRole !== undefined) { if (memberRole !== undefined) {
let userHasAccess = false; let userHasAccess = false;
let authUser = await this.authService.getLoggedInUser();
let server = route.params["serverId"]; let server = route.params["serverId"];
if (!authUser || !authUser.users) { if (this.sidebarService.hasFeature("TechnicianFullAccess") && isTechnician) {
return true; return true;
} }
if (!authUser || !authUser.users) {
return false;
}
authUser?.users?.forEach(u => { authUser?.users?.forEach(u => {
if (u.server === +(server ?? 0)) { if (u.server === +(server ?? 0)) {
if ( if (

View File

@ -15,216 +15,218 @@ import { DataService } from "../data/data.service";
import { FeatureFlag } from "../../models/config/feature-flags.model"; import { FeatureFlag } from "../../models/config/feature-flags.model";
@Injectable({ @Injectable({
providedIn: "root" providedIn: "root"
}) })
export class SidebarService { export class SidebarService {
isSidebarOpen: boolean = true; isSidebarOpen: boolean = true;
menuItems$ = new BehaviorSubject<MenuItem[]>(new Array<MenuItem>()); menuItems$ = new BehaviorSubject<MenuItem[]>(new Array<MenuItem>());
server!: Server | undefined; server!: Server | undefined;
dashboard: MenuItem = {}; dashboard: MenuItem = {};
serverDashboard: MenuItem = {}; serverDashboard: MenuItem = {};
serverProfile: MenuItem = {}; serverProfile: MenuItem = {};
serverMembers: MenuItem = {}; serverMembers: MenuItem = {};
serverAutoRoles: MenuItem = {}; serverAutoRoles: MenuItem = {};
serverLevels: MenuItem = {}; serverLevels: MenuItem = {};
serverAchievements: MenuItem = {}; serverAchievements: MenuItem = {};
serverShortRoleNames: MenuItem = {}; serverShortRoleNames: MenuItem = {};
serverConfig: MenuItem = {}; serverConfig: MenuItem = {};
serverMenu: MenuItem = {}; serverMenu: MenuItem = {};
adminConfig: MenuItem = {}; adminConfig: MenuItem = {};
adminUsers: MenuItem = {}; adminUsers: MenuItem = {};
adminMenu: MenuItem = {}; adminMenu: MenuItem = {};
featureFlags: FeatureFlag[] = []; featureFlags: FeatureFlag[] = [];
constructor( constructor(
private themeService: ThemeService, private themeService: ThemeService,
private authService: AuthService, private authService: AuthService,
private translateService: TranslateService, private translateService: TranslateService,
private router: Router, private router: Router,
private serverService: ServerService, private serverService: ServerService,
private data: DataService private data: DataService
) { ) {
this.themeService.isSidebarOpen$.subscribe(value => { this.themeService.isSidebarOpen$.subscribe(value => {
this.isSidebarOpen = value; this.isSidebarOpen = value;
this.setMenu(true); this.setMenu(true);
});
this.translateService.onLangChange.subscribe(_ => {
this.setMenu(true);
});
this.serverService.server$.subscribe(server => {
this.server = server;
if (server) {
this.setMenu(true);
} else {
this.setMenu(false);
}
});
}
async buildMenu(user: UserDTO | null, hasPermission: boolean, isTechnician: boolean = false) {
this.dashboard = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.dashboard") : "",
icon: "pi pi-th-large",
routerLink: "dashboard"
};
this.serverDashboard = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.dashboard") : "",
icon: "pi pi-th-large",
routerLink: `server/${this.server?.id}`
};
this.serverProfile = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.profile") : "",
icon: "pi pi-id-card",
routerLink: `server/${this.server?.id}/members/${user?.id}`
};
this.serverMembers = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.members") : "",
icon: "pi pi-users",
visible: true,
routerLink: `server/${this.server?.id}/members`
};
this.serverAutoRoles = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.auto_roles") : "",
icon: "pi pi-sitemap",
visible: true,
routerLink: `server/${this.server?.id}/auto-roles`
};
this.serverLevels = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.levels") : "",
icon: "pi pi-book",
visible: true,
routerLink: `server/${this.server?.id}/levels`
};
this.serverAchievements = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.achievements") : "",
icon: "pi pi-angle-double-up",
visible: true,
routerLink: `server/${this.server?.id}/achievements`
};
this.serverShortRoleNames = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.short_role_names") : "",
icon: "pi pi-list",
visible: true,
routerLink: `server/${this.server?.id}/short-role-names`
};
this.serverConfig = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.configuration") : "",
icon: "pi pi-cog",
visible: true,
routerLink: `server/${this.server?.id}/config`
};
this.serverMenu = {
label: this.isSidebarOpen ? this.server?.name : "",
icon: "pi pi-server",
visible: false,
expanded: true,
items: [this.serverDashboard, this.serverProfile, this.serverMembers, this.serverAutoRoles, this.serverLevels, this.serverAchievements, this.serverShortRoleNames, this.serverConfig]
};
this.adminConfig = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.config") : "",
visible: hasPermission || isTechnician,
icon: "pi pi-cog",
routerLink: "/admin/settings"
};
this.adminUsers = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.auth_user_list") : "",
visible: hasPermission,
icon: "pi pi-user-edit",
routerLink: "/admin/users"
};
this.adminMenu = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.administration") : "",
icon: "pi pi-cog",
visible: hasPermission || isTechnician,
expanded: true,
items: [this.adminConfig, this.adminUsers]
};
}
setMenu(build: boolean = false) {
const server = this.server;
if (server) {
this.featureFlags = [];
this.data.query<PossibleFeatureFlagsQuery>("{possibleFeatureFlags}"
).subscribe(data => {
let observables: Observable<HasServerFeatureFlagQuery>[] = [];
data.possibleFeatureFlags.forEach(flag => {
observables.push(
this.data.query<HasServerFeatureFlagQuery>(Queries.hasServerFeatureFlag, {
filter: { id: server.id },
flag: flag
},
function(data: Query) {
return data.servers[0];
}
)
);
}); });
this.translateService.onLangChange.subscribe(_ => { forkJoin(observables).subscribe(data => {
this.setMenu(true); data.forEach(flag => {
}); if (!flag.hasFeatureFlag.value) {
return;
this.serverService.server$.subscribe(server => {
this.server = server;
if (server) {
this.setMenu(true);
} else {
this.setMenu(false);
} }
this.featureFlags.push(flag.hasFeatureFlag);
});
this._setMenu(build);
}); });
});
} else {
this._setMenu(build);
} }
}
async buildMenu(user: UserDTO | null, hasPermission: boolean, isTechnician: boolean = false) { private _setMenu(build: boolean = false) {
this.dashboard = { this.authService.hasUserPermission(AuthRoles.Admin).then(async hasPermission => {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.dashboard") : "", let authUser = await this.authService.getLoggedInUser();
icon: "pi pi-th-large", let user: UserDTO | null = authUser?.users?.find(u => u.server == this.server?.id) ?? null;
routerLink: "dashboard" let isTechnician = (authUser?.users?.map(u => u.isTechnician).filter(u => u) ?? []).length > 0;
}; let isTechnicianAndFullAccessActive = this.hasFeature("TechnicianFullAccess") && isTechnician;
this.serverDashboard = { console.log(this.hasFeature("TechnicianFullAccess"))
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.dashboard") : "",
icon: "pi pi-th-large",
routerLink: `server/${this.server?.id}`
};
this.serverProfile = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.profile") : "",
icon: "pi pi-id-card",
routerLink: `server/${this.server?.id}/members/${user?.id}`
};
this.serverMembers = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.members") : "",
icon: "pi pi-users",
visible: true,
routerLink: `server/${this.server?.id}/members`
};
this.serverAutoRoles = { if (build || this.menuItems$.value.length == 0) {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.auto_roles") : "", await this.buildMenu(user, hasPermission, isTechnician);
icon: "pi pi-sitemap", }
visible: true,
routerLink: `server/${this.server?.id}/auto-roles`
};
this.serverLevels = { if (this.server) {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.levels") : "", this.serverMenu.visible = true;
icon: "pi pi-book", this.serverMembers.visible = isTechnicianAndFullAccessActive || user?.isModerator;
visible: true, this.serverAutoRoles.visible = isTechnicianAndFullAccessActive || this.hasFeature("AutoRoleModule") && user?.isModerator;
routerLink: `server/${this.server?.id}/levels` this.serverLevels.visible = isTechnicianAndFullAccessActive || this.hasFeature("LevelModule") && user?.isModerator;
}; this.serverAchievements.visible = isTechnicianAndFullAccessActive || this.hasFeature("AchievementsModule") && user?.isModerator;
this.serverShortRoleNames.visible = isTechnicianAndFullAccessActive || this.hasFeature("ShortRoleName") && user?.isAdmin;
this.serverAchievements = { this.serverConfig.visible = isTechnicianAndFullAccessActive || user?.isAdmin;
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.achievements") : "", } else {
icon: "pi pi-angle-double-up", this.serverMenu.visible = false;
visible: true, }
routerLink: `server/${this.server?.id}/achievements`
};
this.serverShortRoleNames = { let menuItems: MenuItem[] = [
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.short_role_names") : "", this.dashboard,
icon: "pi pi-list", this.serverMenu,
visible: true, this.adminMenu
routerLink: `server/${this.server?.id}/short-role-names` ];
}; this.menuItems$.next(menuItems);
});
}
this.serverConfig = { public hasFeature(key: string): boolean {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.configuration") : "", const flag = this.featureFlags.filter(flag => flag.key == key);
icon: "pi pi-cog", if (flag.length == 0) {
visible: true, return false;
routerLink: `server/${this.server?.id}/config`
};
this.serverMenu = {
label: this.isSidebarOpen ? this.server?.name : "",
icon: "pi pi-server",
visible: false,
expanded: true,
items: [this.serverDashboard, this.serverProfile, this.serverMembers, this.serverAutoRoles, this.serverLevels, this.serverAchievements, this.serverShortRoleNames, this.serverConfig]
};
this.adminConfig = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.config") : "",
visible: hasPermission || isTechnician,
icon: "pi pi-cog",
routerLink: "/admin/settings"
};
this.adminUsers = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.auth_user_list") : "",
visible: hasPermission,
icon: "pi pi-user-edit",
routerLink: "/admin/users"
};
this.adminMenu = {
label: this.isSidebarOpen ? this.translateService.instant("sidebar.administration") : "",
icon: "pi pi-cog",
visible: hasPermission || isTechnician,
expanded: true,
items: [this.adminConfig, this.adminUsers]
};
}
setMenu(build: boolean = false) {
const server = this.server;
if (server) {
this.featureFlags = [];
this.data.query<PossibleFeatureFlagsQuery>("{possibleFeatureFlags}"
).subscribe(data => {
let observables: Observable<HasServerFeatureFlagQuery>[] = [];
data.possibleFeatureFlags.forEach(flag => {
observables.push(
this.data.query<HasServerFeatureFlagQuery>(Queries.hasServerFeatureFlag, {
filter: { id: server.id },
flag: flag
},
function(data: Query) {
return data.servers[0];
}
)
);
});
forkJoin(observables).subscribe(data => {
data.forEach(flag => {
if (!flag.hasFeatureFlag.value) {
return;
}
this.featureFlags.push(flag.hasFeatureFlag);
});
this._setMenu(build);
});
});
} else {
this._setMenu(build);
}
}
private _setMenu(build: boolean = false) {
this.authService.hasUserPermission(AuthRoles.Admin).then(async hasPermission => {
let authUser = await this.authService.getLoggedInUser();
let user: UserDTO | null = authUser?.users?.find(u => u.server == this.server?.id) ?? null;
let isTechnician = authUser?.users?.map(u => u.isTechnician).filter(u => u) ?? [];
if (build || this.menuItems$.value.length == 0) {
await this.buildMenu(user, hasPermission, isTechnician.length > 0);
}
if (this.server) {
this.serverMenu.visible = true;
this.serverMembers.visible = !!user?.isModerator;
this.serverAutoRoles.visible = this.hasFeature("AutoRoleModule") ? !!user?.isModerator : false;
this.serverLevels.visible = this.hasFeature("LevelModule") ? !!user?.isModerator : false;
this.serverAchievements.visible = this.hasFeature("AchievementsModule") ? !!user?.isModerator : false;
this.serverShortRoleNames.visible = this.hasFeature("ShortRoleName") ? !!user?.isAdmin : false;
this.serverConfig.visible = !!user?.isAdmin || isTechnician.length > 0;
} else {
this.serverMenu.visible = false;
}
let menuItems: MenuItem[] = [
this.dashboard,
this.serverMenu,
this.adminMenu
];
this.menuItems$.next(menuItems);
});
}
private hasFeature(key: string): boolean {
const flag = this.featureFlags.filter(flag => flag.key == key);
if (flag.length == 0) {
return false;
}
return flag[0].value;
} }
return flag[0].value;
}
} }

View File

@ -2,6 +2,6 @@
"WebVersion": { "WebVersion": {
"Major": "1", "Major": "1",
"Minor": "1", "Minor": "1",
"Micro": "9" "Micro": "10"
} }
} }