Added flag check to hide pages #378

This commit is contained in:
Sven Heidemann 2023-09-28 15:14:38 +02:00
parent 376cb76036
commit 3546d38f75
7 changed files with 218 additions and 156 deletions

View File

@ -35,7 +35,7 @@ type Server implements TableWithHistoryQuery {
shortRoleNames(filter: ShortRoleNameFilter, page: Page, sort: Sort): [ShortRoleName] shortRoleNames(filter: ShortRoleNameFilter, page: Page, sort: Sort): [ShortRoleName]
config: ServerConfig config: ServerConfig
hasFeatureFlag(flag: String): Boolean hasFeatureFlag(flag: String): FeatureFlag
createdAt: String createdAt: String
modifiedAt: String modifiedAt: String

View File

@ -103,4 +103,7 @@ class ServerQuery(DataQueryWithHistoryABC):
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{server.discord_id}") settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{server.discord_id}")
if "flag" not in kwargs: if "flag" not in kwargs:
return False return False
return FeatureFlagsSettings.get_flag_from_dict(settings.feature_flags, FeatureFlagsEnum(kwargs["flag"])) return {
"key": kwargs["flag"],
"value": FeatureFlagsSettings.get_flag_from_dict(settings.feature_flags, FeatureFlagsEnum(kwargs["flag"])),
}

View File

@ -4,6 +4,7 @@ import {Level} from "./level.model";
import {Client} from "./client.model"; import {Client} from "./client.model";
import { AutoRole } from "./auto_role.model"; import { AutoRole } from "./auto_role.model";
import { ServerConfig } from "../config/server-config.model"; import { ServerConfig } from "../config/server-config.model";
import { FeatureFlag } from "../config/feature-flags.model";
export interface GameServer { export interface GameServer {
id?: number; id?: number;
@ -24,7 +25,8 @@ export interface Server extends Data {
userCount?: number; userCount?: number;
users?: User[]; users?: User[];
config?: ServerConfig; config?: ServerConfig;
hasFeatureFlag?: boolean; hasFeatureFlag?: FeatureFlag;
activeFeatureFlags?: FeatureFlag[];
} }
export interface ServerFilter { export interface ServerFilter {

View File

@ -85,7 +85,10 @@ export class Queries {
static hasServerFeatureFlag = ` static hasServerFeatureFlag = `
query HasServerFeatureFlag($filter: ServerFilter, $flag: String) { query HasServerFeatureFlag($filter: ServerFilter, $flag: String) {
servers(filter: $filter) { servers(filter: $filter) {
hasFeatureFlag(flag: $flag) hasFeatureFlag(flag: $flag) {
key
value
}
} }
} }
`; `;

View File

@ -7,6 +7,7 @@ import { Achievement, AchievementAttribute } from "../data/achievement.model";
import { TechnicianConfig } from "../config/technician-config.model"; import { TechnicianConfig } from "../config/technician-config.model";
import { ServerConfig } from "../config/server-config.model"; import { ServerConfig } from "../config/server-config.model";
import { ShortRoleName } from "../data/short_role_name.model"; import { ShortRoleName } from "../data/short_role_name.model";
import { FeatureFlag } from "../config/feature-flags.model";
export interface Query { export interface Query {
serverCount: number; serverCount: number;
@ -66,7 +67,7 @@ export interface PossibleFeatureFlagsQuery {
} }
export interface HasServerFeatureFlagQuery { export interface HasServerFeatureFlagQuery {
hasFeatureFlag: boolean; hasFeatureFlag: FeatureFlag;
} }
export interface ShortRoleNameListQuery { export interface ShortRoleNameListQuery {

View File

@ -9,7 +9,7 @@ import { NavigationEnd, Router } from "@angular/router";
export class ServerService { export class ServerService {
server$ = new BehaviorSubject<Server | null>(null); server$ = new BehaviorSubject<Server | undefined>(undefined);
constructor( constructor(
private router: Router private router: Router
@ -19,16 +19,17 @@ export class ServerService {
return; return;
} }
if (!event.url.startsWith("/server/") && this.server$.value) { if (!event.url.startsWith("/server/") && this.server$.value) {
this.setServer(null); this.setServer(undefined);
} }
}); });
} }
setServer(server: Server | null) { setServer(server: Server | undefined) {
if (!server) { if (!server) {
this.server$.next(server); this.server$.next(undefined);
return; return;
} }
if (server.id != this.server$.value?.id) { if (server.id != this.server$.value?.id) {
this.server$.next(server); this.server$.next(server);
} }

View File

@ -1,6 +1,6 @@
import { Injectable } from "@angular/core"; import { Injectable } from "@angular/core";
import { MenuItem } from "primeng/api"; import { MenuItem } from "primeng/api";
import { BehaviorSubject } from "rxjs"; import { BehaviorSubject, forkJoin, Observable } from "rxjs";
import { AuthRoles } from "../../models/auth/auth-roles.enum"; import { AuthRoles } from "../../models/auth/auth-roles.enum";
import { AuthService } from "../auth/auth.service"; import { AuthService } from "../auth/auth.service";
import { TranslateService } from "@ngx-translate/core"; import { TranslateService } from "@ngx-translate/core";
@ -9,6 +9,10 @@ import { ThemeService } from "../theme/theme.service";
import { Server } from "../../models/data/server.model"; import { Server } from "../../models/data/server.model";
import { UserDTO } from "../../models/auth/auth-user.dto"; import { UserDTO } from "../../models/auth/auth-user.dto";
import { ServerService } from "../server.service"; import { ServerService } from "../server.service";
import { HasServerFeatureFlagQuery, PossibleFeatureFlagsQuery, Query } from "../../models/graphql/query.model";
import { Queries } from "../../models/graphql/queries.model";
import { DataService } from "../data/data.service";
import { FeatureFlag } from "../../models/config/feature-flags.model";
@Injectable({ @Injectable({
providedIn: "root" providedIn: "root"
@ -17,7 +21,7 @@ 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 | null; server!: Server | undefined;
dashboard: MenuItem = {}; dashboard: MenuItem = {};
serverDashboard: MenuItem = {}; serverDashboard: MenuItem = {};
@ -33,12 +37,15 @@ export class SidebarService {
adminUsers: MenuItem = {}; adminUsers: MenuItem = {};
adminMenu: MenuItem = {}; adminMenu: MenuItem = {};
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
) { ) {
this.themeService.isSidebarOpen$.subscribe(value => { this.themeService.isSidebarOpen$.subscribe(value => {
this.isSidebarOpen = value; this.isSidebarOpen = value;
@ -146,6 +153,42 @@ export class SidebarService {
} }
setMenu(build: boolean = false) { 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 => { this.authService.hasUserPermission(AuthRoles.Admin).then(async hasPermission => {
let authUser = await this.authService.getLoggedInUser(); let authUser = await this.authService.getLoggedInUser();
let user: UserDTO | null = authUser?.users?.find(u => u.server == this.server?.id) ?? null; let user: UserDTO | null = authUser?.users?.find(u => u.server == this.server?.id) ?? null;
@ -158,10 +201,11 @@ export class SidebarService {
if (this.server) { if (this.server) {
this.serverMenu.visible = true; this.serverMenu.visible = true;
this.serverMembers.visible = !!user?.isModerator; this.serverMembers.visible = !!user?.isModerator;
this.serverAutoRoles.visible = !!user?.isModerator; this.serverAutoRoles.visible = this.hasFeature("AutoRoleModule") ? !!user?.isModerator : false;
this.serverLevels.visible = !!user?.isModerator; this.serverLevels.visible = this.hasFeature("LevelModule") ? !!user?.isModerator : false;
this.serverAchievements.visible = !!user?.isModerator; this.serverAchievements.visible = this.hasFeature("AchievementsModule") ? !!user?.isModerator : false;
this.serverShortRoleNames.visible = !!user?.isAdmin; this.serverShortRoleNames.visible = this.hasFeature("ShortRoleNameModule") ? !!user?.isAdmin : false;
this.serverConfig.visible = !!user?.isAdmin || isTechnician.length > 0; this.serverConfig.visible = !!user?.isAdmin || isTechnician.length > 0;
} else { } else {
this.serverMenu.visible = false; this.serverMenu.visible = false;
@ -175,4 +219,12 @@ export class SidebarService {
this.menuItems$.next(menuItems); 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;
}
} }