diff --git a/db/constants.py b/db/constants.py index 5bb13ef..df3dfa5 100644 --- a/db/constants.py +++ b/db/constants.py @@ -3,3 +3,6 @@ TIMELINE_ORDER_ISSUED = "ORDER_ISSUED" TIMELINE_ORDER_CONFIRMED = "ORDER_CONFIRMED" TIMELINE_ORDER_NOT_PUNISHED = "ORDER_NOT_PUNISHED" TIMELINE_ORDER_PUNISHED = "ORDER_PUNISHED" +TIMELINE_ORDERS_POOL_CREATED = "ORDERS_POOL_CREATED" +TIMELINE_ORDERS_POOL_UPDATED = "ORDERS_POOL_UPDATED" +TIMELINE_ORDERS_POOL_DELETED = "ORDERS_POOL_DELETED" diff --git a/db/models.py b/db/models.py index 21c97cf..a918cfa 100644 --- a/db/models.py +++ b/db/models.py @@ -227,7 +227,7 @@ class TimelineEvent(BaseModel): OrdersPool, column_name='orders_pool_id', field='id', - null=False, + null=True, backref="timeline_events" ) diff --git a/db/queries.py b/db/queries.py index 2e98e99..bc534d0 100644 --- a/db/queries.py +++ b/db/queries.py @@ -164,7 +164,7 @@ def order_status_outstanding(): .having(fn.COUNT(Punishment.id) == 0) ) -def timeline_event_put(type, text, user, orders_pool, order_status=None, extra=None): +def timeline_event_put(type, text, user, orders_pool=None, order_status=None, extra=None): return TimelineEvent.create( updated_at=sqlite_time(datetime.datetime.now(datetime.UTC)), type=type, diff --git a/migrations/023_timeline_event_null_orders_pool.py b/migrations/023_timeline_event_null_orders_pool.py new file mode 100644 index 0000000..ce77b17 --- /dev/null +++ b/migrations/023_timeline_event_null_orders_pool.py @@ -0,0 +1,50 @@ +"""Peewee migrations -- 023_timeline_event_null_orders_pool.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['table_name'] # Return model in current state by name + > Model = migrator.ModelClass # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.run(func, *args, **kwargs) # Run python function with the given args + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.add_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + > migrator.add_constraint(model, name, sql) + > migrator.drop_index(model, *col_names) + > migrator.drop_not_null(model, *field_names) + > migrator.drop_constraints(model, *constraints) + +""" + +from contextlib import suppress + +import peewee as pw +from peewee_migrate import Migrator + + +with suppress(ImportError): + import playhouse.postgres_ext as pw_pext + + +def migrate(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your migrations here.""" + + # migrator.change_fields('timeline_event', orders_pool=pw.ForeignKeyField(column_name='orders_pool_id', field='id', model=migrator.orm['orders_pool'], null=True)) + + migrator.drop_not_null('timeline_event', 'orders_pool') + + +def rollback(migrator: Migrator, database: pw.Database, *, fake=False): + """Write your rollback migrations here.""" + + migrator.change_fields('timeline_event', orders_pool=pw.ForeignKeyField(column_name='orders_pool_id', field='id', model=migrator.orm['orders_pool'])) + + migrator.add_not_null('timeline_event', 'orders_pool') diff --git a/web/api.py b/web/api.py index 3db9286..aeeffd6 100644 --- a/web/api.py +++ b/web/api.py @@ -4,8 +4,9 @@ import json from functools import wraps from flask import Blueprint, jsonify, abort, request from flask_login import login_required, current_user +from db.constants import TIMELINE_ORDERS_POOL_CREATED, TIMELINE_ORDERS_POOL_DELETED, TIMELINE_ORDERS_POOL_UPDATED from db.models import database, OrdersPool, Order, OrderAddOn, MastodonServer -from db.queries import timeline_event_recent, user_get, domsubusers_list, orders_pool_list, orders_pool, mastodon_server_get, mastodon_server_put, user_mastodon_server_set, user_preferences_set +from db.queries import timeline_event_put, timeline_event_recent, user_get, domsubusers_list, orders_pool_list, orders_pool, mastodon_server_get, mastodon_server_put, user_mastodon_server_set, user_preferences_set from settings import MASTODON_OAUTH_CLIENT_NAME, MASTODON_OAUTH_REDIRECT_URI, MASTODON_OAUTH_SCOPES, MASTODON_OAUTH_CLIENT_WEBSITE from util import time_sqlite @@ -66,7 +67,7 @@ def timeline(): "orders_pool": { "id": t.orders_pool.id, "name": t.orders_pool.name, - }, + } if t.orders_pool is not None else None, "order_status": t.order_status.text if t.order_status is not None else None, } for t in timeline_event_recent(current_user.db_user.id) ]) @@ -231,7 +232,15 @@ def sub_order_set_create(username, sub): name=add_on_to_create['name'], probability=add_on_to_create['probability'] ) - except: + + timeline_event_put( + TIMELINE_ORDERS_POOL_CREATED, + new_order_pool.name, + current_user.db_user, + new_order_pool + ) + except Exception as e: + print(e) transaction.rollback() abort(500) @@ -314,12 +323,30 @@ def sub_order_set(username, set_id, sub): ) update_add_ons(order_to_update, updated_order['add_ons']) + + timeline_event_put( + TIMELINE_ORDERS_POOL_UPDATED, + op.name, + current_user.db_user, + op + ) except Exception as e: print(e) transaction.rollback() abort(500) elif request.method == 'DELETE': - op.delete_instance(recursive=True) - return ('', 204) + try: + op.delete_instance(recursive=True) + + timeline_event_put( + TIMELINE_ORDERS_POOL_DELETED, + op.name, + current_user.db_user + ) + + return ('', 204) + except Exception as e: + print(e) + abort(500) return jsonify(op.to_dict()) diff --git a/web/vite/src/TimelineList.tsx b/web/vite/src/TimelineList.tsx index d093d58..3020030 100644 --- a/web/vite/src/TimelineList.tsx +++ b/web/vite/src/TimelineList.tsx @@ -7,6 +7,10 @@ import { IconArrowBadgeRightFilled, IconCheck, IconExternalLink, + IconFileDiff, + IconFileMinus, + IconFilePlus, + IconPlaylistAdd, IconX, } from "@tabler/icons-react"; @@ -36,6 +40,21 @@ const TIMELINE_TYPE = { color: "red.6", bullet: , }, + ORDERS_POOL_CREATED: { + title: "Orders pool created", + color: "green.3", + bullet: , + }, + ORDERS_POOL_UPDATED: { + title: "Orders pool updated", + color: "green.3", + bullet: , + }, + ORDERS_POOL_DELETED: { + title: "Orders pool deleted", + color: "red.3", + bullet: , + }, }; export const TimelineList: React.FC<{