Added feature flags to server config #334

This commit is contained in:
Sven Heidemann 2023-08-15 20:50:11 +02:00
parent 4b57d7f102
commit 8a0d939147
15 changed files with 74 additions and 25 deletions

View File

@ -1,3 +1,4 @@
import json
from datetime import datetime from datetime import datetime
from cpl_core.configuration import ConfigurationModelABC from cpl_core.configuration import ConfigurationModelABC
@ -236,6 +237,7 @@ class ServerConfig(TableABC, ConfigurationModelABC):
`HelpVoiceChannelId`, `HelpVoiceChannelId`,
`TeamChannelId`, `TeamChannelId`,
`LoginMessageChannelId`, `LoginMessageChannelId`,
`FeatureFlags`,
`ServerId` `ServerId`
) VALUES ( ) VALUES (
{self._message_delete_timer}, {self._message_delete_timer},
@ -251,6 +253,7 @@ class ServerConfig(TableABC, ConfigurationModelABC):
{self._help_voice_channel_id}, {self._help_voice_channel_id},
{self._team_channel_id}, {self._team_channel_id},
{self._login_message_channel_id}, {self._login_message_channel_id},
'{json.dumps(self._feature_flags)}',
{self._server.id} {self._server.id}
); );
""" """
@ -274,6 +277,7 @@ class ServerConfig(TableABC, ConfigurationModelABC):
`HelpVoiceChannelId` = {self._help_voice_channel_id}, `HelpVoiceChannelId` = {self._help_voice_channel_id},
`TeamChannelId` = {self._team_channel_id}, `TeamChannelId` = {self._team_channel_id},
`LoginMessageChannelId` = {self._login_message_channel_id}, `LoginMessageChannelId` = {self._login_message_channel_id},
`FeatureFlags` = '{json.dumps(self._feature_flags)}',
`ServerId` = {self._server.id} `ServerId` = {self._server.id}
WHERE `Id` = {self._id}; WHERE `Id` = {self._id};
""" """

View File

@ -40,4 +40,5 @@ type Query {
technicianConfig: TechnicianConfig technicianConfig: TechnicianConfig
guilds(filter: GuildFilter): [Guild] guilds(filter: GuildFilter): [Guild]
possibleFeatureFlags: [String]
} }

View File

@ -13,6 +13,7 @@ type ServerConfig implements TableWithHistoryQuery {
helpVoiceChannelId: String helpVoiceChannelId: String
teamChannelId: String teamChannelId: String
loginMessageChannelId: String loginMessageChannelId: String
featureFlags: [FeatureFlag]
afkChannelIds: [String] afkChannelIds: [String]
moderatorRoleIds: [String] moderatorRoleIds: [String]
@ -41,6 +42,7 @@ type ServerConfigHistory implements HistoryTableQuery {
helpVoiceChannelId: String helpVoiceChannelId: String
teamChannelId: String teamChannelId: String
loginMessageChannelId: String loginMessageChannelId: String
featureFlags: [FeatureFlag]
serverId: ID serverId: ID
@ -87,6 +89,7 @@ input ServerConfigInput {
helpVoiceChannelId: String helpVoiceChannelId: String
teamChannelId: String teamChannelId: String
loginMessageChannelId: String loginMessageChannelId: String
featureFlags: [FeatureFlagInput]
afkChannelIds: [String] afkChannelIds: [String]
moderatorRoleIds: [String] moderatorRoleIds: [String]

View File

@ -82,6 +82,11 @@ class ServerConfigMutation(QueryABC):
if "loginMessageChannelId" in input if "loginMessageChannelId" in input
else server_config.login_message_channel_id else server_config.login_message_channel_id
) )
server_config.feature_flags = (
dict(zip([x["key"] for x in input["featureFlags"]], [x["value"] for x in input["featureFlags"]]))
if "featureFlags" in input
else server_config.feature_flags
)
server_config.afk_channel_ids = ( server_config.afk_channel_ids = (
List(int).extend([int(x) for x in input["afkChannelIds"]]) List(int).extend([int(x) for x in input["afkChannelIds"]])
if "afkChannelIds" in input if "afkChannelIds" in input

View File

@ -23,6 +23,10 @@ class ServerConfigQuery(DataQueryWithHistoryABC):
self.set_field("helpVoiceChannelId", lambda config, *_: config.help_voice_channel_id) self.set_field("helpVoiceChannelId", lambda config, *_: config.help_voice_channel_id)
self.set_field("teamChannelId", lambda config, *_: config.team_channel_id) self.set_field("teamChannelId", lambda config, *_: config.team_channel_id)
self.set_field("loginMessageChannelId", lambda config, *_: config.login_message_channel_id) self.set_field("loginMessageChannelId", lambda config, *_: config.login_message_channel_id)
self.set_field(
"featureFlags",
lambda config, *_: [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags],
)
self.set_field("afkChannelIds", lambda config, *_: config.afk_channel_ids) self.set_field("afkChannelIds", lambda config, *_: config.afk_channel_ids)
self.set_field( self.set_field(
"moderatorRoleIds", "moderatorRoleIds",

View File

@ -1,5 +1,6 @@
from cpl_discord.service import DiscordBotServiceABC from cpl_discord.service import DiscordBotServiceABC
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC 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
@ -75,6 +76,7 @@ class Query(QueryABC):
self.set_field("guilds", self._resolve_guilds) self.set_field("guilds", self._resolve_guilds)
self.set_field("achievementAttributes", lambda x, *_: achievement_service.get_attributes()) self.set_field("achievementAttributes", lambda x, *_: achievement_service.get_attributes())
self.set_field("achievementOperators", lambda x, *_: achievement_service.get_operators()) self.set_field("achievementOperators", lambda x, *_: achievement_service.get_operators())
self.set_field("possibleFeatureFlags", lambda x, *_: [e.value for e in FeatureFlagsEnum])
def _resolve_guilds(self, *_, filter=None): def _resolve_guilds(self, *_, filter=None):
if filter is None or "id" not in filter: if filter is None or "id" not in filter:

View File

@ -1,4 +1,5 @@
import { DataWithHistory } from "../data/data.model"; import { DataWithHistory } from "../data/data.model";
import { FeatureFlag } from "./feature-flags.model";
export interface ServerConfig extends DataWithHistory { export interface ServerConfig extends DataWithHistory {
id?: number; id?: number;
@ -15,6 +16,7 @@ export interface ServerConfig extends DataWithHistory {
helpVoiceChannelId?: string; helpVoiceChannelId?: string;
teamChannelId?: string; teamChannelId?: string;
loginMessageChannelId?: string; loginMessageChannelId?: string;
featureFlags: FeatureFlag[];
afkChannelIds: string[]; afkChannelIds: string[];
moderatorRoleIds: string[]; moderatorRoleIds: string[];
adminRoleIds: string[]; adminRoleIds: string[];

View File

@ -211,6 +211,7 @@ export class Mutations {
$helpVoiceChannelId: String, $helpVoiceChannelId: String,
$teamChannelId: String, $teamChannelId: String,
$loginMessageChannelId: String, $loginMessageChannelId: String,
$featureFlags: [FeatureFlagInput],
$afkChannelIds: [String], $afkChannelIds: [String],
$moderatorRoleIds: [String], $moderatorRoleIds: [String],
$adminRoleIds: [String] $adminRoleIds: [String]
@ -218,21 +219,22 @@ export class Mutations {
serverConfig { serverConfig {
updateServerConfig(input: { updateServerConfig(input: {
id: $id, id: $id,
messageDeleteTimer: $messageDeleteTimer messageDeleteTimer: $messageDeleteTimer,
notificationChatId: $notificationChatId notificationChatId: $notificationChatId,
maxVoiceStateHours: $maxVoiceStateHours maxVoiceStateHours: $maxVoiceStateHours,
xpPerMessage: $xpPerMessage xpPerMessage: $xpPerMessage,
xpPerReaction: $xpPerReaction xpPerReaction: $xpPerReaction,
maxMessageXpPerHour: $maxMessageXpPerHour maxMessageXpPerHour: $maxMessageXpPerHour,
xpPerOntimeHour: $xpPerOntimeHour xpPerOntimeHour: $xpPerOntimeHour,
xpPerEventParticipation: $xpPerEventParticipation xpPerEventParticipation: $xpPerEventParticipation,
xpPerAchievement: $xpPerAchievement xpPerAchievement: $xpPerAchievement,
afkCommandChannelId: $afkCommandChannelId afkCommandChannelId: $afkCommandChannelId,
helpVoiceChannelId: $helpVoiceChannelId helpVoiceChannelId: $helpVoiceChannelId,
teamChannelId: $teamChannelId teamChannelId: $teamChannelId,
loginMessageChannelId: $loginMessageChannelId loginMessageChannelId: $loginMessageChannelId,
afkChannelIds: $afkChannelIds featureFlags: $featureFlags,
moderatorRoleIds: $moderatorRoleIds afkChannelIds: $afkChannelIds,
moderatorRoleIds: $moderatorRoleIds,
adminRoleIds: $adminRoleIds adminRoleIds: $adminRoleIds
}) { }) {
id id
@ -249,6 +251,10 @@ export class Mutations {
helpVoiceChannelId helpVoiceChannelId
teamChannelId teamChannelId
loginMessageChannelId loginMessageChannelId
featureFlags {
key
value
}
afkChannelIds afkChannelIds
moderatorRoleIds moderatorRoleIds
adminRoleIds adminRoleIds

View File

@ -385,6 +385,10 @@ export class Queries {
helpVoiceChannelId helpVoiceChannelId
teamChannelId teamChannelId
loginMessageChannelId loginMessageChannelId
featureFlags {
key
value
}
afkChannelIds afkChannelIds
moderatorRoleIds moderatorRoleIds
adminRoleIds adminRoleIds

View File

@ -59,3 +59,8 @@ export interface AutoRoleRuleQuery {
autoRoleRules: AutoRoleRule[]; autoRoleRules: AutoRoleRule[];
} }
export interface PossibleFeatureFlagsQuery {
possibleFeatureFlags: string[];
}

View File

@ -163,9 +163,7 @@
<div class="content-divider"></div> <div class="content-divider"></div>
<app-config-list translationKey="admin.settings.bot.ping_urls" [(data)]="config.pingURLs"></app-config-list> <app-config-list translationKey="admin.settings.bot.ping_urls" [(data)]="config.pingURLs"></app-config-list>
<app-config-list translationKey="admin.settings.bot.technician_ids" [(data)]="config.technicianIds"></app-config-list> <app-config-list translationKey="admin.settings.bot.technician_ids" [(data)]="config.technicianIds"></app-config-list>
<app-feature-flag-list [(data)]="config.featureFlags"></app-feature-flag-list> <app-feature-flag-list [(data)]="config.featureFlags"></app-feature-flag-list>
<div class="content-divider"></div>
<div class="content-row"> <div class="content-row">
<button pButton icon="pi pi-save" label="{{'common.save' | translate}}" class="btn login-form-submit-btn" <button pButton icon="pi pi-save" label="{{'common.save' | translate}}" class="btn login-form-submit-btn"

View File

@ -19,7 +19,7 @@
<td style="flex: 3;"> <td style="flex: 3;">
<p-cellEditor> <p-cellEditor>
<ng-template pTemplate="input"> <ng-template pTemplate="input">
<input class="table-edit-input" pInputText type="text" [(ngModel)]="value.value.key"> <p-dropdown class="table-edit-input" [options]="featureFlags" [(ngModel)]="value.value.key"></p-dropdown>
</ng-template> </ng-template>
<ng-template pTemplate="output"> <ng-template pTemplate="output">
{{value.value.key}} {{value.value.key}}
@ -52,3 +52,4 @@
</div> </div>
</div> </div>
</div> </div>
<div class="content-divider"></div>

View File

@ -1,24 +1,36 @@
import { Component } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { ConfigListComponent } from "../config-list/config-list.component"; import { ConfigListComponent } from "../config-list/config-list.component";
import { Table } from "primeng/table"; import { Table } from "primeng/table";
import { PossibleFeatureFlagsQuery } from "../../../../models/graphql/query.model";
import { DataService } from "../../../../services/data/data.service";
@Component({ @Component({
selector: "app-feature-flag-list", selector: "app-feature-flag-list",
templateUrl: "./feature-flag-list.component.html", templateUrl: "./feature-flag-list.component.html",
styleUrls: ["./feature-flag-list.component.scss"] styleUrls: ["./feature-flag-list.component.scss"]
}) })
export class FeatureFlagListComponent extends ConfigListComponent { export class FeatureFlagListComponent extends ConfigListComponent implements OnInit {
options: boolean[] = [true, false]; featureFlags: string[] = [];
constructor() {
constructor(
private dataService: DataService
) {
super(); super();
} }
ngOnInit() {
this.dataService.query<PossibleFeatureFlagsQuery>("{possibleFeatureFlags}"
).subscribe(data => {
this.featureFlags = data.possibleFeatureFlags;
});
}
override addNew(table: Table) { override addNew(table: Table) {
const id = Math.max.apply(Math, this.internal_data.map(value => { const id = Math.max.apply(Math, this.internal_data.map(value => {
return value.id ?? 0; return value.id ?? 0;
})) + 1; })) + 1;
const newItem = { id: id, value: {key: "", value: false} }; const newItem = { id: id, value: { key: "", value: false } };
this.internal_data.push(newItem); this.internal_data.push(newItem);
table.initRowEdit(newItem); table.initRowEdit(newItem);

View File

@ -113,6 +113,7 @@
<app-config-list translationKey="view.server.config.bot.afk_channels" [(data)]="config.afkChannelIds"></app-config-list> <app-config-list translationKey="view.server.config.bot.afk_channels" [(data)]="config.afkChannelIds"></app-config-list>
<app-config-list translationKey="view.server.config.bot.moderator_roles" [(data)]="config.moderatorRoleIds"></app-config-list> <app-config-list translationKey="view.server.config.bot.moderator_roles" [(data)]="config.moderatorRoleIds"></app-config-list>
<app-config-list translationKey="view.server.config.bot.admin_roles" [(data)]="config.adminRoleIds"></app-config-list> <app-config-list translationKey="view.server.config.bot.admin_roles" [(data)]="config.adminRoleIds"></app-config-list>
<app-feature-flag-list [(data)]="config.featureFlags"></app-feature-flag-list>
<div class="content-row"> <div class="content-row">
<button pButton icon="pi pi-save" label="{{'common.save' | translate}}" class="btn login-form-submit-btn" <button pButton icon="pi pi-save" label="{{'common.save' | translate}}" class="btn login-form-submit-btn"

View File

@ -16,7 +16,6 @@ import { AuthService } from "../../../../../../services/auth/auth.service";
import { ServerConfig } from "../../../../../../models/config/server-config.model"; import { ServerConfig } from "../../../../../../models/config/server-config.model";
import { Server } from "../../../../../../models/data/server.model"; import { Server } from "../../../../../../models/data/server.model";
import { ActivatedRoute } from "@angular/router"; import { ActivatedRoute } from "@angular/router";
import { Table } from "primeng/table";
type AFKChannelId = { type AFKChannelId = {
id: number; id: number;
@ -31,6 +30,7 @@ type AFKChannelId = {
export class ConfigComponent implements OnInit { export class ConfigComponent implements OnInit {
config: ServerConfig = { config: ServerConfig = {
messageDeleteTimer: 0, messageDeleteTimer: 0,
featureFlags: [],
afkChannelIds: [], afkChannelIds: [],
moderatorRoleIds: [], moderatorRoleIds: [],
adminRoleIds: [] adminRoleIds: []
@ -101,6 +101,7 @@ export class ConfigComponent implements OnInit {
helpVoiceChannelId: this.config.helpVoiceChannelId, helpVoiceChannelId: this.config.helpVoiceChannelId,
teamChannelId: this.config.teamChannelId, teamChannelId: this.config.teamChannelId,
loginMessageChannelId: this.config.loginMessageChannelId, loginMessageChannelId: this.config.loginMessageChannelId,
featureFlags: this.config.featureFlags,
afkChannelIds: this.config.afkChannelIds, afkChannelIds: this.config.afkChannelIds,
moderatorRoleIds: this.config.moderatorRoleIds, moderatorRoleIds: this.config.moderatorRoleIds,
adminRoleIds: this.config.adminRoleIds adminRoleIds: this.config.adminRoleIds
@ -110,7 +111,7 @@ export class ConfigComponent implements OnInit {
return throwError(err); return throwError(err);
})).subscribe(result => { })).subscribe(result => {
this.spinner.hideSpinner(); this.spinner.hideSpinner();
this.toastService.success(this.translate.instant("view.server.config.message.server#_config_create"), this.translate.instant("view.server.config.message.server_config_create_d")); this.toastService.success(this.translate.instant("view.server.config.message.server_config_create"), this.translate.instant("view.server.config.message.server_config_create_d"));
}); });
} }
} }