diff --git a/bot/src/bot_data/model/scheduled_event.py b/bot/src/bot_data/model/scheduled_event.py index fa05c946..3f8fbee3 100644 --- a/bot/src/bot_data/model/scheduled_event.py +++ b/bot/src/bot_data/model/scheduled_event.py @@ -4,13 +4,14 @@ from typing import Optional import discord from cpl_core.database import TableABC +from bot_data.model.scheduled_event_interval_enum import ScheduledEventIntervalEnum from bot_data.model.server import Server class ScheduledEvent(TableABC): def __init__( self, - interval: str, + interval: ScheduledEventIntervalEnum, name: str, description: str, channel_id: int, @@ -43,11 +44,11 @@ class ScheduledEvent(TableABC): return self._id @property - def interval(self) -> str: + def interval(self) -> ScheduledEventIntervalEnum: return self._interval @interval.setter - def interval(self, value: str): + def interval(self, value: ScheduledEventIntervalEnum): self._interval = value @property @@ -145,11 +146,11 @@ class ScheduledEvent(TableABC): return str( f""" INSERT INTO `ScheduledEvents` ( - `Interval`, `Name`, `Description`, `ChannelId`, `StartTime`, `EndTime`, `EntityType`, `Location`, `ServerId`, + `Interval`, `Name`, `Description`, `ChannelId`, `StartTime`, `EndTime`, `EntityType`, `Location`, `ServerId` ) VALUES ( - '{self._interval}', + '{self._interval.value}', '{self._name}', - '{self._description}', + {"NULL" if self._description is None else f"'{self._description}'"}, {"NULL" if self._channel_id is None else f"'{self._channel_id}'"}, '{self._start_time}', {"NULL" if self._end_time is None else f"'{self._end_time}'"}, @@ -165,7 +166,7 @@ class ScheduledEvent(TableABC): return str( f""" UPDATE `ScheduledEvents` - SET `Interval` = '{self._interval}', + SET `Interval` = '{self._interval.value}', `Name` = '{self._name}', `Description` = '{self._start_time}', `ChannelId` = {"NULL" if self._channel_id is None else f"'{self._channel_id}'"}, diff --git a/bot/src/bot_data/model/scheduled_event_interval_enum.py b/bot/src/bot_data/model/scheduled_event_interval_enum.py new file mode 100644 index 00000000..7f13c589 --- /dev/null +++ b/bot/src/bot_data/model/scheduled_event_interval_enum.py @@ -0,0 +1,8 @@ +from enum import Enum + + +class ScheduledEventIntervalEnum(Enum): + daily = "daily" + weekly = "weekly" + monthly = "monthly" + yearly = "yearly" diff --git a/bot/src/bot_data/scripts/1.2.2/1_ScheduledEvents_up.sql b/bot/src/bot_data/scripts/1.2.2/1_ScheduledEvents_up.sql index 2768651e..843c21fc 100644 --- a/bot/src/bot_data/scripts/1.2.2/1_ScheduledEvents_up.sql +++ b/bot/src/bot_data/scripts/1.2.2/1_ScheduledEvents_up.sql @@ -1,9 +1,9 @@ CREATE TABLE IF NOT EXISTS `ScheduledEvents` ( `Id` BIGINT NOT NULL AUTO_INCREMENT, - `Interval` VARCHAR(255) NOT NULL, + `Interval` ENUM ('daily', 'weekly', 'monthly', 'yearly') NOT NULL, `Name` VARCHAR(255) NOT NULL, - `Description` VARCHAR(255) NOT NULL, + `Description` VARCHAR(255) NULL, `ChannelId` BIGINT NULL, `StartTime` DATETIME(6) NOT NULL, `EndTime` DATETIME(6) NULL, @@ -19,9 +19,9 @@ CREATE TABLE IF NOT EXISTS `ScheduledEvents` CREATE TABLE IF NOT EXISTS `ScheduledEventsHistory` ( `Id` BIGINT(20) NOT NULL, - `Interval` VARCHAR(255) NOT NULL, + `Interval` ENUM ('daily', 'weekly', 'monthly', 'yearly') NOT NULL, `Name` VARCHAR(255) NOT NULL, - `Description` VARCHAR(255) NOT NULL, + `Description` VARCHAR(255) NULL, `ChannelId` BIGINT NULL, `StartTime` DATETIME(6) NOT NULL, `EndTime` DATETIME(6) NULL, diff --git a/bot/src/bot_data/service/scheduled_event_repository_service.py b/bot/src/bot_data/service/scheduled_event_repository_service.py index 7d5e67ba..01d4fc6c 100644 --- a/bot/src/bot_data/service/scheduled_event_repository_service.py +++ b/bot/src/bot_data/service/scheduled_event_repository_service.py @@ -7,6 +7,7 @@ from bot_core.logging.database_logger import DatabaseLogger from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC from bot_data.model.scheduled_event import ScheduledEvent +from bot_data.model.scheduled_event_interval_enum import ScheduledEventIntervalEnum class ScheduledEventRepositoryService(ScheduledEventRepositoryABC): @@ -32,17 +33,17 @@ class ScheduledEventRepositoryService(ScheduledEventRepositoryABC): def _scheduled_event_from_result(self, sql_result: tuple) -> ScheduledEvent: return ScheduledEvent( - self._get_value_from_result(sql_result[0]), # interval - self._get_value_from_result(sql_result[1]), # name - self._get_value_from_result(sql_result[2]), # description - int(self._get_value_from_result(sql_result[3])), # channel_id - self._get_value_from_result(sql_result[4]), # start_time - self._get_value_from_result(sql_result[5]), # end_time - self._get_value_from_result(sql_result[6]), # entity_type - self._get_value_from_result(sql_result[7]), # location - self._servers.get_server_by_id((sql_result[8])), # server - self._get_value_from_result(sql_result[9]), # created_at - self._get_value_from_result(sql_result[10]), # modified_at + self._get_value_from_result(ScheduledEventIntervalEnum(sql_result[1])), # interval + self._get_value_from_result(sql_result[2]), # name + self._get_value_from_result(sql_result[3]), # description + int(self._get_value_from_result(sql_result[4])), # channel_id + self._get_value_from_result(sql_result[5]), # start_time + self._get_value_from_result(sql_result[6]), # end_time + self._get_value_from_result(sql_result[7]), # entity_type + self._get_value_from_result(sql_result[8]), # location + self._servers.get_server_by_id((sql_result[9])), # server + self._get_value_from_result(sql_result[10]), # created_at + self._get_value_from_result(sql_result[11]), # modified_at id=self._get_value_from_result(sql_result[0]), ) diff --git a/bot/src/bot_graphql/abc/filter_abc.py b/bot/src/bot_graphql/abc/filter_abc.py index 7c1fa477..3067b075 100644 --- a/bot/src/bot_graphql/abc/filter_abc.py +++ b/bot/src/bot_graphql/abc/filter_abc.py @@ -63,7 +63,9 @@ class FilterABC(ABC): self.__setattr__(f"_{attr}", attr_type(values[attr])) @staticmethod - def _filter_by_attributes(attrs: list[Callable], values: List[T]) -> List[R]: + def _filter_by_attributes(attrs: list[dict], values: List[T]) -> List[R]: for attr in attrs: - values = values.where(attr) + if attr["attr"] is None: + continue + values = values.where(attr["func"]) return values diff --git a/bot/src/bot_graphql/filter/scheduled_event_filter.py b/bot/src/bot_graphql/filter/scheduled_event_filter.py index d1937c25..e98be02b 100644 --- a/bot/src/bot_graphql/filter/scheduled_event_filter.py +++ b/bot/src/bot_graphql/filter/scheduled_event_filter.py @@ -51,15 +51,15 @@ class ScheduledEventFilter(FilterABC): query = self._filter_by_attributes( [ - lambda x: x.id == self._id, - lambda x: x.interval == self._interval, - lambda x: x.name == self._name, - lambda x: x.description == self._description, - lambda x: x.channel_id == self._channel_id, - lambda x: x.start_time == self._start_time, - lambda x: x.end_time == self._end_time, - lambda x: x.entity_type == self._entity_type, - lambda x: x.location == self._location, + {"attr": self._id, "func": lambda x: x.id == self._id}, + {"attr": self._interval, "func": lambda x: x.interval == self._interval}, + {"attr": self._name, "func": lambda x: x.name == self._name}, + {"attr": self._description, "func": lambda x: x.description == self._description}, + {"attr": self._channel_id, "func": lambda x: x.channel_id == self._channel_id}, + {"attr": self._start_time, "func": lambda x: x.start_time == self._start_time}, + {"attr": self._end_time, "func": lambda x: x.end_time == self._end_time}, + {"attr": self._entity_type, "func": lambda x: x.entity_type == self._entity_type}, + {"attr": self._location, "func": lambda x: x.location == self._location}, ], query, ) diff --git a/bot/src/bot_graphql/mutation.py b/bot/src/bot_graphql/mutation.py index 39e38cc5..86b269d0 100644 --- a/bot/src/bot_graphql/mutation.py +++ b/bot/src/bot_graphql/mutation.py @@ -4,6 +4,7 @@ from bot_graphql.mutations.achievement_mutation import AchievementMutation from bot_graphql.mutations.auto_role_mutation import AutoRoleMutation from bot_graphql.mutations.auto_role_rule_mutation import AutoRoleRuleMutation from bot_graphql.mutations.level_mutation import LevelMutation +from bot_graphql.mutations.scheduled_event_mutation import ScheduledEventMutation from bot_graphql.mutations.server_config_mutation import ServerConfigMutation from bot_graphql.mutations.short_role_name_mutation import ShortRoleNameMutation from bot_graphql.mutations.technician_config_mutation import TechnicianConfigMutation @@ -23,6 +24,7 @@ class Mutation(MutationType): achievement_mutation: AchievementMutation, user_joined_game_server: UserJoinedGameServerMutation, technician_config: TechnicianConfigMutation, + scheduled_event: ScheduledEventMutation, server_config: ServerConfigMutation, short_role_name_mutation: ShortRoleNameMutation, ): @@ -36,4 +38,5 @@ class Mutation(MutationType): self.set_field("userJoinedGameServer", lambda *_: user_joined_game_server) self.set_field("shortRoleName", lambda *_: short_role_name_mutation) self.set_field("technicianConfig", lambda *_: technician_config) + self.set_field("scheduledEvent", lambda *_: scheduled_event) self.set_field("serverConfig", lambda *_: server_config) diff --git a/bot/src/bot_graphql/mutations/scheduled_event_mutation.py b/bot/src/bot_graphql/mutations/scheduled_event_mutation.py index c138b082..81353c62 100644 --- a/bot/src/bot_graphql/mutations/scheduled_event_mutation.py +++ b/bot/src/bot_graphql/mutations/scheduled_event_mutation.py @@ -1,9 +1,12 @@ +from datetime import datetime + from cpl_core.database.context import DatabaseContextABC from cpl_discord.service import DiscordBotServiceABC from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC from bot_data.model.scheduled_event import ScheduledEvent +from bot_data.model.scheduled_event_interval_enum import ScheduledEventIntervalEnum from bot_data.model.user_role_enum import UserRoleEnum from bot_graphql.abc.query_abc import QueryABC from modules.permission.service.permission_service import PermissionService @@ -35,14 +38,14 @@ class ScheduledEventMutation(QueryABC): self._can_user_mutate_data(server, UserRoleEnum.moderator) scheduled_event = ScheduledEvent( - input["interval"], + ScheduledEventIntervalEnum(input["interval"]), input["name"], - input["description"], - input["channel_id"], - input["start_time"], - input["end_time"], - input["entity_type"], - input["location"], + input["description"] if "description" in input else None, + input["channelId"] if "channelId" in input else None, + datetime.strptime(input["startTime"], "%Y-%m-%dT%H:%M:%S.%fZ"), + datetime.strptime(input["endTime"], "%Y-%m-%dT%H:%M:%S.%fZ") if "endTime" in input else None, + input["entityType"], + input["location"] if "location" in input else None, server, ) @@ -70,10 +73,10 @@ class ScheduledEventMutation(QueryABC): scheduled_event.interval = input["interval"] if "interval" in input else scheduled_event.interval scheduled_event.name = input["name"] if "name" in input else scheduled_event.name scheduled_event.description = input["description"] if "description" in input else scheduled_event.description - scheduled_event.channel_id = input["channel_id"] if "channel_id" in input else scheduled_event.channel_id - scheduled_event.start_time = input["start_time"] if "start_time" in input else scheduled_event.start_time - scheduled_event.end_time = input["end_time"] if "end_time" in input else scheduled_event.end_time - scheduled_event.entity_type = input["entity_type"] if "entity_type" in input else scheduled_event.entity_type + scheduled_event.channel_id = input["channelId"] if "channelId" in input else scheduled_event.channel_id + scheduled_event.start_time = input["startTime"] if "startTime" in input else scheduled_event.start_time + scheduled_event.end_time = input["endTime"] if "endTime" in input else scheduled_event.end_time + scheduled_event.entity_type = input["entityType"] if "entityType" in input else scheduled_event.entity_type scheduled_event.location = input["location"] if "location" in input else scheduled_event.location self._scheduled_events.update_scheduled_event(scheduled_event) diff --git a/web/package.json b/web/package.json index 3255abc5..281eca54 100644 --- a/web/package.json +++ b/web/package.json @@ -1,56 +1,56 @@ { - "name": "web", - "version": "1.2.2", - "scripts": { - "ng": "ng", - "update-version": "ts-node update-version.ts", - "prestart": "npm run update-version", - "start": "ng serve", - "prebuild": "npm run update-version", - "build": "ng build", - "watch": "ng build --watch --configuration development", - "test": "ng test", - "gv": "echo $npm_package_version", - "predocker-build": "npm run update-version", - "docker-build": "export VERSION=$npm_package_version; ng build; docker build -t sh-edraft.de/sdb-web:$VERSION .", - "docker-build-dev": "export VERSION=$npm_package_version; ng build --configuration development; docker build -t sh-edraft.de/sdb-web:$VERSION .", - "docker-build-stage": "export VERSION=$npm_package_version; ng build --configuration staging; docker build -t sh-edraft.de/sdb-web:$VERSION ." - }, - "private": true, - "dependencies": { - "@angular/animations": "^15.1.4", - "@angular/common": "^15.1.4", - "@angular/compiler": "^15.1.4", - "@angular/core": "^15.1.4", - "@angular/forms": "^15.1.4", - "@angular/platform-browser": "^15.1.4", - "@angular/platform-browser-dynamic": "^15.1.4", - "@angular/router": "^15.1.4", - "@auth0/angular-jwt": "^5.1.0", - "@microsoft/signalr": "^6.0.9", - "@ngx-translate/core": "^14.0.0", - "@ngx-translate/http-loader": "^7.0.0", - "@types/socket.io-client": "^3.0.0", - "moment": "^2.29.4", - "primeicons": "^6.0.1", - "primeng": "^15.2.0", - "rxjs": "~7.5.0", - "socket.io-client": "^4.5.3", - "zone.js": "~0.11.4" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^15.1.5", - "@angular/cli": "~15.1.5", - "@angular/compiler-cli": "^15.1.4", - "@types/jasmine": "~4.0.0", - "@types/node": "^18.11.9", - "jasmine-core": "~4.1.0", - "karma": "~6.3.0", - "karma-chrome-launcher": "~3.1.0", - "karma-coverage": "~2.2.0", - "karma-jasmine": "~5.0.0", - "karma-jasmine-html-reporter": "~1.7.0", - "tslib": "^2.4.1", - "typescript": "~4.9.5" - } -} + "name": "web", + "version": "1.2.dev410", + "scripts": { + "ng": "ng", + "update-version": "ts-node update-version.ts", + "prestart": "npm run update-version", + "start": "ng serve", + "prebuild": "npm run update-version", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test", + "gv": "echo $npm_package_version", + "predocker-build": "npm run update-version", + "docker-build": "export VERSION=$npm_package_version; ng build; docker build -t sh-edraft.de/sdb-web:$VERSION .", + "docker-build-dev": "export VERSION=$npm_package_version; ng build --configuration development; docker build -t sh-edraft.de/sdb-web:$VERSION .", + "docker-build-stage": "export VERSION=$npm_package_version; ng build --configuration staging; docker build -t sh-edraft.de/sdb-web:$VERSION ." + }, + "private": true, + "dependencies": { + "@angular/animations": "^15.1.4", + "@angular/common": "^15.1.4", + "@angular/compiler": "^15.1.4", + "@angular/core": "^15.1.4", + "@angular/forms": "^15.1.4", + "@angular/platform-browser": "^15.1.4", + "@angular/platform-browser-dynamic": "^15.1.4", + "@angular/router": "^15.1.4", + "@auth0/angular-jwt": "^5.1.0", + "@microsoft/signalr": "^6.0.9", + "@ngx-translate/core": "^14.0.0", + "@ngx-translate/http-loader": "^7.0.0", + "@types/socket.io-client": "^3.0.0", + "moment": "^2.29.4", + "primeicons": "^6.0.1", + "primeng": "^15.2.0", + "rxjs": "~7.5.0", + "socket.io-client": "^4.5.3", + "zone.js": "~0.11.4" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^15.1.5", + "@angular/cli": "~15.1.5", + "@angular/compiler-cli": "^15.1.4", + "@types/jasmine": "~4.0.0", + "@types/node": "^18.11.9", + "jasmine-core": "~4.1.0", + "karma": "~6.3.0", + "karma-chrome-launcher": "~3.1.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.0.0", + "karma-jasmine-html-reporter": "~1.7.0", + "tslib": "^2.4.1", + "typescript": "~4.9.5" + } +} \ No newline at end of file diff --git a/web/src/app/models/data/discord.model.ts b/web/src/app/models/data/discord.model.ts index 6e640052..a77de21e 100644 --- a/web/src/app/models/data/discord.model.ts +++ b/web/src/app/models/data/discord.model.ts @@ -1,4 +1,4 @@ -export interface Discord { +export interface Discord { guilds?: Guild[]; users?: DiscordUser[]; } @@ -21,7 +21,8 @@ export interface Channel { export enum ChannelType { category = "CategoryChannel", text = "TextChannel", - voice = "VoiceChannel" + voice = "VoiceChannel", + stage = "StageChannel" } export interface Role { diff --git a/web/src/app/models/data/scheduled_events.model.ts b/web/src/app/models/data/scheduled_events.model.ts index c3e8beea..972c10bb 100644 --- a/web/src/app/models/data/scheduled_events.model.ts +++ b/web/src/app/models/data/scheduled_events.model.ts @@ -9,12 +9,12 @@ export enum EventType { export interface ScheduledEvent extends DataWithHistory { id?: number; - interval?: string; + interval?: ScheduledEventInterval; name?: string; description?: string; channelId?: string; - startTime?: string; - endTime?: string; + startTime?: Date; + endTime?: Date; entityType?: EventType; location?: string; server?: Server; @@ -32,3 +32,10 @@ export interface ScheduledEventFilter { location?: string; server?: ServerFilter; } + +export enum ScheduledEventInterval { + daily = "daily", + weekly = "weekly", + monthly = "monthly", + yearly = "yearly" +} diff --git a/web/src/app/models/graphql/mutations.model.ts b/web/src/app/models/graphql/mutations.model.ts index 27fd48c1..95843b64 100644 --- a/web/src/app/models/graphql/mutations.model.ts +++ b/web/src/app/models/graphql/mutations.model.ts @@ -185,14 +185,16 @@ export class Mutations { endTime: $endTime, entityType: $entityType, location: $location, - serverId: $serverId} - ) { - id + serverId: $serverId + }) { + interval name description - attribute - operator - value + channelId + startTime + endTime + entityType + location server { id } @@ -215,12 +217,17 @@ export class Mutations { location: $location, serverId: $serverId} ) { - id + interval name description - attribute - operator - value + channelId + startTime + endTime + entityType + location + server { + id + } } } } @@ -397,7 +404,6 @@ export class Mutations { `; - static createUserWarning = ` mutation createUserWarning($name: String, $description: String, $attribute: String, $operator: String, $value: String, $serverId: ID) { userWarning { diff --git a/web/src/app/modules/shared/shared.module.ts b/web/src/app/modules/shared/shared.module.ts index 2a7bfc45..af9e8ea8 100644 --- a/web/src/app/modules/shared/shared.module.ts +++ b/web/src/app/modules/shared/shared.module.ts @@ -1,4 +1,4 @@ -import { CommonModule } from "@angular/common"; +import { CommonModule, DatePipe } from "@angular/common"; import { HttpClientModule } from "@angular/common/http"; import { NgModule } from "@angular/core"; import { FormsModule, ReactiveFormsModule } from "@angular/forms"; @@ -38,6 +38,8 @@ import { FileUploadModule } from "primeng/fileupload"; import { SelectButtonModule } from "primeng/selectbutton"; import { TabViewModule } from "primeng/tabview"; import { RadioButtonModule } from "primeng/radiobutton"; +import { InputTextareaModule } from "primeng/inputtextarea"; +import { InputMaskModule } from "primeng/inputmask"; const PrimeNGModules = [ @@ -69,7 +71,9 @@ const PrimeNGModules = [ FileUploadModule, SelectButtonModule, TabViewModule, - RadioButtonModule + RadioButtonModule, + InputTextareaModule, + InputMaskModule ]; @NgModule({ @@ -102,6 +106,9 @@ const PrimeNGModules = [ MultiSelectColumnsComponent, FeatureFlagListComponent, DataImportAndExportComponent + ], + providers: [ + DatePipe ] }) export class SharedModule { diff --git a/web/src/app/modules/view/server/scheduled-events/components/edit-scheduled-event-dialog/edit-scheduled-event-dialog.component.html b/web/src/app/modules/view/server/scheduled-events/components/edit-scheduled-event-dialog/edit-scheduled-event-dialog.component.html index 938281d5..62289884 100644 --- a/web/src/app/modules/view/server/scheduled-events/components/edit-scheduled-event-dialog/edit-scheduled-event-dialog.component.html +++ b/web/src/app/modules/view/server/scheduled-events/components/edit-scheduled-event-dialog/edit-scheduled-event-dialog.component.html @@ -1,44 +1,92 @@