#268_achievements #325

Merged
edraft merged 23 commits from #268_achievements into 1.1.0 2023-08-14 09:36:20 +02:00
17 changed files with 123 additions and 20 deletions
Showing only changes of commit fedf2f4b8b - Show all commits

View File

@ -27,6 +27,10 @@ class AchievementRepositoryABC(ABC):
def get_achievements_by_user_id(self, user_id: int) -> List[Achievement]:
pass
@abstractmethod
def get_user_got_achievements_by_achievement_id(self, achievement_id: int) -> List[Achievement]:
pass
@abstractmethod
def add_achievement(self, achievement: Achievement):
pass

View File

@ -21,6 +21,7 @@ class AchievementsMigration(MigrationABC):
CREATE TABLE IF NOT EXISTS `Achievements` (
`Id` BIGINT NOT NULL AUTO_INCREMENT,
`Name` VARCHAR(255) NOT NULL,
`Description` VARCHAR(255) NOT NULL,
`Attribute` VARCHAR(255) NOT NULL,
`Operator` VARCHAR(255) NOT NULL,
`Value` VARCHAR(255) NOT NULL,
@ -41,6 +42,7 @@ class AchievementsMigration(MigrationABC):
(
`Id` BIGINT(20) NOT NULL,
`Name` VARCHAR(255) NOT NULL,
`Description` VARCHAR(255) NOT NULL,
`Attribute` VARCHAR(255) NOT NULL,
`Operator` VARCHAR(255) NOT NULL,
`Value` VARCHAR(255) NOT NULL,
@ -77,41 +79,45 @@ class AchievementsMigration(MigrationABC):
self._cursor.execute(str(f"""ALTER TABLE UsersHistory ADD MessageCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""))
self._cursor.execute(str(f"""ALTER TABLE UsersHistory ADD ReactionCount BIGINT NOT NULL DEFAULT 0 AFTER XP;"""))
self._cursor.execute(str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsUpdate`;"""))
self._cursor.execute(
str(
f"""
DROP TRIGGER IF EXISTS `TR_AchievementsUpdate`;
CREATE TRIGGER `TR_AchievementsUpdate`
AFTER UPDATE
ON `Achievements`
FOR EACH ROW
BEGIN
INSERT INTO `AchievementsHistory` (
`Id`, `Name`, `Attribute`, `Operator`, `Value`, `ServerId`, `DateFrom`, `DateTo`
`Id`, `Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId`, `DateFrom`, `DateTo`
)
VALUES (
OLD.Id, OLD.Name, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)
OLD.Id, OLD.Name, OLD.Description, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)
);
END;
DROP TRIGGER IF EXISTS `TR_AchievementsDelete`;
"""
)
)
self._cursor.execute(str(f"""DROP TRIGGER IF EXISTS `TR_AchievementsDelete`;"""))
self._cursor.execute(
str(
f"""
CREATE TRIGGER `TR_AchievementsDelete`
AFTER DELETE
ON `Achievements`
FOR EACH ROW
BEGIN
INSERT INTO `AchievementsHistory` (
`Id`, `Name`, `Attribute`, `Operator`, `Value`, `ServerId`, `Deleted`, `DateFrom`, `DateTo`
`Id`, `Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId`, `Deleted`, `DateFrom`, `DateTo`
)
VALUES (
OLD.Id, OLD.Name, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)
OLD.Id, OLD.Name, OLD.Description, OLD.Attribute, OLD.Operator, OLD.Value, OLD.ServerId, TRUE, OLD.LastModifiedAt, CURRENT_TIMESTAMP(6)
);
END;
"""
),
multi=True,
)
)
def downgrade(self):

View File

@ -11,6 +11,7 @@ class Achievement(TableABC):
def __init__(
self,
name: str,
description: str,
attribute: str,
operator: str,
value: str,
@ -21,6 +22,7 @@ class Achievement(TableABC):
):
self._id = id
self._name = name
self._description = description
self._attribute = attribute
if self._is_operator_valid(operator):
@ -53,6 +55,14 @@ class Achievement(TableABC):
def name(self, value: str):
self._name = value
@property
def description(self) -> str:
return self._description
@description.setter
def description(self, value: str):
self._description = value
@property
def attribute(self) -> str:
return self._attribute
@ -103,9 +113,10 @@ class Achievement(TableABC):
return str(
f"""
INSERT INTO `Achievements` (
`Name`, `Attribute`, `Operator`, `Value`, `ServerId`
`Name`, `Description`, `Attribute`, `Operator`, `Value`, `ServerId`
) VALUES (
'{self._name}',
'{self._description}',
'{self._attribute}',
'{self._operator}',
'{self._value}',
@ -120,6 +131,7 @@ class Achievement(TableABC):
f"""
UPDATE `Achievements`
SET `Name` = '{self._name}',
`Description` = '{self._description}',
`Attribute` = '{self._attribute}',
`Operator` = '{self._operator}',
`Value` = '{self._value}'

View File

@ -5,6 +5,7 @@ class AchievementHistory(HistoryTableABC):
def __init__(
self,
name: str,
description: str,
attribute: str,
operator: str,
value: str,
@ -18,6 +19,7 @@ class AchievementHistory(HistoryTableABC):
self._id = id
self._name = name
self._description = description
self._attribute = attribute
self._operator = operator
self._value = value
@ -35,6 +37,10 @@ class AchievementHistory(HistoryTableABC):
def name(self) -> str:
return self._name
@property
def description(self) -> str:
return self._description
@property
def attribute(self) -> str:
return self._attribute

View File

@ -62,6 +62,15 @@ class UserGotAchievement(TableABC):
"""
)
@staticmethod
def get_select_by_achievement_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `UserGotAchievements`
WHERE `AchievementId` = {id};
"""
)
@property
def insert_string(self) -> str:
return str(

View File

@ -31,9 +31,10 @@ class AchievementRepositoryService(AchievementRepositoryABC):
result[2],
result[3],
result[4],
self._servers.get_server_by_id(result[5]),
result[6],
result[5],
self._servers.get_server_by_id(result[6]),
result[7],
result[8],
id=result[0],
)
@ -89,6 +90,18 @@ class AchievementRepositoryService(AchievementRepositoryABC):
return achievements
def get_user_got_achievements_by_achievement_id(self, achievement_id: int) -> List[Achievement]:
achievements_joins = List(UserGotAchievement)
self._logger.trace(
__name__, f"Send SQL command: {UserGotAchievement.get_select_by_achievement_id_string(achievement_id)}"
)
results = self._context.select(UserGotAchievement.get_select_by_achievement_id_string(achievement_id))
for result in results:
self._logger.trace(__name__, f"Got UserGotAchievement with id {result[0]}")
achievements_joins.append(self._join_from_result(result))
return achievements_joins
def add_achievement(self, achievement: Achievement):
self._logger.trace(__name__, f"Send SQL command: {achievement.insert_string}")
self._context.cursor.execute(achievement.insert_string)

View File

@ -10,6 +10,7 @@ class AchievementFilter(FilterABC):
self._id = None
self._name = None
self._description = None
self._attribute = None
self._operator = None
self._value = None
@ -22,6 +23,9 @@ class AchievementFilter(FilterABC):
if "name" in values:
self._name = values["name"]
if "description" in values:
self._description = values["description"]
if "attribute" in values:
self._attribute = values["attribute"]
@ -42,10 +46,13 @@ class AchievementFilter(FilterABC):
query = query.where(lambda x: x.id == self._id)
if self._name is not None:
query = query.where(lambda x: x.name == self._name)
query = query.where(lambda x: x.name == self._name or self._name in x.name)
if self._description is not None:
query = query.where(lambda x: x.description == self._description or self._description in x.description)
if self._attribute is not None:
query = query.where(lambda x: x.attribute == self._attribute)
query = query.where(lambda x: x.attribute == self._attribute or self._attribute in x.attribute)
if self._operator is not None:
query = query.where(lambda x: x.operator == self._operator)

View File

@ -9,6 +9,7 @@ type AchievementAttribute {
type Achievement implements TableWithHistoryQuery {
id: ID
name: String
description: String
attribute: String
operator: String
value: String
@ -24,6 +25,7 @@ type Achievement implements TableWithHistoryQuery {
type AchievementHistory implements HistoryTableQuery {
id: ID
name: String
description: String
attribute: String
operator: String
value: String
@ -38,6 +40,7 @@ type AchievementHistory implements HistoryTableQuery {
input AchievementFilter {
id: ID
name: String
description: String
attribute: String
operator: String
value: String
@ -53,6 +56,7 @@ type AchievementMutation {
input AchievementInput {
id: ID
name: String
description: String
attribute: String
operator: String
value: String

View File

@ -36,6 +36,7 @@ class AchievementMutation(QueryABC):
achievement = Achievement(
input["name"],
input["description"],
input["attribute"],
input["operator"],
input["value"],
@ -47,6 +48,7 @@ class AchievementMutation(QueryABC):
def get_new_achievement(a: Achievement):
return (
a.name == achievement.name
and a.description == achievement.description
and a.attribute == achievement.attribute
and a.operator == achievement.operator
and a.value == achievement.value
@ -60,6 +62,7 @@ class AchievementMutation(QueryABC):
self._can_user_mutate_data(achievement.server, UserRoleEnum.moderator)
achievement.name = input["name"] if "name" in input else achievement.name
achievement.description = input["description"] if "description" in input else achievement.description
achievement.attribute = input["attribute"] if "attribute" in input else achievement.attribute
achievement.operator = input["operator"] if "operator" in input else achievement.operator
achievement.value = input["value"] if "value" in input else achievement.value
@ -74,6 +77,10 @@ class AchievementMutation(QueryABC):
achievement = self._achievements.get_achievement_by_id(id)
self._can_user_mutate_data(achievement.server, UserRoleEnum.admin)
joins = self._achievements.get_user_got_achievements_by_achievement_id(id)
for join in joins:
self._achievements.delete_user_got_achievement(join)
self._achievements.delete_achievement(achievement)
self._db.save_changes()

View File

@ -7,6 +7,7 @@ class AchievementHistoryQuery(HistoryQueryABC):
self.set_field("id", lambda x, *_: x.id)
self.set_field("name", lambda x, *_: x.name)
self.set_field("description", lambda x, *_: x.description)
self.set_field("attribute", lambda x, *_: x.attribute)
self.set_field("operator", lambda x, *_: x.operator)
self.set_field("value", lambda x, *_: x.value)

View File

@ -13,6 +13,7 @@ class AchievementQuery(DataQueryWithHistoryABC):
self.set_field("id", lambda x, *_: x.id)
self.set_field("name", lambda x, *_: x.name)
self.set_field("description", lambda x, *_: x.description)
self.set_field("attribute", lambda x, *_: x.attribute)
self.set_field("operator", lambda x, *_: x.operator)
self.set_field("value", lambda x, *_: x.value)

View File

@ -9,6 +9,7 @@ export interface AchievementAttribute {
export interface Achievement extends DataWithHistory {
id?: number;
name?: string;
description?: string;
attribute?: string | AchievementAttribute;
operator?: string;
value?: string;
@ -20,6 +21,7 @@ export interface Achievement extends DataWithHistory {
export interface AchievementFilter {
id?: number;
name?: string;
description?: string;
attribute?: string;
operator?: string;
value?: string;

View File

@ -123,11 +123,12 @@ export class Mutations {
`;
static createAchievement = `
mutation createAchievement($name: String, $attribute: String, $operator: String, $value: String, $serverId: ID) {
mutation createAchievement($name: String, $description: String, $attribute: String, $operator: String, $value: String, $serverId: ID) {
achievement {
createAchievement(input: { name: $name, attribute: $attribute, operator: $operator, value: $value, serverId: $serverId}) {
createAchievement(input: { name: $name, description: $description, attribute: $attribute, operator: $operator, value: $value, serverId: $serverId}) {
id
name
description
attribute
operator
value
@ -140,11 +141,12 @@ export class Mutations {
`;
static updateAchievement = `
mutation updateAchievement($id: ID, $name: String, $attribute: String, $operator: String, $value: String) {
mutation updateAchievement($id: ID, $name: String, $description: String, $attribute: String, $operator: String, $value: String) {
achievement {
updateAchievement(input: { id: $id, name: $name, attribute: $attribute, operator: $operator, value: $value}) {
updateAchievement(input: { id: $id, name: $name, description: $description, attribute: $attribute, operator: $operator, value: $value}) {
id
name
description
attribute
operator
value

View File

@ -117,6 +117,7 @@ export class Queries {
achievements(filter: $filter, page: $page, sort: $sort) {
id
name
description
attribute
operator
value
@ -141,6 +142,7 @@ export class Queries {
history {
id
name
description
attribute
operator
value

View File

@ -43,6 +43,13 @@
</div>
</th>
<th pSortableColumn="description">
<div class="table-header-label">
<div class="table-header-text">{{'view.server.achievements.headers.description' | translate}}</div>
<p-sortIcon field="name" class="table-header-icon"></p-sortIcon>
</div>
</th>
<th pSortableColumn="attribute">
<div class="table-header-label">
<div class="table-header-text">{{'view.server.achievements.headers.attribute' | translate}}</div>
@ -96,6 +103,12 @@
placeholder="{{'view.server.achievements.headers.name' | translate}}">
</form>
</th>
<th>
<form [formGroup]="filterForm">
<input type="text" pInputText formControlName="name"
placeholder="{{'view.server.achievements.headers.description' | translate}}">
</form>
</th>
<th></th>
<th></th>
<th></th>
@ -129,6 +142,17 @@
</p-cellEditor>
</td>
<td>
<p-cellEditor>
<ng-template pTemplate="input">
<input class="table-edit-input" pInputText type="text" [(ngModel)]="achievement.description">
</ng-template>
<ng-template pTemplate="output">
{{achievement.description}}
</ng-template>
</p-cellEditor>
</td>
<td>
<p-cellEditor>
<ng-template pTemplate="input">

View File

@ -227,6 +227,7 @@ export class AchievementComponent implements OnInit, OnDestroy {
this.spinner.showSpinner();
this.data.mutation<AchievementMutationResult>(Mutations.createAchievement, {
name: newAchievement.name,
description: newAchievement.description,
attribute: newAchievement.attribute,
operator: newAchievement.operator,
value: newAchievement.value + "",
@ -250,6 +251,7 @@ export class AchievementComponent implements OnInit, OnDestroy {
this.data.mutation<AchievementMutationResult>(Mutations.updateAchievement, {
id: newAchievement.id,
name: newAchievement.name,
description: newAchievement.description,
attribute: newAchievement.attribute,
operator: newAchievement.operator,
value: newAchievement.value + ""

View File

@ -326,6 +326,7 @@
"headers": {
"attribute": "Attribut",
"name": "Name",
"description": "Beschreibung",
"operator": "Operator",
"value": "Wert"
},