#268_achievements #325
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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}'
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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">
|
||||
|
@ -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 + ""
|
||||
|
@ -326,6 +326,7 @@
|
||||
"headers": {
|
||||
"attribute": "Attribut",
|
||||
"name": "Name",
|
||||
"description": "Beschreibung",
|
||||
"operator": "Operator",
|
||||
"value": "Wert"
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user