Reviewed-on: sh-edraft.de/kd_discord_bot#222 Reviewed-by: edraft-dev <dev.sven.heidemann@sh-edraft.de> Closes #134
This commit is contained in:
commit
c0882a8ad3
@ -32,7 +32,8 @@
|
|||||||
"cpl-discord==2022.12.2"
|
"cpl-discord==2022.12.2"
|
||||||
],
|
],
|
||||||
"DevDependencies": [
|
"DevDependencies": [
|
||||||
"cpl-cli==2022.12.1.post3"
|
"cpl-cli==2022.12.1.post3",
|
||||||
|
"pygount==1.5.1"
|
||||||
],
|
],
|
||||||
"PythonVersion": ">=3.10.4",
|
"PythonVersion": ">=3.10.4",
|
||||||
"PythonPath": {},
|
"PythonPath": {},
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit eff27f42808909a816c37f31d81f085d59d4728c
|
Subproject commit 7986144705052ff38472a5d3f0776cb6c1752a55
|
@ -89,7 +89,7 @@ class AutoRoleRule(TableABC):
|
|||||||
INSERT INTO `AutoRoleRules` (
|
INSERT INTO `AutoRoleRules` (
|
||||||
`AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `CreatedAt`, `LastModifiedAt`
|
`AutoRoleId`, `DiscordEmojiName`, `DiscordRoleId`, `CreatedAt`, `LastModifiedAt`
|
||||||
) VALUES (
|
) VALUES (
|
||||||
{self._auto_role},
|
{self._auto_role.id},
|
||||||
'{self._discord_emoji_name}',
|
'{self._discord_emoji_name}',
|
||||||
{self._discord_role_id},
|
{self._discord_role_id},
|
||||||
'{self._created_at}',
|
'{self._created_at}',
|
||||||
@ -103,8 +103,8 @@ class AutoRoleRule(TableABC):
|
|||||||
return str(
|
return str(
|
||||||
f"""
|
f"""
|
||||||
UPDATE `AutoRoleRules`
|
UPDATE `AutoRoleRules`
|
||||||
SET `AutoRoleId` = {self._auto_role},
|
SET `AutoRoleId` = {self._auto_role.id},
|
||||||
`DiscordEmojiName` = {self._discord_emoji_name},
|
`DiscordEmojiName` = '{self._discord_emoji_name}',
|
||||||
`DiscordRoleId` = {self._discord_role_id},
|
`DiscordRoleId` = {self._discord_role_id},
|
||||||
`LastModifiedAt` = '{self._modified_at}'
|
`LastModifiedAt` = '{self._modified_at}'
|
||||||
WHERE `AutoRoleRuleId` = {self._auto_role_rule_id};
|
WHERE `AutoRoleRuleId` = {self._auto_role_rule_id};
|
||||||
|
@ -45,16 +45,19 @@ class AutoRoleFilter(FilterABC):
|
|||||||
query = query.where(lambda x: x.id == self._id)
|
query = query.where(lambda x: x.id == self._id)
|
||||||
|
|
||||||
if self._channel_id is not None:
|
if self._channel_id is not None:
|
||||||
query = query.where(lambda x: x.discord_channel_id == self._channel_id)
|
|
||||||
|
|
||||||
if self._channel_name is not None and self._channel_id is not None:
|
|
||||||
query = query.where(
|
query = query.where(
|
||||||
lambda x: self._bot.get_channel(x.discord_channel_id).name == self._channel_name
|
lambda x: x.discord_channel_id == self._channel_id or str(self._channel_id) in str(x.discord_channel_id)
|
||||||
or self._channel_name in self._bot.get_channel(x.discord_channel_id).name
|
)
|
||||||
|
|
||||||
|
if self._channel_name is not None:
|
||||||
|
query = query.where(
|
||||||
|
lambda x: x.discord_channel_name == self._channel_name or self._channel_name in x.discord_channel_name
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._message_id is not None:
|
if self._message_id is not None:
|
||||||
query = query.where(lambda x: x.discord_message_id == self._message_id)
|
query = query.where(
|
||||||
|
lambda x: x.discord_message_id == self._message_id or str(self._message_id) in str(x.discord_message_id)
|
||||||
|
)
|
||||||
|
|
||||||
if self._server is not None:
|
if self._server is not None:
|
||||||
servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.id)
|
servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.id)
|
||||||
|
29
kdb-bot/src/bot_graphql/model/discord.gql
Normal file
29
kdb-bot/src/bot_graphql/model/discord.gql
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
type Guild {
|
||||||
|
id: ID
|
||||||
|
name: String
|
||||||
|
|
||||||
|
channels: [Channel]
|
||||||
|
roles: [Role]
|
||||||
|
emojis: [Emoji]
|
||||||
|
}
|
||||||
|
|
||||||
|
input GuildFilter {
|
||||||
|
id: ID
|
||||||
|
}
|
||||||
|
|
||||||
|
type Channel {
|
||||||
|
id: String
|
||||||
|
name: String
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type Role {
|
||||||
|
id: String
|
||||||
|
name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type Emoji {
|
||||||
|
id: String
|
||||||
|
name: String
|
||||||
|
url: String
|
||||||
|
}
|
@ -28,4 +28,6 @@ type Query {
|
|||||||
|
|
||||||
userCount: Int
|
userCount: Int
|
||||||
users(filter: UserFilter, page: Page, sort: Sort): [User]
|
users(filter: UserFilter, page: Page, sort: Sort): [User]
|
||||||
|
|
||||||
|
guilds(filter: GuildFilter): [Guild]
|
||||||
}
|
}
|
@ -35,9 +35,9 @@ class AutoRoleRuleMutation(QueryABC):
|
|||||||
|
|
||||||
def get_new(x: AutoRoleRule):
|
def get_new(x: AutoRoleRule):
|
||||||
return (
|
return (
|
||||||
x.auto_role.id == input["autoRoleId"]
|
x.auto_role.id == int(input["autoRoleId"])
|
||||||
and x.emoji_name == input["emojiName"]
|
and x.emoji_name == input["emojiName"]
|
||||||
and x.role_id == input["roleId"]
|
and x.role_id == int(input["roleId"])
|
||||||
)
|
)
|
||||||
|
|
||||||
return self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role_rule.auto_role.id).where(get_new).last()
|
return self._auto_roles.get_auto_role_rules_by_auto_role_id(auto_role_rule.auto_role.id).where(get_new).last()
|
||||||
|
0
kdb-bot/src/bot_graphql/queries/discord/__init__.py
Normal file
0
kdb-bot/src/bot_graphql/queries/discord/__init__.py
Normal file
10
kdb-bot/src/bot_graphql/queries/discord/channel_query.py
Normal file
10
kdb-bot/src/bot_graphql/queries/discord/channel_query.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from bot_graphql.abc.data_query_abc import DataQueryABC
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelQuery(DataQueryABC):
|
||||||
|
def __init__(self):
|
||||||
|
DataQueryABC.__init__(self, "Channel")
|
||||||
|
|
||||||
|
self.set_field("id", lambda c, *_: c.id)
|
||||||
|
self.set_field("name", lambda c, *_: c.name)
|
||||||
|
self.set_field("type", lambda c, *_: type(c))
|
10
kdb-bot/src/bot_graphql/queries/discord/emoji_query.py
Normal file
10
kdb-bot/src/bot_graphql/queries/discord/emoji_query.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from bot_graphql.abc.data_query_abc import DataQueryABC
|
||||||
|
|
||||||
|
|
||||||
|
class RoleQuery(DataQueryABC):
|
||||||
|
def __init__(self):
|
||||||
|
DataQueryABC.__init__(self, "Emoji")
|
||||||
|
|
||||||
|
self.set_field("id", lambda e, *_: e.id)
|
||||||
|
self.set_field("name", lambda e, *_: e.name)
|
||||||
|
self.set_field("url", lambda e, *_: e.url)
|
12
kdb-bot/src/bot_graphql/queries/discord/guild_query.py
Normal file
12
kdb-bot/src/bot_graphql/queries/discord/guild_query.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from bot_graphql.abc.data_query_abc import DataQueryABC
|
||||||
|
|
||||||
|
|
||||||
|
class GuildQuery(DataQueryABC):
|
||||||
|
def __init__(self):
|
||||||
|
DataQueryABC.__init__(self, "Guild")
|
||||||
|
|
||||||
|
self.set_field("id", lambda g, *_: g.id)
|
||||||
|
self.set_field("name", lambda g, *_: g.name)
|
||||||
|
self.set_field("channels", lambda g, *_: g.channels)
|
||||||
|
self.set_field("roles", lambda g, *_: g.roles)
|
||||||
|
self.set_field("emojis", lambda g, *_: g.emojis)
|
9
kdb-bot/src/bot_graphql/queries/discord/role_query.py
Normal file
9
kdb-bot/src/bot_graphql/queries/discord/role_query.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from bot_graphql.abc.data_query_abc import DataQueryABC
|
||||||
|
|
||||||
|
|
||||||
|
class RoleQuery(DataQueryABC):
|
||||||
|
def __init__(self):
|
||||||
|
DataQueryABC.__init__(self, "Role")
|
||||||
|
|
||||||
|
self.set_field("id", lambda r, *_: r.id)
|
||||||
|
self.set_field("name", lambda r, *_: r.name)
|
@ -1,3 +1,5 @@
|
|||||||
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
|
|
||||||
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
|
||||||
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
||||||
@ -22,44 +24,46 @@ from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceC
|
|||||||
class Query(QueryABC):
|
class Query(QueryABC):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
bot: DiscordBotServiceABC,
|
||||||
auto_roles: AutoRoleRepositoryABC,
|
auto_roles: AutoRoleRepositoryABC,
|
||||||
clients: ClientRepositoryABC,
|
clients: ClientRepositoryABC,
|
||||||
known_users: KnownUserRepositoryABC,
|
known_users: KnownUserRepositoryABC,
|
||||||
levels: LevelRepositoryABC,
|
levels: LevelRepositoryABC,
|
||||||
servers: ServerRepositoryABC,
|
servers: ServerRepositoryABC,
|
||||||
user_joined_servers: UserJoinedServerRepositoryABC,
|
user_joined_servers: UserJoinedServerRepositoryABC,
|
||||||
user_joined_voice_channel: UserJoinedVoiceChannelRepositoryABC,
|
user_joined_voice_channels: UserJoinedVoiceChannelRepositoryABC,
|
||||||
user_joined_game_server: UserJoinedGameServerRepositoryABC,
|
user_joined_game_server: UserJoinedGameServerRepositoryABC,
|
||||||
users: UserRepositoryABC,
|
users: UserRepositoryABC,
|
||||||
):
|
):
|
||||||
QueryABC.__init__(self, "Query")
|
QueryABC.__init__(self, "Query")
|
||||||
self._auto_roles = auto_roles
|
|
||||||
self._clients = clients
|
|
||||||
self._known_users = known_users
|
|
||||||
self._levels = levels
|
|
||||||
self._servers = servers
|
|
||||||
self._user_joined_servers = user_joined_servers
|
|
||||||
self._user_joined_voice_channels = user_joined_voice_channel
|
|
||||||
self._user_joined_game_server = user_joined_game_server
|
|
||||||
self._users = users
|
|
||||||
|
|
||||||
self.add_collection("autoRole", lambda *_: self._auto_roles.get_auto_roles(), AutoRoleFilter)
|
self._bot = bot
|
||||||
self.add_collection("autoRoleRule", lambda *_: self._auto_roles.get_auto_role_rules(), AutoRoleRuleFilter)
|
|
||||||
self.add_collection("client", lambda *_: self._clients.get_clients(), ClientFilter)
|
self.add_collection("autoRole", lambda *_: auto_roles.get_auto_roles(), AutoRoleFilter)
|
||||||
self.add_collection("knownUser", lambda *_: self._known_users.get_users())
|
self.add_collection("autoRoleRule", lambda *_: auto_roles.get_auto_role_rules(), AutoRoleRuleFilter)
|
||||||
self.add_collection("level", lambda *_: self._levels.get_levels(), LevelFilter)
|
self.add_collection("client", lambda *_: clients.get_clients(), ClientFilter)
|
||||||
self.add_collection("server", lambda *_: self._servers.get_servers(), ServerFilter)
|
self.add_collection("knownUser", lambda *_: known_users.get_users())
|
||||||
|
self.add_collection("level", lambda *_: levels.get_levels(), LevelFilter)
|
||||||
|
self.add_collection("server", lambda *_: servers.get_servers(), ServerFilter)
|
||||||
self.add_collection(
|
self.add_collection(
|
||||||
"userJoinedServer", lambda *_: self._user_joined_servers.get_user_joined_servers(), UserJoinedServerFilter
|
"userJoinedServer", lambda *_: user_joined_servers.get_user_joined_servers(), UserJoinedServerFilter
|
||||||
)
|
)
|
||||||
self.add_collection(
|
self.add_collection(
|
||||||
"userJoinedVoiceChannel",
|
"userJoinedVoiceChannel",
|
||||||
lambda *_: self._user_joined_voice_channels.get_user_joined_voice_channels(),
|
lambda *_: user_joined_voice_channels.get_user_joined_voice_channels(),
|
||||||
UserJoinedVoiceChannelFilter,
|
UserJoinedVoiceChannelFilter,
|
||||||
)
|
)
|
||||||
self.add_collection(
|
self.add_collection(
|
||||||
"userJoinedGameServer",
|
"userJoinedGameServer",
|
||||||
lambda *_: self._user_joined_game_server.get_user_joined_game_servers(),
|
lambda *_: user_joined_game_server.get_user_joined_game_servers(),
|
||||||
UserJoinedGameServerFilter,
|
UserJoinedGameServerFilter,
|
||||||
)
|
)
|
||||||
self.add_collection("user", lambda *_: self._users.get_users(), UserFilter)
|
self.add_collection("user", lambda *_: users.get_users(), UserFilter)
|
||||||
|
|
||||||
|
self.set_field("guilds", self._resolve_guilds)
|
||||||
|
|
||||||
|
def _resolve_guilds(self, *_, filter=None):
|
||||||
|
if filter is None or "id" not in filter:
|
||||||
|
return self._bot.guilds
|
||||||
|
|
||||||
|
return self._bot.guilds.where(lambda g: g.id == int(filter["id"]))
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "kdb-web",
|
"name": "kdb-web",
|
||||||
"version": "1.0.dev130",
|
"version": "1.0.dev134",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"update-version": "ts-node-esm update-version.ts",
|
"update-version": "ts-node-esm update-version.ts",
|
||||||
|
@ -13,8 +13,8 @@ import { SpinnerService } from "src/app/services/spinner/spinner.service";
|
|||||||
export class FooterComponent implements OnInit {
|
export class FooterComponent implements OnInit {
|
||||||
|
|
||||||
|
|
||||||
frontendVersion!: SoftwareVersion;
|
frontendVersion: SoftwareVersion = new SoftwareVersion("0", "0", "0");
|
||||||
backendVersion!: SoftwareVersion;
|
backendVersion: SoftwareVersion = new SoftwareVersion("0", "0", "0");
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private settings: SettingsService,
|
private settings: SettingsService,
|
||||||
|
36
kdb-web/src/app/models/data/auto_role.model.ts
Normal file
36
kdb-web/src/app/models/data/auto_role.model.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { Data } from "./data.model";
|
||||||
|
import { Server, ServerFilter } from "./server.model";
|
||||||
|
|
||||||
|
export interface AutoRole extends Data {
|
||||||
|
id?: number;
|
||||||
|
channelId?: string;
|
||||||
|
channelName?: string;
|
||||||
|
messageId?: string;
|
||||||
|
server?: Server;
|
||||||
|
|
||||||
|
autoRoleRuleCount?: number;
|
||||||
|
autoRoleRules?: AutoRoleRule[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AutoRoleFilter {
|
||||||
|
id?: number;
|
||||||
|
channelId?: string;
|
||||||
|
channelName?: string;
|
||||||
|
messageId?: string;
|
||||||
|
server?: ServerFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AutoRoleRule extends Data {
|
||||||
|
id?: number;
|
||||||
|
emojiName?: string;
|
||||||
|
roleId?: string;
|
||||||
|
roleName?: string;
|
||||||
|
autoRole?: AutoRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AutoRoleRuleFilter {
|
||||||
|
id?: number;
|
||||||
|
emojiName?: string;
|
||||||
|
roleId?: string;
|
||||||
|
autoRole?: AutoRoleFilter;
|
||||||
|
}
|
31
kdb-web/src/app/models/data/discord.model.ts
Normal file
31
kdb-web/src/app/models/data/discord.model.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
export interface Guild {
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
|
||||||
|
channels: [Channel]
|
||||||
|
roles: [Role]
|
||||||
|
emojis: [Emoji]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Channel {
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
type?: ChannelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ChannelType {
|
||||||
|
category = "category",
|
||||||
|
text = "text",
|
||||||
|
voice = "voice"
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Role {
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Emoji {
|
||||||
|
id?: string;
|
||||||
|
name?: string;
|
||||||
|
url?: string;
|
||||||
|
}
|
@ -2,6 +2,7 @@ import {Data} from "./data.model";
|
|||||||
import {User} from "./user.model";
|
import {User} from "./user.model";
|
||||||
import {Level} from "./level.model";
|
import {Level} from "./level.model";
|
||||||
import {Client} from "./client.model";
|
import {Client} from "./client.model";
|
||||||
|
import { AutoRole } from "./auto_role.model";
|
||||||
|
|
||||||
export interface Server extends Data {
|
export interface Server extends Data {
|
||||||
id?: number;
|
id?: number;
|
||||||
@ -9,7 +10,7 @@ export interface Server extends Data {
|
|||||||
name?: string;
|
name?: string;
|
||||||
iconURL?: string;
|
iconURL?: string;
|
||||||
autoRoleCount?: number;
|
autoRoleCount?: number;
|
||||||
autoRoles?: [];
|
autoRoles?: AutoRole[];
|
||||||
clientCount?: number;
|
clientCount?: number;
|
||||||
clients?: Client[];
|
clients?: Client[];
|
||||||
levelCount?: number;
|
levelCount?: number;
|
||||||
|
@ -14,4 +14,69 @@ export class Mutations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
static createAutoRole = `
|
||||||
|
mutation createAutoRole($serverId: ID, $channelId: String, $messageId: String) {
|
||||||
|
autoRole {
|
||||||
|
createAutoRole(input: { serverId: $serverId, channelId: $channelId, messageId: $messageId }) {
|
||||||
|
id
|
||||||
|
channelId
|
||||||
|
channelName
|
||||||
|
messageId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
static deleteAutoRole = `
|
||||||
|
mutation deleteAutoRole($id: ID) {
|
||||||
|
autoRole {
|
||||||
|
deleteAutoRole(id: $id) {
|
||||||
|
id
|
||||||
|
channelId
|
||||||
|
channelName
|
||||||
|
messageId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
static createAutoRoleRule = `
|
||||||
|
mutation createAutoRoleRule($autoRoleId: ID, $emojiName: String, $roleId: String) {
|
||||||
|
autoRoleRule {
|
||||||
|
createAutoRoleRule(input: { autoRoleId: $autoRoleId, emojiName: $emojiName, roleId: $roleId }) {
|
||||||
|
id
|
||||||
|
emojiName
|
||||||
|
roleId
|
||||||
|
roleName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
static updateAutoRoleRule = `
|
||||||
|
mutation updateAutoRoleRule($id: ID, $emojiName: String, $roleId: String) {
|
||||||
|
autoRoleRule {
|
||||||
|
updateAutoRoleRule(input: { id: $id, emojiName: $emojiName, roleId: $roleId }) {
|
||||||
|
id
|
||||||
|
emojiName
|
||||||
|
roleId
|
||||||
|
roleName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
static deleteAutoRoleRule = `
|
||||||
|
mutation deleteAutoRoleRule($id: ID) {
|
||||||
|
autoRoleRule {
|
||||||
|
deleteAutoRoleRule(id: $id) {
|
||||||
|
id
|
||||||
|
emojiName
|
||||||
|
roleId
|
||||||
|
roleName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,29 @@
|
|||||||
export class Queries {
|
export class Queries {
|
||||||
|
|
||||||
|
static guildsQuery = `
|
||||||
|
query GuildsQuery($id: ID) {
|
||||||
|
guilds(filter: {id: $id}) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
|
||||||
|
channels {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
type
|
||||||
|
}
|
||||||
|
roles {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
emojis {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
static serversQuery = `
|
static serversQuery = `
|
||||||
query ServerInfo($filter: ServerFilter, $page: Page, $sort: Sort) {
|
query ServerInfo($filter: ServerFilter, $page: Page, $sort: Sort) {
|
||||||
servers(filter: $filter, page: $page, sort: $sort) {
|
servers(filter: $filter, page: $page, sort: $sort) {
|
||||||
@ -131,4 +155,49 @@ export class Queries {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
static autoRolesQuery = `
|
||||||
|
query AutoRoleQuery($serverId: ID, $filter: AutoRoleFilter, $page: Page, $sort: Sort) {
|
||||||
|
servers(filter: {id: $serverId}) {
|
||||||
|
autoRoleCount
|
||||||
|
autoRoles(filter: $filter, page: $page, sort: $sort) {
|
||||||
|
id
|
||||||
|
channelId
|
||||||
|
channelName
|
||||||
|
messageId
|
||||||
|
autoRoleRuleCount
|
||||||
|
|
||||||
|
server {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
|
||||||
|
createdAt
|
||||||
|
modifiedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
static autoRoleRulesQuery = `
|
||||||
|
query AutoRoleRuleQuery($serverId: ID, $autoRoleId: ID, $filter: AutoRoleRuleFilter, $page: Page, $sort: Sort) {
|
||||||
|
servers(filter: {id: $serverId}) {
|
||||||
|
autoRoles(filter: {id: $autoRoleId}) {
|
||||||
|
autoRoleRuleCount
|
||||||
|
autoRoleRules(filter: $filter, page: $page, sort: $sort) {
|
||||||
|
id
|
||||||
|
emojiName
|
||||||
|
roleId
|
||||||
|
roleName
|
||||||
|
|
||||||
|
autoRole {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
|
||||||
|
createdAt
|
||||||
|
modifiedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
import { Server } from "../data/server.model";
|
import { Server } from "../data/server.model";
|
||||||
import { User } from "../data/user.model";
|
import { User } from "../data/user.model";
|
||||||
|
import { AutoRole, AutoRoleRule } from "../data/auto_role.model";
|
||||||
|
import { Guild } from "../data/discord.model";
|
||||||
|
import { Level } from "../data/level.model";
|
||||||
|
|
||||||
export interface Query {
|
export interface Query {
|
||||||
serverCount: number;
|
serverCount: number;
|
||||||
servers: Server[];
|
servers: Server[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SingleDiscordQuery {
|
||||||
|
guilds: Guild[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface UserListQuery {
|
export interface UserListQuery {
|
||||||
userCount: number;
|
userCount: number;
|
||||||
users: User[];
|
users: User[];
|
||||||
@ -13,6 +20,16 @@ export interface UserListQuery {
|
|||||||
|
|
||||||
export interface LevelListQuery {
|
export interface LevelListQuery {
|
||||||
levelCount: number;
|
levelCount: number;
|
||||||
levels: User[];
|
levels: Level[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AutoRoleQuery {
|
||||||
|
autoRoleCount: number;
|
||||||
|
autoRoles: AutoRole[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AutoRoleRuleQuery {
|
||||||
|
autoRoleRuleCount: number;
|
||||||
|
autoRoleRules: AutoRoleRule[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
import { User } from "../data/user.model";
|
import { User } from "../data/user.model";
|
||||||
|
import { AutoRole, AutoRoleRule } from "../data/auto_role.model";
|
||||||
|
|
||||||
|
export interface GraphQLResult {
|
||||||
|
data: any;
|
||||||
|
errors?: [];
|
||||||
|
}
|
||||||
|
|
||||||
export interface QueryResult {
|
export interface QueryResult {
|
||||||
data: any;
|
data: any;
|
||||||
@ -9,3 +15,19 @@ export interface UpdateUserMutationResult {
|
|||||||
updateUser: User
|
updateUser: User
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AutoRoleMutationResult {
|
||||||
|
autoRole: {
|
||||||
|
createAutoRole?: AutoRole
|
||||||
|
updateAutoRole?: AutoRole
|
||||||
|
deleteAutoRole?: AutoRole
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AutoRoleRuleMutationResult {
|
||||||
|
autoRoleRule: {
|
||||||
|
createAutoRoleRule?: AutoRoleRule
|
||||||
|
updateAutoRoleRule?: AutoRoleRule
|
||||||
|
deleteAutoRoleRule?: AutoRoleRule
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -5,4 +5,5 @@ export interface Variables {
|
|||||||
filter?: object;
|
filter?: object;
|
||||||
page?: Page;
|
page?: Page;
|
||||||
sort?: Sort;
|
sort?: Sort;
|
||||||
|
[x: string | number | symbol]: unknown;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
icon="pi pi-user-plus" (click)="addUser(dt)" [disabled]="isEditingNew">
|
icon="pi pi-user-plus" (click)="addUser(dt)" [disabled]="isEditingNew">
|
||||||
</button>
|
</button>
|
||||||
<button pButton label="{{'admin.auth_users.reset_filters' | translate}}" icon="pi pi-undo"
|
<button pButton label="{{'admin.auth_users.reset_filters' | translate}}" icon="pi pi-undo"
|
||||||
class="icon-btn btn" (click)="resetFilters(dt)">
|
class="icon-btn btn" (click)="resetFilters()">
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { catchError, debounceTime, last } from 'rxjs/operators';
|
import { catchError, debounceTime } from "rxjs/operators";
|
||||||
import { AuthRoles } from 'src/app/models/auth/auth-roles.enum';
|
import { AuthRoles } from "src/app/models/auth/auth-roles.enum";
|
||||||
import { AuthUserDTO } from 'src/app/models/auth/auth-user.dto';
|
import { AuthUserDTO } from "src/app/models/auth/auth-user.dto";
|
||||||
import { AuthService } from 'src/app/services/auth/auth.service';
|
import { AuthService } from "src/app/services/auth/auth.service";
|
||||||
import { ConfirmationDialogService } from 'src/app/services/confirmation-dialog/confirmation-dialog.service';
|
import { ConfirmationDialogService } from "src/app/services/confirmation-dialog/confirmation-dialog.service";
|
||||||
import { SpinnerService } from 'src/app/services/spinner/spinner.service';
|
import { SpinnerService } from "src/app/services/spinner/spinner.service";
|
||||||
import { ToastService } from 'src/app/services/toast/toast.service';
|
import { ToastService } from "src/app/services/toast/toast.service";
|
||||||
import { Table } from 'primeng/table';
|
import { Table } from "primeng/table";
|
||||||
import { ServiceErrorCode } from 'src/app/models/error/service-error-code.enum';
|
import { ServiceErrorCode } from "src/app/models/error/service-error-code.enum";
|
||||||
import { RegisterErrorMessages } from 'src/app/models/auth/register-error-messages.enum';
|
import { RegisterErrorMessages } from "src/app/models/auth/register-error-messages.enum";
|
||||||
import { ErrorDTO } from 'src/app/models/error/error-dto';
|
import { ErrorDTO } from "src/app/models/error/error-dto";
|
||||||
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
import { FormBuilder, FormControl, FormGroup } from "@angular/forms";
|
||||||
import { AuthUserSelectCriterion } from 'src/app/models/selection/auth-user/auth-user-select-criterion.dto';
|
import { AuthUserSelectCriterion } from "src/app/models/selection/auth-user/auth-user-select-criterion.dto";
|
||||||
import { LazyLoadEvent } from 'primeng/api';
|
import { LazyLoadEvent } from "primeng/api";
|
||||||
import { throwError } from 'rxjs';
|
import { throwError } from "rxjs";
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -162,7 +162,7 @@ export class AuthUserComponent implements OnInit {
|
|||||||
this.loadNextPage();
|
this.loadNextPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
resetFilters(table: Table) {
|
resetFilters() {
|
||||||
this.filterForm.reset();
|
this.filterForm.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +309,6 @@ export class AuthUserComponent implements OnInit {
|
|||||||
addUser(table: Table) {
|
addUser(table: Table) {
|
||||||
const newUser = JSON.parse(JSON.stringify(this.newUserTemplate));
|
const newUser = JSON.parse(JSON.stringify(this.newUserTemplate));
|
||||||
newUser.id = Math.max.apply(Math, this.users.map(u => { return u.id ?? 0; })) + 1;
|
newUser.id = Math.max.apply(Math, this.users.map(u => { return u.id ?? 0; })) + 1;
|
||||||
console.log(newUser);
|
|
||||||
|
|
||||||
this.users.push(newUser);
|
this.users.push(newUser);
|
||||||
this.triggerUserChangeDetection();
|
this.triggerUserChangeDetection();
|
||||||
|
@ -20,6 +20,8 @@ import { IpAddressPipe } from './pipes/ip-address.pipe';
|
|||||||
import { BoolPipe } from './pipes/bool.pipe';
|
import { BoolPipe } from './pipes/bool.pipe';
|
||||||
import { PanelMenuModule } from 'primeng/panelmenu';
|
import { PanelMenuModule } from 'primeng/panelmenu';
|
||||||
import { PanelModule } from "primeng/panel";
|
import { PanelModule } from "primeng/panel";
|
||||||
|
import { InputNumberModule } from 'primeng/inputnumber';
|
||||||
|
import { ImageModule } from "primeng/image";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +51,8 @@ import { PanelModule } from "primeng/panel";
|
|||||||
DynamicDialogModule,
|
DynamicDialogModule,
|
||||||
PanelMenuModule,
|
PanelMenuModule,
|
||||||
PanelModule,
|
PanelModule,
|
||||||
|
InputNumberModule,
|
||||||
|
ImageModule
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
ButtonModule,
|
ButtonModule,
|
||||||
@ -72,6 +76,8 @@ import { PanelModule } from "primeng/panel";
|
|||||||
AuthRolePipe,
|
AuthRolePipe,
|
||||||
IpAddressPipe,
|
IpAddressPipe,
|
||||||
BoolPipe,
|
BoolPipe,
|
||||||
|
InputNumberModule,
|
||||||
|
ImageModule
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SharedModule { }
|
export class SharedModule { }
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
import { NgModule } from "@angular/core";
|
||||||
|
import { RouterModule, Routes } from "@angular/router";
|
||||||
|
import { AutoRolesComponent } from "./components/auto-roles/auto-roles.component";
|
||||||
|
import { AutoRolesRulesComponent } from "./components/auto-roles-rules/auto-roles-rules.component";
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
|
||||||
|
{ path: "", component: AutoRolesComponent },
|
||||||
|
{ path: ":autoRoleId/rules", component: AutoRolesRulesComponent }
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(routes)],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
export class AutoRoleRoutingModule {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
import { NgModule } from "@angular/core";
|
||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
|
||||||
|
import { AutoRoleRoutingModule } from "./auto-role-routing.module";
|
||||||
|
import { AutoRolesComponent } from "./components/auto-roles/auto-roles.component";
|
||||||
|
import { AutoRolesRulesComponent } from "./components/auto-roles-rules/auto-roles-rules.component";
|
||||||
|
import { SharedModule } from "../../../shared/shared.module";
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AutoRolesComponent,
|
||||||
|
AutoRolesRulesComponent
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
AutoRoleRoutingModule,
|
||||||
|
SharedModule,
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class AutoRoleModule { }
|
@ -0,0 +1,188 @@
|
|||||||
|
<h1>
|
||||||
|
{{'view.server.auto_roles.rules.header' | translate}}
|
||||||
|
</h1>
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div class="content">
|
||||||
|
<p-table #dt [value]="rules" dataKey="id" editMode="row" [rowHover]="true" [rows]="10"
|
||||||
|
[rowsPerPageOptions]="[10,25,50]" [paginator]="true" [loading]="loading" [totalRecords]="totalRecords"
|
||||||
|
[lazy]="true" (onLazyLoad)="nextPage($event)">
|
||||||
|
|
||||||
|
<ng-template pTemplate="caption">
|
||||||
|
<div class="table-caption">
|
||||||
|
<div class="table-caption-text">
|
||||||
|
<ng-container *ngIf="!loading">{{rules.length}} {{'view.server.auto_roles.rules.of' | translate}}
|
||||||
|
{{dt.totalRecords}}
|
||||||
|
</ng-container>
|
||||||
|
{{'view.server.auto_roles.rules.auto_roles' | translate}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-caption-btn-wrapper btn-wrapper">
|
||||||
|
<button pButton label="{{'admin.auth_users.add' | translate}}" class="icon-btn btn"
|
||||||
|
icon="pi pi-user-plus" (click)="addAutoRoleRule(dt)" [disabled]="isEditingNew">
|
||||||
|
</button>
|
||||||
|
<button pButton label="{{'view.server.auto_roles.rules.reset_filters' | translate}}" icon="pi pi-undo"
|
||||||
|
class="icon-btn btn" (click)="resetFilters()">
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="header">
|
||||||
|
<tr>
|
||||||
|
<th pSortableColumn="id">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.auto_roles.rules.headers.id' | translate}}</div>
|
||||||
|
<p-sortIcon field="id" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th pSortableColumn="roleName">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.auto_roles.rules.headers.role' | translate}}</div>
|
||||||
|
<p-sortIcon field="roleName" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.auto_roles.rules.headers.emoji' | translate}}</div>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'common.created_at' | translate}}</div>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'common.modified_at' | translate}}</div>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.auto_roles.rules.headers.actions' | translate}}</div>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th class="table-header-small">
|
||||||
|
<form [formGroup]="filterForm">
|
||||||
|
<input type="text" pInputText formControlName="id" placeholder="{{'view.server.auto_roles.rules.headers.id' | translate}}">
|
||||||
|
</form>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<form [formGroup]="filterForm">
|
||||||
|
<input type="text" pInputText formControlName="roleId" placeholder="{{'view.server.auto_roles.rules.headers.role' | translate}}">
|
||||||
|
</form>
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
<th class="table-header-small-dropdown"></th>
|
||||||
|
<th class="table-header-small-dropdown"></th>
|
||||||
|
<th class="table-header-actions"></th>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="body" let-autoRoleRule let-editing="editing" let-ri="rowIndex">
|
||||||
|
<tr [pEditableRow]="autoRoleRule">
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{autoRoleRule.id}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{autoRoleRule.id}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
<p-dropdown [options]="roles" optionValue="value.id" [(ngModel)]="autoRoleRule.roleId"
|
||||||
|
placeholder="{{'view.server.auto_roles.rules.headers.role' | translate}}"></p-dropdown>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{autoRoleRule.roleName}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
<p-dropdown [options]="emojis" optionValue="value.name" [(ngModel)]="autoRoleRule.emojiName"
|
||||||
|
placeholder="{{'view.server.auto_roles.rules.headers.emoji' | translate}}">
|
||||||
|
<ng-template pTemplate="selectedItem">
|
||||||
|
<div class="dropdown-icon-label-wrapper" *ngIf="autoRoleRule.emojiName">
|
||||||
|
<p-image [src]="getEmojiUrl(autoRoleRule.emojiName)" [alt]="autoRoleRule.emojiName" width="25"></p-image>
|
||||||
|
<div>{{autoRoleRule.emojiName}}</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template let-emoji pTemplate="item">
|
||||||
|
<div class="dropdown-icon-label-wrapper">
|
||||||
|
<p-image [src]="emoji.value.url" [alt]="emoji.label" width="25"></p-image>
|
||||||
|
<div>{{emoji.label}}</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</p-dropdown>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
<p-image [src]="getEmojiUrl(autoRoleRule.emojiName)" [alt]="autoRoleRule.emojiName" width="50"></p-image>
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{autoRoleRule.createdAt | date:'dd.MM.yy HH:mm'}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{autoRoleRule.createdAt | date:'dd.MM.yy HH:mm'}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{autoRoleRule.modifiedAt | date:'dd.MM.yy HH:mm'}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{autoRoleRule.modifiedAt | date:'dd.MM.yy HH:mm'}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div class="btn-wrapper">
|
||||||
|
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil" (click)="onRowEditInit(dt, autoRoleRule, ri)"></button>
|
||||||
|
<button *ngIf="!editing" pButton class="btn icon-btn danger-icon-btn" icon="pi pi-trash"
|
||||||
|
(click)="deleteAutoRoleRule(autoRoleRule)"></button>
|
||||||
|
|
||||||
|
<button *ngIf="editing" pButton pSaveEditableRow class="btn icon-btn"
|
||||||
|
icon="pi pi-check-circle" (click)="onRowEditSave(dt, autoRoleRule, ri)"></button>
|
||||||
|
<button *ngIf="editing" pButton pCancelEditableRow class="btn icon-btn danger-icon-btn"
|
||||||
|
icon="pi pi-times-circle" (click)="onRowEditCancel(ri)"></button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="emptymessage">
|
||||||
|
<tr></tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="10">{{'view.server.auto_roles.rules.no_entries_found' | translate}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr></tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="paginatorleft">
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AutoRolesRulesComponent } from './auto-roles-rules.component';
|
||||||
|
|
||||||
|
describe('AutoRolesRulesComponent', () => {
|
||||||
|
let component: AutoRolesRulesComponent;
|
||||||
|
let fixture: ComponentFixture<AutoRolesRulesComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ AutoRolesRulesComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(AutoRolesRulesComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,290 @@
|
|||||||
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
import { DataService } from "../../../../../../services/data/data.service";
|
||||||
|
import { ActivatedRoute, Router } from "@angular/router";
|
||||||
|
import { AutoRoleRule, AutoRoleRuleFilter } from "../../../../../../models/data/auto_role.model";
|
||||||
|
import { Guild } from "../../../../../../models/data/discord.model";
|
||||||
|
import { LazyLoadEvent, MenuItem } from "primeng/api";
|
||||||
|
import { User } from "../../../../../../models/data/user.model";
|
||||||
|
import { FormBuilder, FormControl, FormGroup } from "@angular/forms";
|
||||||
|
import { Page } from "../../../../../../models/graphql/filter/page.model";
|
||||||
|
import { Sort, SortDirection } from "../../../../../../models/graphql/filter/sort.model";
|
||||||
|
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 { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { SidebarService } from "../../../../../../services/sidebar/sidebar.service";
|
||||||
|
import { AutoRoleRuleQuery, SingleDiscordQuery } from "../../../../../../models/graphql/query.model";
|
||||||
|
import { Queries } from "../../../../../../models/graphql/queries.model";
|
||||||
|
import { Server } from "../../../../../../models/data/server.model";
|
||||||
|
import { catchError, debounceTime } from "rxjs/operators";
|
||||||
|
import { Table } from "primeng/table";
|
||||||
|
import { AutoRoleMutationResult, AutoRoleRuleMutationResult } from "../../../../../../models/graphql/result.model";
|
||||||
|
import { Mutations } from "../../../../../../models/graphql/mutations.model";
|
||||||
|
import { throwError } from "rxjs";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-auto-roles-rules",
|
||||||
|
templateUrl: "./auto-roles-rules.component.html",
|
||||||
|
styleUrls: ["./auto-roles-rules.component.scss"]
|
||||||
|
})
|
||||||
|
export class AutoRolesRulesComponent implements OnInit {
|
||||||
|
|
||||||
|
rules!: AutoRoleRule[];
|
||||||
|
guild!: Guild;
|
||||||
|
emojis: MenuItem[] = [];
|
||||||
|
roles: MenuItem[] = [];
|
||||||
|
loading = true;
|
||||||
|
|
||||||
|
autoRoleId!: number;
|
||||||
|
|
||||||
|
clonedUsers: { [s: string]: User; } = {};
|
||||||
|
isEditingNew: boolean = false;
|
||||||
|
|
||||||
|
newAutoRoleTemplate: AutoRoleRule = {
|
||||||
|
id: 0,
|
||||||
|
createdAt: "",
|
||||||
|
modifiedAt: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
filterForm!: FormGroup<{
|
||||||
|
id: FormControl<number | null>,
|
||||||
|
emojiName: FormControl<string | null>,
|
||||||
|
roleId: FormControl<string | null>,
|
||||||
|
}>;
|
||||||
|
|
||||||
|
filter: AutoRoleRuleFilter = {};
|
||||||
|
page: Page = {
|
||||||
|
pageSize: undefined,
|
||||||
|
pageIndex: undefined
|
||||||
|
};
|
||||||
|
sort: Sort = {
|
||||||
|
sortColumn: undefined,
|
||||||
|
sortDirection: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
totalRecords!: number;
|
||||||
|
|
||||||
|
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,
|
||||||
|
private router: Router
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public getEmojiUrl(name: string): string {
|
||||||
|
return this.guild?.emojis.filter(x => x.name == name)[0].url ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnInit(): void {
|
||||||
|
this.data.getServerFromRoute(this.route);
|
||||||
|
this.spinner.showSpinner();
|
||||||
|
if (!this.route.snapshot.params["autoRoleId"]) {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.router.navigate(["../"]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.autoRoleId = +this.route.snapshot.params["autoRoleId"];
|
||||||
|
|
||||||
|
this.spinner.showSpinner();
|
||||||
|
this.data.query<SingleDiscordQuery>(Queries.guildsQuery, {
|
||||||
|
filter: {
|
||||||
|
id: this.sidebar.server$.value?.discordId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).subscribe(data => {
|
||||||
|
this.guild = data.guilds[0];
|
||||||
|
this.emojis = this.guild.emojis
|
||||||
|
.map(x => {
|
||||||
|
return { label: x.name, value: x };
|
||||||
|
});
|
||||||
|
this.roles = this.guild.roles
|
||||||
|
.map(x => {
|
||||||
|
return { label: x.name, value: x };
|
||||||
|
});
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setFilterForm();
|
||||||
|
this.loadNextPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public loadNextPage(): void {
|
||||||
|
this.loading = true;
|
||||||
|
this.data.query<AutoRoleRuleQuery>(Queries.autoRoleRulesQuery, {
|
||||||
|
id: this.sidebar.server$.value?.id, filter: this.filter, page: this.page, sort: this.sort
|
||||||
|
},
|
||||||
|
(x: { servers: Server[] }) => {
|
||||||
|
if (!x.servers[0].autoRoles || x.servers[0].autoRoles?.length == 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return x.servers[0].autoRoles[0];
|
||||||
|
}
|
||||||
|
).subscribe(data => {
|
||||||
|
this.totalRecords = data.autoRoleRuleCount;
|
||||||
|
this.rules = data.autoRoleRules;
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public setFilterForm(): void {
|
||||||
|
this.filterForm = this.fb.group({
|
||||||
|
id: new FormControl<number | null>(null),
|
||||||
|
emojiName: new FormControl<string | null>(null),
|
||||||
|
roleId: new FormControl<string | null>(null)
|
||||||
|
});
|
||||||
|
|
||||||
|
this.filterForm.valueChanges.pipe(
|
||||||
|
debounceTime(600)
|
||||||
|
).subscribe(changes => {
|
||||||
|
if (changes.id) {
|
||||||
|
this.filter.id = changes.id;
|
||||||
|
} else {
|
||||||
|
this.filter.id = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.emojiName) {
|
||||||
|
this.filter.emojiName = changes.emojiName;
|
||||||
|
} else {
|
||||||
|
this.filter.emojiName = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.roleId) {
|
||||||
|
this.filter.roleId = changes.roleId;
|
||||||
|
} else {
|
||||||
|
this.filter.roleId = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.page.pageSize)
|
||||||
|
this.page.pageSize = 10;
|
||||||
|
|
||||||
|
if (this.page.pageIndex)
|
||||||
|
this.page.pageIndex = 0;
|
||||||
|
|
||||||
|
this.loadNextPage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public nextPage(event: LazyLoadEvent): void {
|
||||||
|
this.page.pageSize = event.rows ?? 0;
|
||||||
|
if (event.first != null && event.rows != null)
|
||||||
|
this.page.pageIndex = event.first / event.rows;
|
||||||
|
this.sort.sortColumn = event.sortField ?? undefined;
|
||||||
|
this.sort.sortDirection = event.sortOrder === 1 ? SortDirection.ASC : event.sortOrder === -1 ? SortDirection.DESC : SortDirection.ASC;
|
||||||
|
|
||||||
|
this.loadNextPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public resetFilters(): void {
|
||||||
|
this.filterForm.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public onRowEditInit(table: Table, autoRoleRule: AutoRoleRule, index: number): void {
|
||||||
|
this.clonedUsers[index] = { ...autoRoleRule };
|
||||||
|
}
|
||||||
|
|
||||||
|
public onRowEditSave(table: Table, newAutoRoleRule: AutoRoleRule, index: number): void {
|
||||||
|
if (this.isEditingNew && JSON.stringify(newAutoRoleRule) === JSON.stringify(this.newAutoRoleTemplate)) {
|
||||||
|
this.isEditingNew = false;
|
||||||
|
this.rules.splice(index, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newAutoRoleRule.id && !this.isEditingNew || !newAutoRoleRule.emojiName && !newAutoRoleRule.roleId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isEditingNew) {
|
||||||
|
this.spinner.showSpinner();
|
||||||
|
this.data.mutation<AutoRoleRuleMutationResult>(Mutations.createAutoRoleRule, {
|
||||||
|
autoRoleId: this.autoRoleId,
|
||||||
|
emojiName: newAutoRoleRule.emojiName,
|
||||||
|
roleId: newAutoRoleRule.roleId
|
||||||
|
}
|
||||||
|
).pipe(catchError(err => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.error(this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_create_failed"), this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_create_failed_d"));
|
||||||
|
return throwError(err);
|
||||||
|
})).subscribe(result => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.success(this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_created"), this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_create_d", { id: result.autoRoleRule.createAutoRoleRule?.id }));
|
||||||
|
this.isEditingNew = false;
|
||||||
|
this.loadNextPage();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.spinner.showSpinner();
|
||||||
|
this.data.mutation<AutoRoleMutationResult>(Mutations.updateAutoRoleRule, {
|
||||||
|
id: newAutoRoleRule.id,
|
||||||
|
emojiName: newAutoRoleRule.emojiName,
|
||||||
|
roleId: newAutoRoleRule.roleId
|
||||||
|
}
|
||||||
|
).pipe(catchError(err => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.error(this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_update_failed"), this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_update_failed_d"));
|
||||||
|
return throwError(err);
|
||||||
|
})).subscribe(result => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.success(this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_updated"), this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_update_d", { id: result.autoRole.createAutoRole?.id }));
|
||||||
|
this.loadNextPage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public onRowEditCancel(index: number): void {
|
||||||
|
if (this.isEditingNew) {
|
||||||
|
this.rules.splice(index, 1);
|
||||||
|
delete this.clonedUsers[index];
|
||||||
|
this.isEditingNew = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.rules[index] = this.clonedUsers[index];
|
||||||
|
delete this.clonedUsers[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteAutoRoleRule(autoRoleRule: AutoRoleRule): void {
|
||||||
|
this.confirmDialog.confirmDialog(
|
||||||
|
this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_delete"), this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_delete_q", { id: autoRoleRule.id }),
|
||||||
|
() => {
|
||||||
|
this.spinner.showSpinner();
|
||||||
|
this.data.mutation<AutoRoleMutationResult>(Mutations.deleteAutoRoleRule, {
|
||||||
|
id: autoRoleRule.id
|
||||||
|
}
|
||||||
|
).pipe(catchError(err => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.error(this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_delete_failed"), this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_delete_failed_d", { id: autoRoleRule.id }));
|
||||||
|
return throwError(err);
|
||||||
|
})).subscribe(_ => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.success(this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_deleted"), this.translate.instant("view.server.auto_roles.rules.message.auto_role_rule_deleted_d", { id: autoRoleRule.id }));
|
||||||
|
this.loadNextPage();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public addAutoRoleRule(table: Table): void {
|
||||||
|
const newAutoRole = JSON.parse(JSON.stringify(this.newAutoRoleTemplate));
|
||||||
|
newAutoRole.id = Math.max.apply(Math, this.rules.map(u => {
|
||||||
|
return u.id ?? 0;
|
||||||
|
})) + 1;
|
||||||
|
|
||||||
|
this.rules.push(newAutoRole);
|
||||||
|
|
||||||
|
table.initRowEdit(newAutoRole);
|
||||||
|
|
||||||
|
const index = this.rules.findIndex(u => u.id == newAutoRole.id);
|
||||||
|
this.onRowEditInit(table, newAutoRole, index);
|
||||||
|
|
||||||
|
this.isEditingNew = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,221 @@
|
|||||||
|
<h1>
|
||||||
|
{{'view.server.auto_roles.header' | translate}}
|
||||||
|
</h1>
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div class="content">
|
||||||
|
<p-table #dt [value]="auto_roles" dataKey="id" editMode="row" [rowHover]="true" [rows]="10"
|
||||||
|
[rowsPerPageOptions]="[10,25,50]" [paginator]="true" [loading]="loading" [totalRecords]="totalRecords"
|
||||||
|
[lazy]="true" (onLazyLoad)="nextPage($event)">
|
||||||
|
|
||||||
|
<ng-template pTemplate="caption">
|
||||||
|
<div class="table-caption">
|
||||||
|
<div class="table-caption-text">
|
||||||
|
<ng-container *ngIf="!loading">{{auto_roles.length}} {{'view.server.auto_roles.of' | translate}}
|
||||||
|
{{dt.totalRecords}}
|
||||||
|
</ng-container>
|
||||||
|
{{'view.server.auto_roles.auto_roles' | translate}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-caption-btn-wrapper btn-wrapper">
|
||||||
|
<button pButton label="{{'admin.auth_users.add' | translate}}" class="icon-btn btn"
|
||||||
|
icon="pi pi-user-plus" (click)="addAutoRole(dt)" [disabled]="isEditingNew">
|
||||||
|
</button>
|
||||||
|
<button pButton label="{{'view.server.auto_roles.reset_filters' | translate}}" icon="pi pi-undo"
|
||||||
|
class="icon-btn btn" (click)="resetFilters()">
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="header">
|
||||||
|
<tr>
|
||||||
|
<th pSortableColumn="id">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.auto_roles.headers.id' | translate}}</div>
|
||||||
|
<p-sortIcon field="id" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th pSortableColumn="discordChannelId">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.auto_roles.headers.channel_id' | translate}}</div>
|
||||||
|
<p-sortIcon field="discordChannelId" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th pSortableColumn="discordChannelName">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.auto_roles.headers.channel_name' | translate}}</div>
|
||||||
|
<p-sortIcon field="discordChannelName" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th pSortableColumn="discordMessageId">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.auto_roles.headers.message_id' | translate}}</div>
|
||||||
|
<p-sortIcon field="discordMessageId" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.auto_roles.headers.role_count' | translate}}</div>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'common.created_at' | translate}}</div>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'common.modified_at' | translate}}</div>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th>
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'view.server.auto_roles.headers.actions' | translate}}</div>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th class="table-header-small">
|
||||||
|
<form [formGroup]="filterForm">
|
||||||
|
<input type="text" pInputText formControlName="id" placeholder="{{'view.server.auto_roles.headers.id' | translate}}">
|
||||||
|
</form>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<form [formGroup]="filterForm">
|
||||||
|
<input type="text" pInputText formControlName="channelId" placeholder="{{'view.server.auto_roles.headers.channel_id' | translate}}">
|
||||||
|
</form>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<form [formGroup]="filterForm">
|
||||||
|
<input type="text" pInputText formControlName="channelName" placeholder="{{'view.server.auto_roles.headers.channel_name' | translate}}">
|
||||||
|
</form>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<form [formGroup]="filterForm">
|
||||||
|
<input type="text" pInputText formControlName="messageId" placeholder="{{'view.server.auto_roles.headers.message_id' | translate}}">
|
||||||
|
</form>
|
||||||
|
</th>
|
||||||
|
<th></th>
|
||||||
|
<th class="table-header-small-dropdown"></th>
|
||||||
|
<th class="table-header-small-dropdown"></th>
|
||||||
|
<th class="table-header-actions"></th>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="body" let-autoRole let-editing="editing" let-ri="rowIndex">
|
||||||
|
<tr [pEditableRow]="autoRole">
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{autoRole.id}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{autoRole.id}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
<p-dropdown [options]="channels" optionValue="value.id" [(ngModel)]="autoRole.channelId" placeholder="{{'view.server.auto_roles.headers.channel_id' | translate}}"></p-dropdown>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{autoRole.channelId}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{autoRole.channelName}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{autoRole.channelName}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
<input pInputText class="table-edit-input" [(ngModel)]="autoRole.messageId">
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{autoRole.messageId}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{autoRole.autoRoleRuleCount}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{autoRole.autoRoleRuleCount}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{autoRole.createdAt | date:'dd.MM.yy HH:mm'}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{autoRole.createdAt | date:'dd.MM.yy HH:mm'}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{autoRole.modifiedAt | date:'dd.MM.yy HH:mm'}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{autoRole.modifiedAt | date:'dd.MM.yy HH:mm'}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<div class="btn-wrapper">
|
||||||
|
<!-- <button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil"-->
|
||||||
|
<!-- (click)="onRowEditInit(dt, autoRole, ri)"></button>-->
|
||||||
|
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-sliders-h" [routerLink]="[autoRole.id, 'rules']"></button>
|
||||||
|
<button *ngIf="!editing" pButton class="btn icon-btn danger-icon-btn" icon="pi pi-trash"
|
||||||
|
(click)="deleteAutoRole(autoRole)"></button>
|
||||||
|
|
||||||
|
<button *ngIf="editing" pButton pSaveEditableRow class="btn icon-btn"
|
||||||
|
icon="pi pi-check-circle" (click)="onRowEditSave(dt, autoRole, ri)"></button>
|
||||||
|
<button *ngIf="editing" pButton pCancelEditableRow class="btn icon-btn danger-icon-btn"
|
||||||
|
icon="pi pi-times-circle" (click)="onRowEditCancel(ri)"></button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="emptymessage">
|
||||||
|
<tr></tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="10">{{'view.server.auto_roles.no_entries_found' | translate}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr></tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="paginatorleft">
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AutoRolesComponent } from './auto-roles.component';
|
||||||
|
|
||||||
|
describe('AutoRolesComponent', () => {
|
||||||
|
let component: AutoRolesComponent;
|
||||||
|
let fixture: ComponentFixture<AutoRolesComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ AutoRolesComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(AutoRolesComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,257 @@
|
|||||||
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
import { User } from "../../../../../../models/data/user.model";
|
||||||
|
import { LazyLoadEvent, MenuItem } from "primeng/api";
|
||||||
|
import { FormBuilder, FormControl, FormGroup } from "@angular/forms";
|
||||||
|
import { Page } from "../../../../../../models/graphql/filter/page.model";
|
||||||
|
import { Sort, SortDirection } from "../../../../../../models/graphql/filter/sort.model";
|
||||||
|
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 { 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 { AutoRoleQuery, SingleDiscordQuery } from "../../../../../../models/graphql/query.model";
|
||||||
|
import { Queries } from "../../../../../../models/graphql/queries.model";
|
||||||
|
import { catchError, debounceTime } from "rxjs/operators";
|
||||||
|
import { Table } from "primeng/table";
|
||||||
|
import { AutoRoleMutationResult } from "../../../../../../models/graphql/result.model";
|
||||||
|
import { Mutations } from "../../../../../../models/graphql/mutations.model";
|
||||||
|
import { throwError } from "rxjs";
|
||||||
|
import { AutoRole, AutoRoleFilter } from "../../../../../../models/data/auto_role.model";
|
||||||
|
import { ChannelType, Guild } from "../../../../../../models/data/discord.model";
|
||||||
|
import { Server } from "../../../../../../models/data/server.model";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-auto-roles",
|
||||||
|
templateUrl: "./auto-roles.component.html",
|
||||||
|
styleUrls: ["./auto-roles.component.scss"]
|
||||||
|
})
|
||||||
|
export class AutoRolesComponent implements OnInit {
|
||||||
|
auto_roles!: AutoRole[];
|
||||||
|
guild!: Guild;
|
||||||
|
channels!: MenuItem[];
|
||||||
|
loading = true;
|
||||||
|
|
||||||
|
clonedUsers: { [s: string]: User; } = {};
|
||||||
|
isEditingNew: boolean = false;
|
||||||
|
|
||||||
|
newAutoRoleTemplate: AutoRole = {
|
||||||
|
id: 0,
|
||||||
|
createdAt: "",
|
||||||
|
modifiedAt: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
filterForm!: FormGroup<{
|
||||||
|
id: FormControl<number | null>,
|
||||||
|
channelId: FormControl<string | null>,
|
||||||
|
channelName: FormControl<string | null>,
|
||||||
|
messageId: FormControl<string | null>,
|
||||||
|
}>;
|
||||||
|
|
||||||
|
filter: AutoRoleFilter = {};
|
||||||
|
page: Page = {
|
||||||
|
pageSize: undefined,
|
||||||
|
pageIndex: undefined
|
||||||
|
};
|
||||||
|
sort: Sort = {
|
||||||
|
sortColumn: undefined,
|
||||||
|
sortDirection: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
totalRecords!: number;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
this.spinner.showSpinner();
|
||||||
|
this.data.query<SingleDiscordQuery>(Queries.guildsQuery, {
|
||||||
|
filter: {
|
||||||
|
id: this.sidebar.server$.value?.discordId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).subscribe(data => {
|
||||||
|
this.guild = data.guilds[0];
|
||||||
|
this.channels = this.guild.channels
|
||||||
|
.filter(x => x.type === ChannelType.text)
|
||||||
|
.map(x => {
|
||||||
|
return { label: x.name, value: x };
|
||||||
|
});
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setFilterForm();
|
||||||
|
this.loadNextPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public loadNextPage(): void {
|
||||||
|
this.loading = true;
|
||||||
|
this.data.query<AutoRoleQuery>(Queries.autoRolesQuery, {
|
||||||
|
id: this.sidebar.server$.value?.id, filter: this.filter, page: this.page, sort: this.sort
|
||||||
|
},
|
||||||
|
(x: { servers: Server[] }) => {
|
||||||
|
return x.servers[0];
|
||||||
|
}
|
||||||
|
).subscribe(data => {
|
||||||
|
this.totalRecords = data.autoRoleCount;
|
||||||
|
this.auto_roles = data.autoRoles;
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public setFilterForm(): void {
|
||||||
|
this.filterForm = this.fb.group({
|
||||||
|
id: new FormControl<number | null>(null),
|
||||||
|
channelId: new FormControl<string | null>(null),
|
||||||
|
channelName: new FormControl<string | null>(null),
|
||||||
|
messageId: new FormControl<string | null>(null)
|
||||||
|
});
|
||||||
|
|
||||||
|
this.filterForm.valueChanges.pipe(
|
||||||
|
debounceTime(600)
|
||||||
|
).subscribe(changes => {
|
||||||
|
if (changes.id) {
|
||||||
|
this.filter.id = changes.id;
|
||||||
|
} else {
|
||||||
|
this.filter.id = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.channelId) {
|
||||||
|
this.filter.channelId = changes.channelId;
|
||||||
|
} else {
|
||||||
|
this.filter.channelId = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.channelName) {
|
||||||
|
this.filter.channelName = changes.channelName;
|
||||||
|
} else {
|
||||||
|
this.filter.channelName = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.messageId) {
|
||||||
|
this.filter.messageId = changes.messageId;
|
||||||
|
} else {
|
||||||
|
this.filter.messageId = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.page.pageSize)
|
||||||
|
this.page.pageSize = 10;
|
||||||
|
|
||||||
|
if (this.page.pageIndex)
|
||||||
|
this.page.pageIndex = 0;
|
||||||
|
|
||||||
|
this.loadNextPage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public nextPage(event: LazyLoadEvent): void {
|
||||||
|
this.page.pageSize = event.rows ?? 0;
|
||||||
|
if (event.first != null && event.rows != null)
|
||||||
|
this.page.pageIndex = event.first / event.rows;
|
||||||
|
this.sort.sortColumn = event.sortField ?? undefined;
|
||||||
|
this.sort.sortDirection = event.sortOrder === 1 ? SortDirection.ASC : event.sortOrder === -1 ? SortDirection.DESC : SortDirection.ASC;
|
||||||
|
|
||||||
|
this.loadNextPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public resetFilters(): void {
|
||||||
|
this.filterForm.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public onRowEditInit(table: Table, autoRole: AutoRole, index: number): void {
|
||||||
|
this.clonedUsers[index] = { ...autoRole };
|
||||||
|
}
|
||||||
|
|
||||||
|
public onRowEditSave(table: Table, newAutoRole: AutoRole, index: number): void {
|
||||||
|
if (this.isEditingNew && JSON.stringify(newAutoRole) === JSON.stringify(this.newAutoRoleTemplate)) {
|
||||||
|
this.isEditingNew = false;
|
||||||
|
this.auto_roles.splice(index, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newAutoRole.id || !newAutoRole.channelId && !newAutoRole.messageId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.spinner.showSpinner();
|
||||||
|
this.data.mutation<AutoRoleMutationResult>(Mutations.createAutoRole, {
|
||||||
|
serverId: this.sidebar.server$.value?.id,
|
||||||
|
channelId: newAutoRole.channelId,
|
||||||
|
messageId: newAutoRole.messageId
|
||||||
|
}
|
||||||
|
).pipe(catchError(err => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.error(this.translate.instant("view.server.auto_roles.message.auto_role_create_failed"), this.translate.instant("view.server.auto_roles.message.auto_role_create_failed_d"));
|
||||||
|
return throwError(err);
|
||||||
|
})).subscribe(result => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.success(this.translate.instant("view.server.auto_roles.message.auto_role_created"), this.translate.instant("view.server.auto_roles.message.auto_role_create_d", { id: result.autoRole.createAutoRole?.id }));
|
||||||
|
this.loadNextPage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public onRowEditCancel(index: number): void {
|
||||||
|
if (this.isEditingNew) {
|
||||||
|
this.auto_roles.splice(index, 1);
|
||||||
|
delete this.clonedUsers[index];
|
||||||
|
this.isEditingNew = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.auto_roles[index] = this.clonedUsers[index];
|
||||||
|
delete this.clonedUsers[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteAutoRole(autoRole: AutoRole): void {
|
||||||
|
this.confirmDialog.confirmDialog(
|
||||||
|
this.translate.instant("view.server.auto_roles.message.auto_role_delete"), this.translate.instant("view.server.auto_roles.message.auto_role_delete_q", { id: autoRole.id }),
|
||||||
|
() => {
|
||||||
|
this.spinner.showSpinner();
|
||||||
|
this.data.mutation<AutoRoleMutationResult>(Mutations.deleteAutoRole, {
|
||||||
|
id: autoRole.id
|
||||||
|
}
|
||||||
|
).pipe(catchError(err => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.error(this.translate.instant("view.server.auto_roles.message.auto_role_delete_failed"), this.translate.instant("view.server.auto_roles.message.auto_role_delete_failed_d", { id: autoRole.id }));
|
||||||
|
return throwError(err);
|
||||||
|
})).subscribe(_ => {
|
||||||
|
this.spinner.hideSpinner();
|
||||||
|
this.toastService.success(this.translate.instant("view.server.auto_roles.message.auto_role_deleted"), this.translate.instant("view.server.auto_roles.message.auto_role_deleted_d", { id: autoRole.id }));
|
||||||
|
this.loadNextPage();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public addAutoRole(table: Table): void {
|
||||||
|
const newAutoRole = JSON.parse(JSON.stringify(this.newAutoRoleTemplate));
|
||||||
|
newAutoRole.id = Math.max.apply(Math, this.auto_roles.map(u => {
|
||||||
|
return u.id ?? 0;
|
||||||
|
})) + 1;
|
||||||
|
|
||||||
|
this.auto_roles.push(newAutoRole);
|
||||||
|
|
||||||
|
table.initRowEdit(newAutoRole);
|
||||||
|
|
||||||
|
const index = this.auto_roles.findIndex(u => u.id == newAutoRole.id);
|
||||||
|
this.onRowEditInit(table, newAutoRole, index);
|
||||||
|
|
||||||
|
this.isEditingNew = true;
|
||||||
|
}
|
||||||
|
}
|
@ -163,7 +163,8 @@
|
|||||||
<td>
|
<td>
|
||||||
<p-cellEditor>
|
<p-cellEditor>
|
||||||
<ng-template pTemplate="input">
|
<ng-template pTemplate="input">
|
||||||
<input class="table-edit-input" pInputText type="number" min="0" [(ngModel)]="member.xp">
|
<p-inputNumber class="table-edit-input" styleClass="input-number" [(ngModel)]="member.xp" mode="decimal" [min]="0" [useGrouping]="false" [showButtons]="true"
|
||||||
|
inputId="minmax-buttons"></p-inputNumber>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<ng-template pTemplate="output">
|
<ng-template pTemplate="output">
|
||||||
{{member.xp}}
|
{{member.xp}}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { FormBuilder, FormControl, FormGroup } from "@angular/forms";
|
import { FormBuilder, FormControl, FormGroup } from "@angular/forms";
|
||||||
import { AuthService } from "../../../../services/auth/auth.service";
|
import { AuthService } from "../../../../services/auth/auth.service";
|
||||||
import { SpinnerService } from "../../../../services/spinner/spinner.service";
|
import { SpinnerService } from "../../../../services/spinner/spinner.service";
|
||||||
@ -25,13 +25,13 @@ import { ActivatedRoute } from "@angular/router";
|
|||||||
templateUrl: "./members.component.html",
|
templateUrl: "./members.component.html",
|
||||||
styleUrls: ["./members.component.scss"]
|
styleUrls: ["./members.component.scss"]
|
||||||
})
|
})
|
||||||
export class MembersComponent {
|
export class MembersComponent implements OnInit {
|
||||||
members!: User[];
|
members!: User[];
|
||||||
// levelsFilter!: MenuItem[];
|
// levelsFilter!: MenuItem[];
|
||||||
levels!: MenuItem[];
|
levels!: MenuItem[];
|
||||||
leftServerOptions = [
|
leftServerOptions = [
|
||||||
{label: this.translate.instant('common.bool_as_string.true'), value: false},
|
{ label: this.translate.instant("common.bool_as_string.true"), value: false },
|
||||||
{label: this.translate.instant('common.bool_as_string.false'), value: true},
|
{ label: this.translate.instant("common.bool_as_string.false"), value: true }
|
||||||
];
|
];
|
||||||
loading = true;
|
loading = true;
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ export class MembersComponent {
|
|||||||
discordId: new FormControl<number | null>(null),
|
discordId: new FormControl<number | null>(null),
|
||||||
name: [""],
|
name: [""],
|
||||||
leftServer: new FormControl<boolean | null>(null),
|
leftServer: new FormControl<boolean | null>(null),
|
||||||
level: new FormControl<number | null>(null),
|
level: new FormControl<number | null>(null)
|
||||||
});
|
});
|
||||||
|
|
||||||
this.filterForm.valueChanges.pipe(
|
this.filterForm.valueChanges.pipe(
|
||||||
|
@ -8,6 +8,7 @@ const routes: Routes = [
|
|||||||
{ path: '', component: ServerDashboardComponent },
|
{ path: '', component: ServerDashboardComponent },
|
||||||
{ path: 'members', component: MembersComponent },
|
{ path: 'members', component: MembersComponent },
|
||||||
{ path: 'members/:memberId', component: ProfileComponent },
|
{ path: 'members/:memberId', component: ProfileComponent },
|
||||||
|
{ path: 'auto-roles', loadChildren: () => import('./auto-role/auto-role.module').then(m => m.AutoRoleModule)},
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -9,6 +9,7 @@ import { Queries } from "../../models/graphql/queries.model";
|
|||||||
import { Query } from "../../models/graphql/query.model";
|
import { Query } from "../../models/graphql/query.model";
|
||||||
import { SidebarService } from "../sidebar/sidebar.service";
|
import { SidebarService } from "../sidebar/sidebar.service";
|
||||||
import { SpinnerService } from "../spinner/spinner.service";
|
import { SpinnerService } from "../spinner/spinner.service";
|
||||||
|
import { GraphQLResult } from "../../models/graphql/result.model";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: "root"
|
providedIn: "root"
|
||||||
@ -20,7 +21,7 @@ export class DataService {
|
|||||||
private http: HttpClient,
|
private http: HttpClient,
|
||||||
private sidebar: SidebarService,
|
private sidebar: SidebarService,
|
||||||
private spinner: SpinnerService,
|
private spinner: SpinnerService,
|
||||||
private router: Router,
|
private router: Router
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ export class DataService {
|
|||||||
this.spinner.showSpinner();
|
this.spinner.showSpinner();
|
||||||
if (!route.snapshot.params["serverId"]) {
|
if (!route.snapshot.params["serverId"]) {
|
||||||
this.spinner.hideSpinner();
|
this.spinner.hideSpinner();
|
||||||
this.router.navigate(['/dashboard']);
|
this.router.navigate(["/dashboard"]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,21 +47,31 @@ export class DataService {
|
|||||||
|
|
||||||
public query<T>(query: string, variables?: Variables, f?: Function): Observable<T> {
|
public query<T>(query: string, variables?: Variables, f?: Function): Observable<T> {
|
||||||
return this.http
|
return this.http
|
||||||
.post<{ data: T }>(`${this.appsettings.getApiURL()}/api/graphql`, {
|
.post<GraphQLResult>(`${this.appsettings.getApiURL()}/api/graphql`, {
|
||||||
query: query,
|
query: query,
|
||||||
variables: variables
|
variables: variables
|
||||||
})
|
})
|
||||||
.pipe(map((d) => d.data))
|
.pipe(map(d => {
|
||||||
|
if (d.errors && d.errors.length > 0) {
|
||||||
|
throw new Error(d.errors.map((x: {message: String}) => x.message).toString());
|
||||||
|
}
|
||||||
|
return d.data;
|
||||||
|
}))
|
||||||
.pipe(map((d) => f ? f(d) : d));
|
.pipe(map((d) => f ? f(d) : d));
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutation<T>(query: string, variables?: object, f?: Function): Observable<T> {
|
public mutation<T>(query: string, variables?: object, f?: Function): Observable<T> {
|
||||||
return this.http
|
return this.http
|
||||||
.post<{ data: T }>(`${this.appsettings.getApiURL()}/api/graphql`, {
|
.post<GraphQLResult>(`${this.appsettings.getApiURL()}/api/graphql`, {
|
||||||
query: query,
|
query: query,
|
||||||
variables: variables
|
variables: variables
|
||||||
})
|
})
|
||||||
.pipe(map((d) => d.data))
|
.pipe(map(d => {
|
||||||
|
if (d.errors && d.errors.length > 0) {
|
||||||
|
throw new Error(d.errors.toString());
|
||||||
|
}
|
||||||
|
return d.data;
|
||||||
|
}))
|
||||||
.pipe(map((d) => f ? f(d) : d));
|
.pipe(map((d) => f ? f(d) : d));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
import { HttpErrorResponse } from '@angular/common/http';
|
import { HttpErrorResponse } from "@angular/common/http";
|
||||||
import { ErrorHandler, Injectable, Injector } from '@angular/core';
|
import { ErrorHandler, Injectable } from "@angular/core";
|
||||||
import { Observable, throwError } from 'rxjs';
|
import { Observable, throwError } from "rxjs";
|
||||||
import { ErrorDTO } from 'src/app/models/error/error-dto';
|
import { ErrorDTO } from "src/app/models/error/error-dto";
|
||||||
import { ServiceErrorCode } from 'src/app/models/error/service-error-code.enum';
|
import { ServiceErrorCode } from "src/app/models/error/service-error-code.enum";
|
||||||
import { AuthService } from '../auth/auth.service';
|
import { AuthService } from "../auth/auth.service";
|
||||||
import { ToastService } from '../toast/toast.service';
|
import { ToastService } from "../toast/toast.service";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ErrorHandlerService implements ErrorHandler {
|
export class ErrorHandlerService implements ErrorHandler {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private injector: Injector
|
private auth: AuthService,
|
||||||
|
private toast: ToastService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
handleError(error: HttpErrorResponse): Observable<never> {
|
handleError(error: HttpErrorResponse): Observable<never> {
|
||||||
@ -20,7 +21,7 @@ export class ErrorHandlerService implements ErrorHandler {
|
|||||||
const errorDto: ErrorDTO = error.error;
|
const errorDto: ErrorDTO = error.error;
|
||||||
|
|
||||||
if (errorDto.errorCode === ServiceErrorCode.Unauthorized) {
|
if (errorDto.errorCode === ServiceErrorCode.Unauthorized) {
|
||||||
this.injector.get(AuthService).logout();
|
this.auth.logout();
|
||||||
return throwError(() => error);
|
return throwError(() => error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,11 +35,13 @@ export class ErrorHandlerService implements ErrorHandler {
|
|||||||
message = error.message;
|
message = error.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.injector.get(ToastService).error(header, message);
|
this.toast.error(header, message);
|
||||||
|
} else {
|
||||||
|
console.error(error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error.status === 401) {
|
if (error.status === 401) {
|
||||||
this.injector.get(AuthService).logout();
|
this.auth.logout();
|
||||||
}
|
}
|
||||||
return throwError(() => error);
|
return throwError(() => error);
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ export class SidebarService {
|
|||||||
serverDashboard!: MenuItem;
|
serverDashboard!: MenuItem;
|
||||||
serverProfile!: MenuItem;
|
serverProfile!: MenuItem;
|
||||||
serverMembers!: MenuItem;
|
serverMembers!: MenuItem;
|
||||||
|
serverAutoRoles!: MenuItem;
|
||||||
|
serverAutoRoleRules!: MenuItem;
|
||||||
serverMenu!: MenuItem;
|
serverMenu!: MenuItem;
|
||||||
adminConfig!: MenuItem;
|
adminConfig!: MenuItem;
|
||||||
adminUsers!: MenuItem;
|
adminUsers!: MenuItem;
|
||||||
@ -81,12 +83,20 @@ export class SidebarService {
|
|||||||
visible: true,
|
visible: true,
|
||||||
routerLink: `server/${this.server$.value?.id}/members`
|
routerLink: `server/${this.server$.value?.id}/members`
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.serverAutoRoles = {
|
||||||
|
label: this.isSidebarOpen ? this.translateService.instant("sidebar.server.auto_roles") : "",
|
||||||
|
icon: "pi pi-sitemap",
|
||||||
|
visible: true,
|
||||||
|
routerLink: `server/${this.server$.value?.id}/auto-roles`
|
||||||
|
};
|
||||||
|
|
||||||
this.serverMenu = {
|
this.serverMenu = {
|
||||||
label: this.isSidebarOpen ? this.server$.value?.name : "",
|
label: this.isSidebarOpen ? this.server$.value?.name : "",
|
||||||
icon: "pi pi-server",
|
icon: "pi pi-server",
|
||||||
visible: false,
|
visible: false,
|
||||||
expanded: true,
|
expanded: true,
|
||||||
items: [this.serverDashboard, this.serverProfile, this.serverMembers]
|
items: [this.serverDashboard, this.serverProfile, this.serverMembers, this.serverAutoRoles]
|
||||||
};
|
};
|
||||||
this.adminConfig = { label: this.isSidebarOpen ? this.translateService.instant("sidebar.config") : "", icon: "pi pi-cog", routerLink: "/admin/settings" };
|
this.adminConfig = { label: this.isSidebarOpen ? this.translateService.instant("sidebar.config") : "", icon: "pi pi-cog", routerLink: "/admin/settings" };
|
||||||
this.adminUsers = {
|
this.adminUsers = {
|
||||||
@ -115,6 +125,7 @@ export class SidebarService {
|
|||||||
if (this.server$.value) {
|
if (this.server$.value) {
|
||||||
this.serverMenu.visible = true;
|
this.serverMenu.visible = true;
|
||||||
this.serverMembers.visible = !!user?.isModerator;
|
this.serverMembers.visible = !!user?.isModerator;
|
||||||
|
this.serverAutoRoles.visible = !!user?.isAdmin;
|
||||||
} else {
|
} else {
|
||||||
this.serverMenu.visible = false;
|
this.serverMenu.visible = false;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from "@angular/core";
|
||||||
import { LangChangeEvent, TranslateService } from '@ngx-translate/core';
|
import { BehaviorSubject } from "rxjs";
|
||||||
import { Subject } from 'rxjs';
|
import { Themes } from "src/app/models/view/themes.enum";
|
||||||
import { Themes } from 'src/app/models/view/themes.enum';
|
import { AuthService } from "../auth/auth.service";
|
||||||
import { AuthService } from '../auth/auth.service';
|
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -15,9 +14,9 @@ export class ThemeService {
|
|||||||
isSidebarOpen = false;
|
isSidebarOpen = false;
|
||||||
hasLangChanged = false;
|
hasLangChanged = false;
|
||||||
|
|
||||||
themeName$ = new Subject<string>();
|
themeName$ = new BehaviorSubject<string>(Themes.Default);
|
||||||
isSidebarOpen$ = new Subject<boolean>();
|
isSidebarOpen$ = new BehaviorSubject<boolean>(true);
|
||||||
sidebarWidth$ = new Subject<string>();
|
sidebarWidth$ = new BehaviorSubject<string>('175px');
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private authService: AuthService
|
private authService: AuthService
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"WebVersion": {
|
"WebVersion": {
|
||||||
"Major": "1",
|
"Major": "1",
|
||||||
"Minor": "0",
|
"Minor": "0",
|
||||||
"Micro": "dev130"
|
"Micro": "dev134"
|
||||||
},
|
},
|
||||||
"Themes": [
|
"Themes": [
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
"server": {
|
"server": {
|
||||||
"dashboard": "Dashboard",
|
"dashboard": "Dashboard",
|
||||||
"profile": "Dein Profil",
|
"profile": "Dein Profil",
|
||||||
"members": "Mitglieder"
|
"members": "Mitglieder",
|
||||||
|
"auto_roles": "Auto Rollen"
|
||||||
},
|
},
|
||||||
"server_empty": "Kein Server ausgewählt",
|
"server_empty": "Kein Server ausgewählt",
|
||||||
"members": "Mitglieder",
|
"members": "Mitglieder",
|
||||||
@ -202,8 +203,8 @@
|
|||||||
"reset_filters": "Filter zurücksetzen",
|
"reset_filters": "Filter zurücksetzen",
|
||||||
"members": "Mitgliedern",
|
"members": "Mitgliedern",
|
||||||
"headers": {
|
"headers": {
|
||||||
"id": "ID",
|
"id": "Id",
|
||||||
"discord_id": "Discord ID",
|
"discord_id": "Discord Id",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"xp": "XP",
|
"xp": "XP",
|
||||||
"ontime": "Ontime",
|
"ontime": "Ontime",
|
||||||
@ -218,6 +219,64 @@
|
|||||||
"user_change_failed": "Benutzer änderung fehlgeschlagen",
|
"user_change_failed": "Benutzer änderung fehlgeschlagen",
|
||||||
"user_change_failed_d": "Benutzer {{name}} konnte nicht geändert werden!"
|
"user_change_failed_d": "Benutzer {{name}} konnte nicht geändert werden!"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"auto_roles": {
|
||||||
|
"header": "Auto Rollen",
|
||||||
|
"of": "von",
|
||||||
|
"add": "Hinzufügen",
|
||||||
|
"reset_filters": "Filter zurücksetzen",
|
||||||
|
"auto_roles": "Auto Rollen",
|
||||||
|
"headers": {
|
||||||
|
"id": "Id",
|
||||||
|
"channel_id": "Kanal Id",
|
||||||
|
"channel_name": "Kanal",
|
||||||
|
"message_id": "Nachricht Id",
|
||||||
|
"role_count": "Regeln",
|
||||||
|
"actions": "Aktionen"
|
||||||
|
},
|
||||||
|
"no_entries_found": "Keine Einträge gefunden",
|
||||||
|
"message": {
|
||||||
|
"auto_role_create": "Auto Rolle erstellt",
|
||||||
|
"auto_role_create_d": "Auto Rolle {{id}} erfolgreich erstellt",
|
||||||
|
"auto_role_create_failed": "Auto Rolle Erstellung fehlgeschlagen",
|
||||||
|
"auto_role_create_failed_d": "Die Erstellung der Auto Rolle ist fehlgeschlagen!",
|
||||||
|
"auto_role_delete": "Auto Rolle löschen",
|
||||||
|
"auto_role_delete_q": "Sind Sie sich sicher, dass Sie die Auto Rolle {{id}} löschen möchten?",
|
||||||
|
"auto_role_deleted": "Auto Rolle gelöscht",
|
||||||
|
"auto_role_deleted_d": "Auto Rolle {{id}} erfolgreich gelöscht",
|
||||||
|
"auto_role_delete_failed": "Auto Rolle Löschung fehlgeschlagen",
|
||||||
|
"auto_role_delete_failed_d": "Die Löschung der Auto Rolle {{id}} ist fehlgeschlagen!"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"header": "Auto Rollen Regeln",
|
||||||
|
"of": "von",
|
||||||
|
"add": "Hinzufügen",
|
||||||
|
"reset_filters": "Filter zurücksetzen",
|
||||||
|
"auto_roles": "Auto Rollen Regeln",
|
||||||
|
"headers": {
|
||||||
|
"id": "Id",
|
||||||
|
"emoji": "Emoji",
|
||||||
|
"role": "Rolle",
|
||||||
|
"actions": "Aktionen"
|
||||||
|
},
|
||||||
|
"no_entries_found": "Keine Einträge gefunden",
|
||||||
|
"message": {
|
||||||
|
"auto_role_rule_create": "Auto Rollen Regel erstellt",
|
||||||
|
"auto_role_rule_create_d": "Auto Rollen Regel {{id}} erfolgreich erstellt",
|
||||||
|
"auto_role_rule_create_failed": "Auto Rollen Regel Erstellung fehlgeschlagen",
|
||||||
|
"auto_role_rule_create_failed_d": "Die Erstellung der Auto Rollen Regel ist fehlgeschlagen!",
|
||||||
|
"auto_role_rule_update": "Auto Rollen Regel bearbeitet",
|
||||||
|
"auto_role_rule_update_d": "Auto Rollen Regel {{id}} erfolgreich bearbeitet",
|
||||||
|
"auto_role_rule_update_failed": "Auto Rollen Regel Bearbeitung fehlgeschlagen",
|
||||||
|
"auto_role_rule_update_failed_d": "Die Bearbeitung der Auto Rollen Regel ist fehlgeschlagen!",
|
||||||
|
"auto_role_rule_delete": "Auto Rollen Regel löschen",
|
||||||
|
"auto_role_rule_delete_q": "Sind Sie sich sicher, dass Sie die Auto Rollen Regel {{id}} löschen möchten?",
|
||||||
|
"auto_role_rule_deleted": "Auto Rollen Regel gelöscht",
|
||||||
|
"auto_role_rule_deleted_d": "Auto Rollen Regel {{id}} erfolgreich gelöscht",
|
||||||
|
"auto_role_rule_delete_failed": "Auto Rollen Regel Löschung fehlgeschlagen",
|
||||||
|
"auto_role_rule_delete_failed_d": "Die Löschung der Auto Rollen Regel {{id}} ist fehlgeschlagen!"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"user-list": {},
|
"user-list": {},
|
||||||
|
@ -156,6 +156,12 @@ header {
|
|||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown-icon-label-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.content-input-field {
|
.content-input-field {
|
||||||
width: 50% !important;
|
width: 50% !important;
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
|
@ -97,6 +97,11 @@ p-table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-dropdown,
|
||||||
|
.p-inputnumber {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
.pi-sort-alt:before {
|
.pi-sort-alt:before {
|
||||||
content: "\e915" !important;
|
content: "\e915" !important;
|
||||||
}
|
}
|
||||||
|
@ -580,4 +580,18 @@
|
|||||||
background-color: $primaryBackgroundColor !important;
|
background-color: $primaryBackgroundColor !important;
|
||||||
color: $primaryHeaderColor !important;
|
color: $primaryHeaderColor !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-number {
|
||||||
|
span {
|
||||||
|
.p-button {
|
||||||
|
background-color: $primaryHeaderColor !important;
|
||||||
|
border: 1px solid $primaryHeaderColor !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $secondaryHeaderColor !important;
|
||||||
|
border: 1px solid $secondaryHeaderColor !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -580,4 +580,18 @@
|
|||||||
background-color: $primaryBackgroundColor !important;
|
background-color: $primaryBackgroundColor !important;
|
||||||
color: $primaryHeaderColor !important;
|
color: $primaryHeaderColor !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-number {
|
||||||
|
span {
|
||||||
|
.p-button {
|
||||||
|
background-color: $primaryHeaderColor !important;
|
||||||
|
border: 1px solid $primaryHeaderColor !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $secondaryHeaderColor !important;
|
||||||
|
border: 1px solid $secondaryHeaderColor !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,4 +582,18 @@
|
|||||||
background-color: $primaryBackgroundColor !important;
|
background-color: $primaryBackgroundColor !important;
|
||||||
color: $primaryHeaderColor !important;
|
color: $primaryHeaderColor !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-number {
|
||||||
|
span {
|
||||||
|
.p-button {
|
||||||
|
background-color: $primaryHeaderColor !important;
|
||||||
|
border: 1px solid $primaryHeaderColor !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $secondaryHeaderColor !important;
|
||||||
|
border: 1px solid $secondaryHeaderColor !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -580,4 +580,18 @@
|
|||||||
background-color: $primaryBackgroundColor !important;
|
background-color: $primaryBackgroundColor !important;
|
||||||
color: $primaryHeaderColor !important;
|
color: $primaryHeaderColor !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-number {
|
||||||
|
span {
|
||||||
|
.p-button {
|
||||||
|
background-color: $primaryHeaderColor !important;
|
||||||
|
border: 1px solid $primaryHeaderColor !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $secondaryHeaderColor !important;
|
||||||
|
border: 1px solid $secondaryHeaderColor !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user