Added feature flags config to technician settings #334
This commit is contained in:
parent
02e0c72a80
commit
4b57d7f102
@ -31,10 +31,10 @@ class Program:
|
|||||||
.use_extension(StartupDiscordExtension)
|
.use_extension(StartupDiscordExtension)
|
||||||
.use_extension(StartupModuleExtension)
|
.use_extension(StartupModuleExtension)
|
||||||
.use_extension(StartupMigrationExtension)
|
.use_extension(StartupMigrationExtension)
|
||||||
|
.use_extension(DatabaseExtension)
|
||||||
.use_extension(ConfigExtension)
|
.use_extension(ConfigExtension)
|
||||||
.use_extension(InitBotExtension)
|
.use_extension(InitBotExtension)
|
||||||
.use_extension(BootLogExtension)
|
.use_extension(BootLogExtension)
|
||||||
.use_extension(DatabaseExtension)
|
|
||||||
.use_extension(AppApiExtension)
|
.use_extension(AppApiExtension)
|
||||||
.use_extension(CoreExtension)
|
.use_extension(CoreExtension)
|
||||||
.use_startup(Startup)
|
.use_startup(Startup)
|
||||||
|
@ -9,6 +9,7 @@ from bot_data.migration.api_key_migration import ApiKeyMigration
|
|||||||
from bot_data.migration.api_migration import ApiMigration
|
from bot_data.migration.api_migration import ApiMigration
|
||||||
from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration
|
from bot_data.migration.auto_role_fix1_migration import AutoRoleFix1Migration
|
||||||
from bot_data.migration.auto_role_migration import AutoRoleMigration
|
from bot_data.migration.auto_role_migration import AutoRoleMigration
|
||||||
|
from bot_data.migration.config_feature_flags_migration import ConfigFeatureFlagsMigration
|
||||||
from bot_data.migration.config_migration import ConfigMigration
|
from bot_data.migration.config_migration import ConfigMigration
|
||||||
from bot_data.migration.db_history_migration import DBHistoryMigration
|
from bot_data.migration.db_history_migration import DBHistoryMigration
|
||||||
from bot_data.migration.initial_migration import InitialMigration
|
from bot_data.migration.initial_migration import InitialMigration
|
||||||
@ -46,3 +47,4 @@ class StartupMigrationExtension(StartupExtensionABC):
|
|||||||
services.add_transient(MigrationABC, DBHistoryMigration) # 06.03.2023 #246 - 1.0.0
|
services.add_transient(MigrationABC, DBHistoryMigration) # 06.03.2023 #246 - 1.0.0
|
||||||
services.add_transient(MigrationABC, AchievementsMigration) # 14.06.2023 #268 - 1.1.0
|
services.add_transient(MigrationABC, AchievementsMigration) # 14.06.2023 #268 - 1.1.0
|
||||||
services.add_transient(MigrationABC, ConfigMigration) # 19.07.2023 #127 - 1.1.0
|
services.add_transient(MigrationABC, ConfigMigration) # 19.07.2023 #127 - 1.1.0
|
||||||
|
services.add_transient(MigrationABC, ConfigFeatureFlagsMigration) # 15.08.2023 #334 - 1.1.0
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
from bot_core.logging.database_logger import DatabaseLogger
|
||||||
|
from bot_data.abc.migration_abc import MigrationABC
|
||||||
|
from bot_data.db_context import DBContext
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigFeatureFlagsMigration(MigrationABC):
|
||||||
|
name = "1.1.0_ConfigFeatureFlagsMigration"
|
||||||
|
|
||||||
|
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
||||||
|
MigrationABC.__init__(self)
|
||||||
|
self._logger = logger
|
||||||
|
self._db = db
|
||||||
|
self._cursor = db.cursor
|
||||||
|
|
||||||
|
def upgrade(self):
|
||||||
|
self._logger.debug(__name__, "Running upgrade")
|
||||||
|
|
||||||
|
self._cursor.execute(
|
||||||
|
str(
|
||||||
|
"""ALTER TABLE CFG_Technician ADD FeatureFlags JSON NULL DEFAULT JSON_OBJECT() AFTER CacheMaxMessages;"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self._cursor.execute(
|
||||||
|
str(
|
||||||
|
"""ALTER TABLE CFG_Server ADD FeatureFlags JSON NULL DEFAULT JSON_OBJECT() AFTER LoginMessageChannelId;"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def downgrade(self):
|
||||||
|
self._logger.debug(__name__, "Running downgrade")
|
||||||
|
self._cursor.execute("ALTER TABLE CFG_Technician DROP COLUMN FeatureFlags;")
|
||||||
|
self._cursor.execute("ALTER TABLE CFG_Server DROP COLUMN FeatureFlags;")
|
@ -143,6 +143,8 @@ class ConfigMigration(MigrationABC):
|
|||||||
|
|
||||||
def downgrade(self):
|
def downgrade(self):
|
||||||
self._logger.debug(__name__, "Running downgrade")
|
self._logger.debug(__name__, "Running downgrade")
|
||||||
|
self._server_downgrade()
|
||||||
|
self._technician_downgrade()
|
||||||
|
|
||||||
def _server_downgrade(self):
|
def _server_downgrade(self):
|
||||||
self._cursor.execute("DROP TABLE `CFG_Server`;")
|
self._cursor.execute("DROP TABLE `CFG_Server`;")
|
||||||
|
@ -4,6 +4,7 @@ from cpl_core.configuration import ConfigurationModelABC
|
|||||||
from cpl_core.database import TableABC
|
from cpl_core.database import TableABC
|
||||||
from cpl_query.extension import List
|
from cpl_query.extension import List
|
||||||
|
|
||||||
|
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||||
from bot_data.model.server import Server
|
from bot_data.model.server import Server
|
||||||
from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig
|
from bot_data.model.server_team_role_ids_config import ServerTeamRoleIdsConfig
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ class ServerConfig(TableABC, ConfigurationModelABC):
|
|||||||
help_voice_channel_id: int,
|
help_voice_channel_id: int,
|
||||||
team_channel_id: int,
|
team_channel_id: int,
|
||||||
login_message_channel_id: int,
|
login_message_channel_id: int,
|
||||||
|
feature_flags: dict[FeatureFlagsEnum],
|
||||||
server: Server,
|
server: Server,
|
||||||
afk_channel_ids: List[int],
|
afk_channel_ids: List[int],
|
||||||
team_role_ids: List[ServerTeamRoleIdsConfig],
|
team_role_ids: List[ServerTeamRoleIdsConfig],
|
||||||
@ -45,6 +47,7 @@ class ServerConfig(TableABC, ConfigurationModelABC):
|
|||||||
self._help_voice_channel_id = help_voice_channel_id
|
self._help_voice_channel_id = help_voice_channel_id
|
||||||
self._team_channel_id = team_channel_id
|
self._team_channel_id = team_channel_id
|
||||||
self._login_message_channel_id = login_message_channel_id
|
self._login_message_channel_id = login_message_channel_id
|
||||||
|
self._feature_flags = feature_flags
|
||||||
self._server = server
|
self._server = server
|
||||||
self._afk_channel_ids = afk_channel_ids
|
self._afk_channel_ids = afk_channel_ids
|
||||||
self._team_role_ids = team_role_ids
|
self._team_role_ids = team_role_ids
|
||||||
@ -161,6 +164,14 @@ class ServerConfig(TableABC, ConfigurationModelABC):
|
|||||||
def login_message_channel_id(self, value: int):
|
def login_message_channel_id(self, value: int):
|
||||||
self._login_message_channel_id = value
|
self._login_message_channel_id = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_flags(self) -> dict[FeatureFlagsEnum]:
|
||||||
|
return self._feature_flags
|
||||||
|
|
||||||
|
@feature_flags.setter
|
||||||
|
def feature_flags(self, value: dict[FeatureFlagsEnum]):
|
||||||
|
self._feature_flags = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def afk_channel_ids(self) -> List[int]:
|
def afk_channel_ids(self) -> List[int]:
|
||||||
return self._afk_channel_ids
|
return self._afk_channel_ids
|
||||||
|
@ -17,6 +17,7 @@ class ServerConfigHistory(HistoryTableABC):
|
|||||||
help_voice_channel_id: int,
|
help_voice_channel_id: int,
|
||||||
team_channel_id: int,
|
team_channel_id: int,
|
||||||
login_message_channel_id: int,
|
login_message_channel_id: int,
|
||||||
|
feature_flags: dict[str],
|
||||||
server_id: int,
|
server_id: int,
|
||||||
deleted: bool,
|
deleted: bool,
|
||||||
date_from: str,
|
date_from: str,
|
||||||
@ -39,6 +40,7 @@ class ServerConfigHistory(HistoryTableABC):
|
|||||||
self._help_voice_channel_id = help_voice_channel_id
|
self._help_voice_channel_id = help_voice_channel_id
|
||||||
self._team_channel_id = team_channel_id
|
self._team_channel_id = team_channel_id
|
||||||
self._login_message_channel_id = login_message_channel_id
|
self._login_message_channel_id = login_message_channel_id
|
||||||
|
self._feature_flags = feature_flags
|
||||||
self._server_id = server_id
|
self._server_id = server_id
|
||||||
|
|
||||||
self._deleted = deleted
|
self._deleted = deleted
|
||||||
@ -97,6 +99,10 @@ class ServerConfigHistory(HistoryTableABC):
|
|||||||
def login_message_channel_id(self) -> int:
|
def login_message_channel_id(self) -> int:
|
||||||
return self._login_message_channel_id
|
return self._login_message_channel_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_flags(self) -> dict[str]:
|
||||||
|
return self._feature_flags
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def server_id(self) -> int:
|
def server_id(self) -> int:
|
||||||
return self._server_id
|
return self._server_id
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
import json
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from cpl_core.configuration import ConfigurationModelABC
|
from cpl_core.configuration import ConfigurationModelABC
|
||||||
from cpl_core.database import TableABC
|
from cpl_core.database import TableABC
|
||||||
from cpl_query.extension import List
|
from cpl_query.extension import List
|
||||||
|
|
||||||
|
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
||||||
|
|
||||||
|
|
||||||
class TechnicianConfig(TableABC, ConfigurationModelABC):
|
class TechnicianConfig(TableABC, ConfigurationModelABC):
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -12,6 +15,7 @@ class TechnicianConfig(TableABC, ConfigurationModelABC):
|
|||||||
wait_for_restart: int,
|
wait_for_restart: int,
|
||||||
wait_for_shutdown: int,
|
wait_for_shutdown: int,
|
||||||
cache_max_messages: int,
|
cache_max_messages: int,
|
||||||
|
feature_flags: dict[FeatureFlagsEnum],
|
||||||
technician_ids: List[int],
|
technician_ids: List[int],
|
||||||
ping_urls: List[str],
|
ping_urls: List[str],
|
||||||
created_at: datetime = None,
|
created_at: datetime = None,
|
||||||
@ -23,6 +27,7 @@ class TechnicianConfig(TableABC, ConfigurationModelABC):
|
|||||||
self._wait_for_restart = wait_for_restart
|
self._wait_for_restart = wait_for_restart
|
||||||
self._wait_for_shutdown = wait_for_shutdown
|
self._wait_for_shutdown = wait_for_shutdown
|
||||||
self._cache_max_messages = cache_max_messages
|
self._cache_max_messages = cache_max_messages
|
||||||
|
self._feature_flags = feature_flags
|
||||||
self._technician_ids = technician_ids
|
self._technician_ids = technician_ids
|
||||||
self._ping_urls = ping_urls
|
self._ping_urls = ping_urls
|
||||||
|
|
||||||
@ -66,6 +71,14 @@ class TechnicianConfig(TableABC, ConfigurationModelABC):
|
|||||||
def cache_max_messages(self, value: int):
|
def cache_max_messages(self, value: int):
|
||||||
self._cache_max_messages = value
|
self._cache_max_messages = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def feature_flags(self) -> dict[FeatureFlagsEnum]:
|
||||||
|
return self._feature_flags
|
||||||
|
|
||||||
|
@feature_flags.setter
|
||||||
|
def feature_flags(self, value: dict[FeatureFlagsEnum]):
|
||||||
|
self._feature_flags = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def technician_ids(self) -> List[int]:
|
def technician_ids(self) -> List[int]:
|
||||||
return self._technician_ids
|
return self._technician_ids
|
||||||
@ -104,12 +117,13 @@ class TechnicianConfig(TableABC, ConfigurationModelABC):
|
|||||||
return str(
|
return str(
|
||||||
f"""
|
f"""
|
||||||
INSERT INTO `CFG_Technician` (
|
INSERT INTO `CFG_Technician` (
|
||||||
`HelpCommandReferenceUrl`, `WaitForRestart`, `WaitForShutdown`, `CacheMaxMessages`
|
`HelpCommandReferenceUrl`, `WaitForRestart`, `WaitForShutdown`, `CacheMaxMessages`, `FeatureFlags`
|
||||||
) VALUES (
|
) VALUES (
|
||||||
'{self._help_command_reference_url}',
|
'{self._help_command_reference_url}',
|
||||||
{self._wait_for_restart},
|
{self._wait_for_restart},
|
||||||
{self._wait_for_shutdown},
|
{self._wait_for_shutdown},
|
||||||
{self._cache_max_messages}
|
{self._cache_max_messages},
|
||||||
|
'{json.dumps(self._feature_flags)}'
|
||||||
);
|
);
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@ -122,7 +136,8 @@ class TechnicianConfig(TableABC, ConfigurationModelABC):
|
|||||||
SET `HelpCommandReferenceUrl` = '{self._help_command_reference_url}',
|
SET `HelpCommandReferenceUrl` = '{self._help_command_reference_url}',
|
||||||
`WaitForRestart` = {self._wait_for_restart},
|
`WaitForRestart` = {self._wait_for_restart},
|
||||||
`WaitForShutdown` = {self._wait_for_shutdown},
|
`WaitForShutdown` = {self._wait_for_shutdown},
|
||||||
`CacheMaxMessages` = {self._cache_max_messages}
|
`CacheMaxMessages` = {self._cache_max_messages},
|
||||||
|
`FeatureFlags` = '{json.dumps(self._feature_flags)}'
|
||||||
WHERE `Id` = {self._id};
|
WHERE `Id` = {self._id};
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
from cpl_core.database.context import DatabaseContextABC
|
from cpl_core.database.context import DatabaseContextABC
|
||||||
from cpl_query.extension import List
|
from cpl_query.extension import List
|
||||||
|
|
||||||
@ -62,11 +64,12 @@ class ServerConfigRepositoryService(ServerConfigRepositoryABC):
|
|||||||
result[11],
|
result[11],
|
||||||
result[12],
|
result[12],
|
||||||
result[13],
|
result[13],
|
||||||
self._servers.get_server_by_id(result[14]),
|
json.loads(result[14]),
|
||||||
self._get_afk_channel_ids(result[14]),
|
self._servers.get_server_by_id(result[15]),
|
||||||
self._get_team_role_ids(result[14]),
|
self._get_afk_channel_ids(result[15]),
|
||||||
result[15],
|
self._get_team_role_ids(result[15]),
|
||||||
result[16],
|
result[16],
|
||||||
|
result[17],
|
||||||
id=result[0],
|
id=result[0],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ class ServerConfigSeeder(DataSeederABC):
|
|||||||
guild.system_channel.id,
|
guild.system_channel.id,
|
||||||
guild.system_channel.id,
|
guild.system_channel.id,
|
||||||
guild.system_channel.id,
|
guild.system_channel.id,
|
||||||
|
{},
|
||||||
server,
|
server,
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
from cpl_core.database.context import DatabaseContextABC
|
from cpl_core.database.context import DatabaseContextABC
|
||||||
from cpl_query.extension import List
|
from cpl_query.extension import List
|
||||||
|
|
||||||
@ -41,10 +43,11 @@ class TechnicianConfigRepositoryService(TechnicianConfigRepositoryABC):
|
|||||||
result[2],
|
result[2],
|
||||||
result[3],
|
result[3],
|
||||||
result[4],
|
result[4],
|
||||||
|
json.loads(result[5]),
|
||||||
self._get_technician_ids(),
|
self._get_technician_ids(),
|
||||||
self._get_technician_ping_urls(),
|
self._get_technician_ping_urls(),
|
||||||
result[5],
|
|
||||||
result[6],
|
result[6],
|
||||||
|
result[7],
|
||||||
id=result[0],
|
id=result[0],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ class TechnicianConfigSeeder(DataSeederABC):
|
|||||||
8,
|
8,
|
||||||
8,
|
8,
|
||||||
1000000,
|
1000000,
|
||||||
|
{},
|
||||||
List(int, [240160344557879316]),
|
List(int, [240160344557879316]),
|
||||||
List(str, ["www.google.com", "www.sh-edraft.de", "www.keksdose-gaming.de"]),
|
List(str, ["www.google.com", "www.sh-edraft.de", "www.keksdose-gaming.de"]),
|
||||||
)
|
)
|
||||||
|
9
kdb-bot/src/bot_graphql/model/featureFlags.gql
Normal file
9
kdb-bot/src/bot_graphql/model/featureFlags.gql
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
type FeatureFlag {
|
||||||
|
key: String
|
||||||
|
value: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
input FeatureFlagInput {
|
||||||
|
key: String
|
||||||
|
value: Boolean
|
||||||
|
}
|
@ -4,6 +4,7 @@ type TechnicianConfig implements TableWithHistoryQuery {
|
|||||||
waitForRestart: Int
|
waitForRestart: Int
|
||||||
waitForShutdown: Int
|
waitForShutdown: Int
|
||||||
cacheMaxMessages: Int
|
cacheMaxMessages: Int
|
||||||
|
featureFlags: [FeatureFlag]
|
||||||
pingURLs: [String]
|
pingURLs: [String]
|
||||||
technicianIds: [String]
|
technicianIds: [String]
|
||||||
|
|
||||||
@ -21,6 +22,7 @@ type TechnicianConfigHistory implements HistoryTableQuery {
|
|||||||
waitForRestart: Int
|
waitForRestart: Int
|
||||||
waitForShutdown: Int
|
waitForShutdown: Int
|
||||||
cacheMaxMessages: Int
|
cacheMaxMessages: Int
|
||||||
|
featureFlags: [FeatureFlag]
|
||||||
|
|
||||||
deleted: Boolean
|
deleted: Boolean
|
||||||
dateFrom: String
|
dateFrom: String
|
||||||
@ -55,6 +57,7 @@ input TechnicianConfigInput {
|
|||||||
waitForRestart: Int
|
waitForRestart: Int
|
||||||
waitForShutdown: Int
|
waitForShutdown: Int
|
||||||
cacheMaxMessages: Int
|
cacheMaxMessages: Int
|
||||||
|
featureFlags: [FeatureFlagInput]
|
||||||
pingURLs: [String]
|
pingURLs: [String]
|
||||||
technicianIds: [String]
|
technicianIds: [String]
|
||||||
}
|
}
|
@ -49,6 +49,11 @@ 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
|
||||||
)
|
)
|
||||||
|
technician_config.feature_flags = (
|
||||||
|
dict(zip([x["key"] for x in input["featureFlags"]], [x["value"] for x in input["featureFlags"]]))
|
||||||
|
if "featureFlags" in input
|
||||||
|
else technician_config.feature_flags
|
||||||
|
)
|
||||||
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
|
||||||
)
|
)
|
||||||
|
@ -9,3 +9,7 @@ class TechnicianConfigHistoryQuery(HistoryQueryABC):
|
|||||||
self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart)
|
self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart)
|
||||||
self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown)
|
self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown)
|
||||||
self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages)
|
self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages)
|
||||||
|
self.set_field(
|
||||||
|
"featureFlags",
|
||||||
|
lambda config, *_: [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags],
|
||||||
|
)
|
||||||
|
@ -16,6 +16,10 @@ class TechnicianConfigQuery(DataQueryWithHistoryABC):
|
|||||||
self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart)
|
self.set_field("waitForRestart", lambda config, *_: config.wait_for_restart)
|
||||||
self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown)
|
self.set_field("waitForShutdown", lambda config, *_: config.wait_for_shutdown)
|
||||||
self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages)
|
self.set_field("cacheMaxMessages", lambda config, *_: config.cache_max_messages)
|
||||||
|
self.set_field(
|
||||||
|
"featureFlags",
|
||||||
|
lambda config, *_: [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags],
|
||||||
|
)
|
||||||
self.set_field("pingURLs", lambda config, *_: config.ping_urls)
|
self.set_field("pingURLs", lambda config, *_: config.ping_urls)
|
||||||
self.set_field("technicianIds", lambda config, *_: config.technician_ids)
|
self.set_field("technicianIds", lambda config, *_: config.technician_ids)
|
||||||
|
|
||||||
|
4
kdb-web/src/app/models/config/feature-flags.model.ts
Normal file
4
kdb-web/src/app/models/config/feature-flags.model.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export interface FeatureFlag {
|
||||||
|
key: string;
|
||||||
|
value: boolean;
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import { DataWithHistory } from "../data/data.model";
|
import { DataWithHistory } from "../data/data.model";
|
||||||
|
import { FeatureFlag } from "./feature-flags.model";
|
||||||
|
|
||||||
export interface TechnicianConfig extends DataWithHistory {
|
export interface TechnicianConfig extends DataWithHistory {
|
||||||
id?: number;
|
id?: number;
|
||||||
@ -6,6 +7,7 @@ export interface TechnicianConfig extends DataWithHistory {
|
|||||||
waitForRestart?: number;
|
waitForRestart?: number;
|
||||||
waitForShutdown?: number;
|
waitForShutdown?: number;
|
||||||
cacheMaxMessages?: number;
|
cacheMaxMessages?: number;
|
||||||
|
featureFlags: FeatureFlag[];
|
||||||
pingURLs: string[];
|
pingURLs: string[];
|
||||||
technicianIds: string[];
|
technicianIds: string[];
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ export class Mutations {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
static updateTechnicianConfig = `
|
static updateTechnicianConfig = `
|
||||||
mutation updateTechnicianConfig($id: ID, $helpCommandReferenceUrl: String, $waitForRestart: Int, $waitForShutdown: Int, $cacheMaxMessages: Int, $pingURLs: [String], $technicianIds: [String]) {
|
mutation updateTechnicianConfig($id: ID, $helpCommandReferenceUrl: String, $waitForRestart: Int, $waitForShutdown: Int, $cacheMaxMessages: Int, $featureFlags: [FeatureFlagInput], $pingURLs: [String], $technicianIds: [String]) {
|
||||||
technicianConfig {
|
technicianConfig {
|
||||||
updateTechnicianConfig(input: {
|
updateTechnicianConfig(input: {
|
||||||
id: $id,
|
id: $id,
|
||||||
@ -175,6 +175,7 @@ export class Mutations {
|
|||||||
waitForRestart: $waitForRestart,
|
waitForRestart: $waitForRestart,
|
||||||
waitForShutdown: $waitForShutdown,
|
waitForShutdown: $waitForShutdown,
|
||||||
cacheMaxMessages: $cacheMaxMessages,
|
cacheMaxMessages: $cacheMaxMessages,
|
||||||
|
featureFlags: $featureFlags,
|
||||||
pingURLs: $pingURLs,
|
pingURLs: $pingURLs,
|
||||||
technicianIds: $technicianIds
|
technicianIds: $technicianIds
|
||||||
}) {
|
}) {
|
||||||
@ -183,6 +184,10 @@ export class Mutations {
|
|||||||
waitForRestart
|
waitForRestart
|
||||||
waitForShutdown
|
waitForShutdown
|
||||||
cacheMaxMessages
|
cacheMaxMessages
|
||||||
|
featureFlags {
|
||||||
|
key
|
||||||
|
value
|
||||||
|
}
|
||||||
pingURLs
|
pingURLs
|
||||||
technicianIds
|
technicianIds
|
||||||
}
|
}
|
||||||
|
@ -353,6 +353,10 @@ export class Queries {
|
|||||||
waitForRestart
|
waitForRestart
|
||||||
waitForShutdown
|
waitForShutdown
|
||||||
cacheMaxMessages
|
cacheMaxMessages
|
||||||
|
featureFlags {
|
||||||
|
key
|
||||||
|
value
|
||||||
|
}
|
||||||
pingURLs
|
pingURLs
|
||||||
technicianIds
|
technicianIds
|
||||||
|
|
||||||
|
@ -164,6 +164,9 @@
|
|||||||
<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>
|
||||||
|
<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"
|
||||||
(click)="saveTechnicianConfig()"></button>
|
(click)="saveTechnicianConfig()"></button>
|
||||||
|
@ -49,6 +49,7 @@ export class SettingsComponent implements OnInit {
|
|||||||
waitForRestart: 0,
|
waitForRestart: 0,
|
||||||
waitForShutdown: 0,
|
waitForShutdown: 0,
|
||||||
cacheMaxMessages: 0,
|
cacheMaxMessages: 0,
|
||||||
|
featureFlags: [],
|
||||||
pingURLs: [],
|
pingURLs: [],
|
||||||
technicianIds: []
|
technicianIds: []
|
||||||
};
|
};
|
||||||
@ -150,6 +151,7 @@ export class SettingsComponent implements OnInit {
|
|||||||
waitForRestart: this.config.waitForRestart,
|
waitForRestart: this.config.waitForRestart,
|
||||||
waitForShutdown: this.config.waitForShutdown,
|
waitForShutdown: this.config.waitForShutdown,
|
||||||
cacheMaxMessages: this.config.cacheMaxMessages,
|
cacheMaxMessages: this.config.cacheMaxMessages,
|
||||||
|
featureFlags: this.config.featureFlags,
|
||||||
pingURLs: this.config.pingURLs,
|
pingURLs: this.config.pingURLs,
|
||||||
technicianIds: this.config.technicianIds
|
technicianIds: this.config.technicianIds
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<ng-template pTemplate="body" let-value let-editing="editing" let-ri="rowIndex">
|
<ng-template pTemplate="body" let-value let-editing="editing" let-ri="rowIndex">
|
||||||
<tr [pEditableRow]="value">
|
<tr [pEditableRow]="value" style="display: flex;">
|
||||||
<td>
|
<td style="flex: 1;">
|
||||||
<p-cellEditor>
|
<p-cellEditor>
|
||||||
<ng-template pTemplate="input">
|
<ng-template pTemplate="input">
|
||||||
<input class="table-edit-input" pInputText type="text" [(ngModel)]="value.value">
|
<input class="table-edit-input" pInputText type="text" [(ngModel)]="value.value">
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
<div class="content-row">
|
||||||
|
<div class="content-column">
|
||||||
|
<div class="content-data-name">
|
||||||
|
{{'common.feature_flags' | translate}}:
|
||||||
|
</div>
|
||||||
|
<div class="content-data-value-row">
|
||||||
|
<p-table #dt [value]="internal_data" dataKey="id" editMode="row">
|
||||||
|
<ng-template pTemplate="caption">
|
||||||
|
<div class="table-caption">
|
||||||
|
<div class="table-caption-btn-wrapper btn-wrapper">
|
||||||
|
<button pButton class="icon-btn btn"
|
||||||
|
icon="pi pi-plus" (click)="addNew(dt)">
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="body" let-value let-editing="editing" let-ri="rowIndex">
|
||||||
|
<tr [pEditableRow]="value" style="display: flex;">
|
||||||
|
<td style="flex: 3;">
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
<input class="table-edit-input" pInputText type="text" [(ngModel)]="value.value.key">
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{value.value.key}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
<td style="flex: 1;">
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
<p-inputSwitch class="table-edit-input" [(ngModel)]="value.value.value"></p-inputSwitch>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
<p-inputSwitch class="table-edit-input" [(ngModel)]="value.value.value" [disabled]="true"></p-inputSwitch>
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="btn-wrapper">
|
||||||
|
<button *ngIf="!editing" pButton type="button" pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" (click)="editInit(value, ri)"></button>
|
||||||
|
<button *ngIf="!editing" pButton type="button" class="btn danger-icon-btn" icon="pi pi-trash" (click)="delete(ri)"></button>
|
||||||
|
|
||||||
|
<button *ngIf="editing" pButton type="button" pSaveEditableRow class="btn icon-btn" icon="pi pi-check" (click)="editSave(value, ri)"></button>
|
||||||
|
<button *ngIf="editing" pButton type="button" pCancelEditableRow class="btn danger-icon-btn" icon="pi pi-times"
|
||||||
|
(click)="editCancel(ri)"></button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { FeatureFlagListComponent } from './feature-flag-list.component';
|
||||||
|
|
||||||
|
describe('FeatureFlagListComponent', () => {
|
||||||
|
let component: FeatureFlagListComponent;
|
||||||
|
let fixture: ComponentFixture<FeatureFlagListComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ FeatureFlagListComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(FeatureFlagListComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,28 @@
|
|||||||
|
import { Component } from "@angular/core";
|
||||||
|
import { ConfigListComponent } from "../config-list/config-list.component";
|
||||||
|
import { Table } from "primeng/table";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-feature-flag-list",
|
||||||
|
templateUrl: "./feature-flag-list.component.html",
|
||||||
|
styleUrls: ["./feature-flag-list.component.scss"]
|
||||||
|
})
|
||||||
|
export class FeatureFlagListComponent extends ConfigListComponent {
|
||||||
|
options: boolean[] = [true, false];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
override addNew(table: Table) {
|
||||||
|
const id = Math.max.apply(Math, this.internal_data.map(value => {
|
||||||
|
return value.id ?? 0;
|
||||||
|
})) + 1;
|
||||||
|
const newItem = { id: id, value: {key: "", value: false} };
|
||||||
|
this.internal_data.push(newItem);
|
||||||
|
|
||||||
|
table.initRowEdit(newItem);
|
||||||
|
const index = this.internal_data.findIndex(l => l.id == newItem.id);
|
||||||
|
this.editInit(newItem, index);
|
||||||
|
}
|
||||||
|
}
|
@ -30,6 +30,8 @@ import { MultiSelectModule } from "primeng/multiselect";
|
|||||||
import { HideableColumnComponent } from './components/hideable-column/hideable-column.component';
|
import { HideableColumnComponent } from './components/hideable-column/hideable-column.component';
|
||||||
import { HideableHeaderComponent } from './components/hideable-header/hideable-header.component';
|
import { HideableHeaderComponent } from './components/hideable-header/hideable-header.component';
|
||||||
import { MultiSelectColumnsComponent } from './base/multi-select-columns/multi-select-columns.component';
|
import { MultiSelectColumnsComponent } from './base/multi-select-columns/multi-select-columns.component';
|
||||||
|
import { FeatureFlagListComponent } from './components/feature-flag-list/feature-flag-list.component';
|
||||||
|
import { InputSwitchModule } from "primeng/inputswitch";
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -42,6 +44,7 @@ import { MultiSelectColumnsComponent } from './base/multi-select-columns/multi-s
|
|||||||
HideableColumnComponent,
|
HideableColumnComponent,
|
||||||
HideableHeaderComponent,
|
HideableHeaderComponent,
|
||||||
MultiSelectColumnsComponent,
|
MultiSelectColumnsComponent,
|
||||||
|
FeatureFlagListComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@ -68,6 +71,7 @@ import { MultiSelectColumnsComponent } from './base/multi-select-columns/multi-s
|
|||||||
SidebarModule,
|
SidebarModule,
|
||||||
DataViewModule,
|
DataViewModule,
|
||||||
MultiSelectModule,
|
MultiSelectModule,
|
||||||
|
InputSwitchModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
ButtonModule,
|
ButtonModule,
|
||||||
@ -102,6 +106,8 @@ import { MultiSelectColumnsComponent } from './base/multi-select-columns/multi-s
|
|||||||
HideableColumnComponent,
|
HideableColumnComponent,
|
||||||
HideableHeaderComponent,
|
HideableHeaderComponent,
|
||||||
MultiSelectColumnsComponent,
|
MultiSelectColumnsComponent,
|
||||||
|
FeatureFlagListComponent,
|
||||||
|
InputSwitchModule,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SharedModule {
|
export class SharedModule {
|
||||||
|
@ -122,6 +122,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
|
"feature_flags": "Funktionen",
|
||||||
"404": "404 - Der Eintrag konnte nicht gefunden werden",
|
"404": "404 - Der Eintrag konnte nicht gefunden werden",
|
||||||
"actions": "Aktionen",
|
"actions": "Aktionen",
|
||||||
"active": "Aktiv",
|
"active": "Aktiv",
|
||||||
|
@ -587,7 +587,7 @@
|
|||||||
|
|
||||||
.p-datatable .p-sortable-column.p-highlight,
|
.p-datatable .p-sortable-column.p-highlight,
|
||||||
.p-datatable .p-sortable-column.p-highlight .p-sortable-column-icon,
|
.p-datatable .p-sortable-column.p-highlight .p-sortable-column-icon,
|
||||||
.p-datatable .p-sortable-column:not(.p-highlight):hover{
|
.p-datatable .p-sortable-column:not(.p-highlight):hover {
|
||||||
color: $primaryHeaderColor !important;
|
color: $primaryHeaderColor !important;
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
@ -672,4 +672,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-inputswitch.p-inputswitch-checked .p-inputswitch-slider {
|
||||||
|
background: $primaryHeaderColor !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-inputswitch.p-focus .p-inputswitch-slider {
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user