diff --git a/kontor-api/src/apis/version1/comic.py b/kontor-api/src/apis/version1/comic.py index a558b3b..2541f2b 100644 --- a/kontor-api/src/apis/version1/comic.py +++ b/kontor-api/src/apis/version1/comic.py @@ -1,11 +1,10 @@ -from uuid import UUID -from typing import List +from typing import List, AnyStr from fastapi import APIRouter, HTTPException, status -from sqlalchemy import select from src.apis.utils import SessionDep +from src.db.repository.comic import get_artist_details, list_comics from src.schema.comics.comic import ComicResponse, ComicDetailsResponse, get_comic_details, get_short_info -from src.schema.comics.artist import ArtistCreation, ArtistDetailResponse, ArtistResponse, get_artist_details +from src.schema.comics.artist import ArtistCreation, ArtistDetailResponse, ArtistResponse from src.db.models.comic import Comic, Artist router = APIRouter( @@ -18,14 +17,14 @@ router = APIRouter( @router.get("/comics") def get_all_comics(db: SessionDep) -> List[ComicResponse]: results: List[ComicResponse] = [] - comics = db.scalars(select(Comic)).all() + comics = list_comics(db) for comic in comics: response = get_short_info(comic) results.append(response) return results @router.get("/comics/{comic_id}", response_model=ComicDetailsResponse) -def get_comic(comic_id: UUID, db: SessionDep) -> ComicDetailsResponse: +def get_comic(comic_id: AnyStr, db: SessionDep) -> ComicDetailsResponse: comic = db.get(Comic, comic_id) if comic is None: raise HTTPException(status_code=404, detail="Comic could not be found") @@ -41,7 +40,7 @@ def get_all_artists(db: SessionDep) -> List[ArtistResponse]: return results @router.get("/artists/{artist_id}", response_model=ArtistDetailResponse) -def get_artist(artist_id: UUID, db: SessionDep) -> ArtistDetailResponse: +def get_artist(artist_id: AnyStr, db: SessionDep) -> ArtistDetailResponse: artist = db.get(Artist, artist_id) if artist is None: raise HTTPException(status_code=404, detail="Artist could not be found") diff --git a/kontor-api/src/apis/version1/media.py b/kontor-api/src/apis/version1/media.py index 2fa7347..f6b4b7e 100644 --- a/kontor-api/src/apis/version1/media.py +++ b/kontor-api/src/apis/version1/media.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List, AnyStr from uuid import UUID from fastapi import APIRouter, status, HTTPException @@ -42,7 +42,7 @@ def get_all_files(db: SessionDep, review: bool = False, download: bool = False) return results @router.get("/files/{file_id}", response_model=MediaFileResponse) -def get_file(file_id: UUID, db: SessionDep) -> MediaFileResponse: +def get_file(file_id: AnyStr, db: SessionDep) -> MediaFileResponse: mediafile = db.get(MediaFile, file_id) if not mediafile: raise HTTPException(status_code=404, detail="MediaFile could not be found") @@ -50,7 +50,7 @@ def get_file(file_id: UUID, db: SessionDep) -> MediaFileResponse: return response @router.put("/files/{file_id}", response_model=MediaFileResponse) -def update_file(file_id: UUID, db: SessionDep, info: MediaFileResponse) -> MediaFileResponse: +def update_file(file_id: AnyStr, db: SessionDep, info: MediaFileResponse) -> MediaFileResponse: mediaFile = db.get(MediaFile, file_id) if not mediaFile: raise HTTPException(status_code=404, detail="MediaFile could not be found") diff --git a/kontor-api/src/db/models/admin.py b/kontor-api/src/db/models/admin.py index caecff8..50f0656 100644 --- a/kontor-api/src/db/models/admin.py +++ b/kontor-api/src/db/models/admin.py @@ -8,11 +8,11 @@ from src.db.models.base import Base, BaseMixin class Profile(Base, BaseMixin): __tablename__ = 'profile' - first_name = Column(String(255)) - last_name = Column(String(255)) - user_name = Column(String(255), nullable=False) - email = Column(String(255)) - password = Column(String(255)) + first_name = Column(String) + last_name = Column(String) + user_name = Column(String, nullable=False) + email = Column(String) + password = Column(String) enabled = Column(Boolean) assignments = relationship("Assignment") tokens = relationship("Token") @@ -30,17 +30,17 @@ class Profile(Base, BaseMixin): class Token(Base, BaseMixin): __tablename__ = "token" - token = Column(String(255), nullable=False, unique=True) - name = Column(String(255)) + token = Column(String, nullable=False, unique=True) + name = Column(String) last_used_date: Mapped[datetime] = mapped_column() enabled = Column(Boolean) - profile_id = Column(String(255), ForeignKey("profile.id"), nullable=False) + profile_id = Column(String, ForeignKey("profile.id"), nullable=False) profile = relationship("Profile", back_populates="tokens") class Permission(Base, BaseMixin): __tablename__ = "permission" - name = Column(String(255), nullable=False) + name = Column(String, nullable=False) assignments = relationship("Assignment") @@ -54,17 +54,17 @@ class Assignment(Base, BaseMixin): class ModuleData(Base, BaseMixin): __tablename__ = "module_data" - module_name = Column(String(255), nullable=False) + module_name = Column(String, nullable=False) import_data = Column(Boolean) class MailAccount(Base, BaseMixin): __tablename__ = "mail_account" - host = Column(String(255)) + host = Column(String) port = Column(Integer) - protocol = Column(String(255)) - user_name = Column(String(255)) - password = Column(String(255)) + protocol = Column(String) + user_name = Column(String) + password = Column(String) start_tls = Column(Boolean) diff --git a/kontor-api/src/db/models/base.py b/kontor-api/src/db/models/base.py index 5ef8183..d090abf 100644 --- a/kontor-api/src/db/models/base.py +++ b/kontor-api/src/db/models/base.py @@ -10,8 +10,8 @@ class Base(DeclarativeBase): class BaseMixin: - id = Column(String(255), primary_key=True, default=uuid.uuid4()) - # id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4()) + #id = Column(String(255), primary_key=True, default=uuid.uuid4) + id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4) # created_date = Column(DateTime) created_date: Mapped[datetime] = mapped_column(default=func.now()) # last_modified_date = Column(DateTime) @@ -21,10 +21,10 @@ class BaseMixin: class BaseVideoMixin: - cloud_link = Column(String(255)) - file_name = Column(String(255)) - path = Column(String(255)) + cloud_link = Column(String) + file_name = Column(String) + path = Column(String) review = Column(Boolean) - title = Column(String(255)) - url = Column(String(255), unique=True) + title = Column(String) + url = Column(String, unique=True) should_download = Column(Boolean) diff --git a/kontor-api/src/db/models/comic.py b/kontor-api/src/db/models/comic.py index 35962f3..7162d84 100644 --- a/kontor-api/src/db/models/comic.py +++ b/kontor-api/src/db/models/comic.py @@ -8,7 +8,7 @@ from src.db.models.base import Base, BaseMixin class Publisher(Base, BaseMixin): __tablename__ = "publisher" - name = Column(String(length=255), unique=True) + name = Column(String, unique=True) comics = relationship("Comic") def __repr__(self): @@ -20,7 +20,7 @@ class Publisher(Base, BaseMixin): class Comic(Base, BaseMixin): __tablename__ = 'comic' - title = Column(String(length=255), unique=True) + title = Column(String, unique=True) publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False) publisher = relationship("Publisher", back_populates="comics") current_order = Column(Boolean) @@ -55,7 +55,7 @@ class Comic(Base, BaseMixin): class Volume(Base, BaseMixin): __tablename__ = "volume" - name = Column(String(length=255), nullable=False) + name = Column(String, nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic = relationship("Comic", back_populates="volumes") issues = relationship("Issue") @@ -63,7 +63,7 @@ class Volume(Base, BaseMixin): class TradePaperback(Base, BaseMixin): __tablename__ = "trade_paperback" - name = Column(String(length=255), nullable=False) + name = Column(String, nullable=False) issue_start = Column(Integer) issue_end = Column(Integer) comic_id = Column(String, ForeignKey("comic.id"), nullable=False) @@ -72,14 +72,14 @@ class TradePaperback(Base, BaseMixin): class StoryArc(Base, BaseMixin): __tablename__ = "story_arc" - name = Column(String(length=255), nullable=False) + name = Column(String, nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic = relationship("Comic", back_populates="story_arcs") class Issue(Base, BaseMixin): __tablename__ = "issue" - issue_number = Column(String(255)) + issue_number = Column(String) in_stock = Column(Boolean) is_read = Column(Boolean) comic_id = Column(String, ForeignKey("comic.id"), nullable=False) @@ -90,7 +90,7 @@ class Issue(Base, BaseMixin): class Artist(Base, BaseMixin): __tablename__ = "artist" - name = Column(String(length=255), nullable=False) + name = Column(String, nullable=False) comic_works = relationship("ComicWork") def get_comics(self) -> Dict[str, List[str]]: @@ -107,7 +107,7 @@ class Artist(Base, BaseMixin): class WorkType(Base, BaseMixin): __tablename__ = "worktype" - name = Column(String(length=255), nullable=False, unique=True) + name = Column(String, nullable=False, unique=True) comic_works = relationship("ComicWork") def __repr__(self): diff --git a/kontor-api/src/db/models/media.py b/kontor-api/src/db/models/media.py index 2b19aa6..a0ccd32 100644 --- a/kontor-api/src/db/models/media.py +++ b/kontor-api/src/db/models/media.py @@ -70,31 +70,31 @@ class MediaFile(Base, BaseMixin, BaseVideoMixin): class MediaActor(Base, BaseMixin): __tablename__ = 'media_actor' - name = Column(String(255)) + name = Column(String) media_actor_files = relationship("MediaActorFile") class MediaActorFile(Base, BaseMixin): __tablename__ = 'media_actor_file' - media_actor_id = Column(String(255), ForeignKey("media_actor.id"), nullable=False) + media_actor_id = Column(String, ForeignKey("media_actor.id"), nullable=False) media_actor = relationship("MediaActor", back_populates="media_actor_files") - media_file_id = Column(String(255), ForeignKey("media_file.id"), nullable=True) + media_file_id = Column(String, ForeignKey("media_file.id"), nullable=True) media_file = relationship("MediaFile", back_populates="media_actor_files") class MediaArticle(Base, BaseMixin): __tablename__ = 'media_article' review = Column(Boolean) - title = Column(String(255)) - url = Column(String(255), unique=True) + title = Column(String) + url = Column(String, unique=True) class MediaVideo(Base, BaseMixin): __tablename__ = 'media_video' - cloud_link = Column(String(255)) - file_name = Column(String(255)) - path = Column(String(255)) + cloud_link = Column(String) + file_name = Column(String) + path = Column(String) review = Column(Boolean) - title = Column(String(255)) - url = Column(String(255), unique=True) + title = Column(String) + url = Column(String, unique=True) should_download = Column(Boolean) diff --git a/kontor-api/src/db/models/metadata.py b/kontor-api/src/db/models/metadata.py index 131f325..ecf24ca 100644 --- a/kontor-api/src/db/models/metadata.py +++ b/kontor-api/src/db/models/metadata.py @@ -6,7 +6,7 @@ from src.db.models.base import Base, BaseMixin class MetaDataTable(Base, BaseMixin): __tablename__ = 'meta_data_table' - table_name = Column(String(255), unique=True) + table_name = Column(String, unique=True) table_columns = relationship("MetaDataColumn") def __repr__(self): @@ -18,15 +18,15 @@ class MetaDataTable(Base, BaseMixin): class MetaDataColumn(Base, BaseMixin): __tablename__ = 'meta_data_column' - column_name = Column(String(255), nullable=False) - column_sync_name = Column(String(255)) - column_type = Column(String(255)) - column_modifier = Column(String(255), nullable=True) + column_name = Column(String, nullable=False) + column_sync_name = Column(String) + column_type = Column(String) + column_modifier = Column(String, nullable=True) column_order = Column(Integer) table_id = Column(String, ForeignKey('meta_data_table.id')) table = relationship("MetaDataTable", back_populates="table_columns") - column_label = Column(String(255)) - filter_label = Column(String(255)) + column_label = Column(String) + filter_label = Column(String) is_shown = Column(Boolean) show_filter = Column(Boolean) ref_column = Column(String, nullable=True) diff --git a/kontor-api/src/db/models/tysc.py b/kontor-api/src/db/models/tysc.py index d3c391d..3a4f553 100644 --- a/kontor-api/src/db/models/tysc.py +++ b/kontor-api/src/db/models/tysc.py @@ -9,15 +9,15 @@ class Sport(Base, BaseMixin): __table_args__ = ( UniqueConstraint("name"), ) - name = Column(String(255), nullable=False, index=True, unique=True) + name = Column(String, nullable=False, index=True, unique=True) teams = relationship("Team") positions = relationship("FieldPosition") class Team(Base, BaseMixin): __tablename__ = "team" - name = Column(String(255), nullable=False, index=True, unique=True) - short_name = Column(String(255), nullable=False, ) + name = Column(String, nullable=False, index=True, unique=True) + short_name = Column(String, nullable=False, ) sport_id = Column(String, ForeignKey("sport.id"), nullable=False) sport = relationship("Sport", back_populates="teams") roosters = relationship("Rooster") @@ -29,8 +29,8 @@ class FieldPosition(Base, BaseMixin): UniqueConstraint("name", "sport_id"), UniqueConstraint("short_name", "sport_id"), ) - name = Column(String(255), nullable=False, index=True) - short_name = Column(String(255), nullable=False) + name = Column(String, nullable=False, index=True) + short_name = Column(String, nullable=False) sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True) sport = relationship("Sport", back_populates="positions") roosters = relationship("Rooster") @@ -41,8 +41,8 @@ class Player(Base, BaseMixin): __table_args__ = ( UniqueConstraint("first_name", "last_name"), ) - first_name = Column(String(255), nullable=False, index=True) - last_name = Column(String(255), nullable=False, index=True) + first_name = Column(String, nullable=False, index=True) + last_name = Column(String, nullable=False, index=True) roosters = relationship("Rooster") def get_full_name(self) -> str: @@ -66,7 +66,7 @@ class Rooster(Base, BaseMixin): class Vendor(Base, BaseMixin): __tablename__ = "vendor" - name = Column(String(255), nullable=False, unique=True, index=True) + name = Column(String, nullable=False, unique=True, index=True) card_sets = relationship("CardSet") cards = relationship("Card") @@ -76,7 +76,7 @@ class CardSet(Base, BaseMixin): __table_args__ = ( UniqueConstraint("name", "vendor_id"), ) - name = Column(String(255), index=True) + name = Column(String, index=True) parallel_set = Column(Boolean) insert_set = Column(Boolean) vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True) diff --git a/kontor-api/src/db/repository/__init__.py b/kontor-api/src/db/repository/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kontor-api/src/db/repository/comic.py b/kontor-api/src/db/repository/comic.py new file mode 100644 index 0000000..3388bb4 --- /dev/null +++ b/kontor-api/src/db/repository/comic.py @@ -0,0 +1,27 @@ +from typing import List, Type + +from sqlalchemy.orm import Session + +from src.db.models.comic import Artist, Comic +from src.schema.comics.artist import ArtistDetailResponse + + +def get_artist_details(artist: Artist) -> ArtistDetailResponse: + works = {} + for work in artist.comic_works: + work_type = work.work_type.name + comic_title = work.comic.title + if work_type in works: + works[work_type].append(comic_title) + else: + works[work_type] = [comic_title] + response = ArtistDetailResponse( + id=artist.id, + name=artist.name, + works=works + ) + return response + +def list_comics(db: Session) -> List[Type[Comic]]: + comics = db.query(Comic).all() + return comics diff --git a/kontor-api/src/db/session.py b/kontor-api/src/db/session.py index 713deb6..38b40af 100644 --- a/kontor-api/src/db/session.py +++ b/kontor-api/src/db/session.py @@ -1,7 +1,7 @@ -from typing import Generator, Annotated +from typing import Generator from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker, Session +from sqlalchemy.orm import sessionmaker from src.core.config import settings diff --git a/kontor-api/src/main.py b/kontor-api/src/main.py index 749d3b4..759c758 100644 --- a/kontor-api/src/main.py +++ b/kontor-api/src/main.py @@ -1,3 +1,5 @@ +import logging + from fastapi import FastAPI from fastapi.staticfiles import StaticFiles @@ -7,6 +9,10 @@ from src.webapps.base import api_router as web_app_router from src.core.config import settings from src.db.models.base import Base +logging.basicConfig(level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + handlers=[logging.StreamHandler()]) # Logs to console + def include_router(app: FastAPI): app.include_router(api_router) app.include_router(web_app_router) @@ -18,6 +24,7 @@ def create_tables(): Base.metadata.create_all(bind=engine) def start_application(): + logging.info(f"using database: {settings.DATABASE_URL}") app = FastAPI(title=settings.PROJECT_NAME, version=settings.PROJECT_VERSION) include_router(app) configure_static(app) @@ -26,4 +33,3 @@ def start_application(): kontor = start_application() - diff --git a/kontor-api/src/schema/comics/artist.py b/kontor-api/src/schema/comics/artist.py index 1b28812..925fa56 100644 --- a/kontor-api/src/schema/comics/artist.py +++ b/kontor-api/src/schema/comics/artist.py @@ -7,30 +7,14 @@ from src.db.models.comic import Artist class ArtistCreation(BaseModel): + id: str name: str class ArtistResponse(BaseModel): - id: UUID + id: str name: str class ArtistDetailResponse(BaseModel): - id: UUID + id: str name: str works: Dict[str, List[str]] - -def get_artist_details(artist: Artist) -> ArtistDetailResponse: - works = {} - for work in artist.comic_works: - work_type = work.work_type.name - comic_title = work.comic.title - if work_type in works: - works[work_type].append(comic_title) - else: - works[work_type] = [comic_title] - response = ArtistDetailResponse( - id=artist.id, - name=artist.name, - works=works - ) - return response - diff --git a/kontor-api/src/schema/comics/comic.py b/kontor-api/src/schema/comics/comic.py index 1c7f548..884e122 100644 --- a/kontor-api/src/schema/comics/comic.py +++ b/kontor-api/src/schema/comics/comic.py @@ -7,12 +7,12 @@ from src.db.models.comic import Comic class ComicResponse(BaseModel): - id: UUID + id: str title: str completed: bool class ComicDetailsResponse(BaseModel): - id: UUID + id: str created: str title: str completed : bool diff --git a/kontor-api/src/webapps/comic/route_comics.py b/kontor-api/src/webapps/comic/route_comics.py index 565bd26..eac1600 100644 --- a/kontor-api/src/webapps/comic/route_comics.py +++ b/kontor-api/src/webapps/comic/route_comics.py @@ -1,10 +1,8 @@ -from uuid import UUID - from fastapi import APIRouter, Request from fastapi.templating import Jinja2Templates - from src.apis.utils import SessionDep from src.db.models.comic import Comic, Artist, Publisher +from typing import AnyStr templates = Jinja2Templates(directory="src/templates") router = APIRouter(include_in_schema=False, prefix="/comic") @@ -15,7 +13,7 @@ def get_comics(db: SessionDep, request: Request, msg: str = None): return templates.TemplateResponse("comic/comics.html", {"request": request, "msg": msg, "comics": comics}) @router.get("/comics/{comic_id}") -def comic_details(comic_id: UUID, request: Request, db: SessionDep): +def comic_details(comic_id: AnyStr, request: Request, db: SessionDep): comic = db.get(Comic, comic_id) return templates.TemplateResponse("comic/comic_detail.html", {"request": request, "comic":comic}) @@ -25,8 +23,8 @@ def get_artists(db: SessionDep, request: Request, msg: str = None): return templates.TemplateResponse("comic/artists.html", {"request": request, "msg": msg, "artists": artists}) @router.get("/artists/{artist_id}") -def artist_detail(artist_id: UUID, request: Request, db: SessionDep): - artist = db.get(Artist, artist_id) +def artist_detail(artist_id: AnyStr, request: Request, db: SessionDep): + artist = db.get(Artist, str(artist_id)) return templates.TemplateResponse("comic/artist_detail.html", {"request": request, "artist": artist}) @router.get("/publishers") @@ -35,7 +33,7 @@ def get_publishers(db: SessionDep, request: Request, msg: str = None): return templates.TemplateResponse("comic/publishers.html", {"request": request, "publishers": publishers}) @router.get("/publishers/{publisher_id}") -def publisher_details(publisher_id: UUID, request: Request, db: SessionDep, msg: str = None): +def publisher_details(publisher_id: AnyStr, request: Request, db: SessionDep, msg: str = None): publisher = db.get(Publisher, publisher_id) if publisher is None: msg = "Could not find Publisher" diff --git a/kontor-scripts/json_to_postgres.py b/kontor-scripts/json_to_postgres.py index d70402e..1a277c6 100644 --- a/kontor-scripts/json_to_postgres.py +++ b/kontor-scripts/json_to_postgres.py @@ -3,6 +3,8 @@ copy data from JSON to Postgres """ from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter from pathlib import Path +from typing import Dict, List + from config import get_logger, get_database_cursors import json import psycopg2 @@ -29,7 +31,10 @@ def copy_data(postgres_conn, data_file: Path, log): # result[table] = import_table(table, json_load[table]) truncate_statement = 'TRUNCATE {} CASCADE'.format(table) #log.info(f"truncate: {truncate_statement}") - postgres_cursor.execute(truncate_statement) + try: + postgres_cursor.execute(truncate_statement) + except: + log.info(f"statement: {insert_statement} FAILED") items = json_load[table] for item in items: #log.info(f"item: {item}") @@ -39,21 +44,110 @@ def copy_data(postgres_conn, data_file: Path, log): columns.append(key) values.append(value) row = tuple(values) - log.info(f"values: {row}") + #log.info(f"values: {row}") insert_statement = 'INSERT INTO {}({}) VALUES({})'.format(table, ', '.join(columns), ', '.join(['%s']*len(columns))) #log.info(f"statement: {insert_statement}") - postgres_cursor.execute(SQL(insert_statement), row) try: + postgres_cursor.execute(SQL(insert_statement), row) postgres_conn.commit() - except psycopg2.Error as error: - log.info('insert failed with %s', error) + except: + log.info(f'insert failed with {insert_statement}') postgres_cursor.execute("SET session_replication_role='origin'") + +def load_json(data_file, log) -> dict: + import_file = Path(data_file) + if not import_file.exists(): + log.info(f"File {data_file} does not exist. Do nothing.") + return + log.info("read json file") + with open(data_file, 'r') as json_file: + json_load = json.load(json_file) + return json_load + + +def insert_data(postgres_conn, data: dict, log): + postgres_cursor = postgres_conn.cursor() + log.info("insert data") + table_list = [] + #table_list = ['worktype', 'artist', 'publisher', 'volume', 'comic', 'issue', 'story_arc', 'trade_paperback', 'comic_work'] + #table_list.extend(['sport', 'team', 'field_position', 'vendor', 'player', 'rooster', 'card_set', 'card']) + #table_list.extend(['card']) + #table_list.extend(['media_file', 'media_video', 'media_actor', 'media_actor_file', 'media_article']) + #table_list.extend(['media_actor_file']) + #table_list.extend(['profile', 'permission', 'token', 'assignment']) + #table_list.extend(['mail', 'mail_account', 'module_data', 'meta_data_table', 'meta_data_column']) + table_list.extend(['meta_data_column']) + #table_list.extend(['book', 'author', 'article', 'bookshelf_publisher', 'book_author', 'article_author']) + #if len(table_list) != 37: + # log.info(f"number of tables incorrect: {len(table_list)}") + # return + for table in table_list: + log.info(f"{table}: {len(data[table])}") + truncate_statement = 'DELETE FROM {}'.format(table) + log.info(f"truncate: {truncate_statement}") + try: + postgres_cursor.execute(truncate_statement) + postgres_conn.commit() + except: + log.info(f"statement: {truncate_statement} FAILED") + items = data[table] + for item in items: + # log.info(f"item: {item}") + values = [] + columns = [] + for (key, value) in item.items(): + columns.append(key) + values.append(value) + row = tuple(values) + # log.info(f"values: {row}") + insert_statement = 'INSERT INTO {}({}) VALUES({})'.format(table, ', '.join(columns), + ', '.join(['%s'] * len(columns))) + # log.info(f"statement: {insert_statement}") + try: + postgres_cursor.execute(SQL(insert_statement), row) + postgres_conn.commit() + except: + log.info(f'insert failed with {insert_statement}') + + +def parse_table_order(data: dict, log): + log.info("parse_table_order") + table_refs: Dict[str, List[str]] = {} + for table in data: + log.info(f"{table}: {len(data[table])}") + items = data[table] + table_refs[table] = [] + if len(items) == 0: + continue + item = items[0] + for key, _ in item.items(): + if key.endswith('_id'): + ref = key[0:-3] + log.info(f"table {table} has reference to {ref}") + if table in table_refs: + table_refs[table].append(ref) + else: + table_refs[table] = [ref] + log.info(f"parsed refs: {table_refs}") + table_order = [] + for table in table_refs: + if len(table_refs[table]) == 0: + log.info(f"insert {table} at beginning") + table_order.insert(0, table) + else: + log.info(f"insert {table} at end") + table_order.append(table) + log.info(f"table_list: {len(table_order)}: {table_order}") + if __name__ == '__main__': logger = get_logger(args.verbose, args.config) logger.info('kontor.json_to_postgres started') _, _, p_conn = get_database_cursors(logger, args.config) - copy_data(p_conn, args.file, logger) + data = load_json(args.file, logger) + #parse_table_order(data, logger) + insert_data(p_conn, data, logger) + #copy_data(p_conn, args.file, logger) p_conn.close() logger.info('kontor.json_to_postgres finished') diff --git a/kontor-scripts/schema/admin.py b/kontor-scripts/schema/admin.py index a0c9f68..583b772 100644 --- a/kontor-scripts/schema/admin.py +++ b/kontor-scripts/schema/admin.py @@ -40,7 +40,7 @@ class Token(Base, BaseMixin): class Permission(Base, BaseMixin): __tablename__ = "permission" - name = Column(String(255), nullable=False) + name = Column(String, nullable=False) assignments = relationship("Assignment") @@ -54,17 +54,17 @@ class Assignment(Base, BaseMixin): class ModuleData(Base, BaseMixin): __tablename__ = "module_data" - module_name = Column(String(255), nullable=False) + module_name = Column(String, nullable=False) import_data = Column(Boolean) class MailAccount(Base, BaseMixin): __tablename__ = "mail_account" - host = Column(String(255)) + host = Column(String) port = Column(Integer) - protocol = Column(String(255)) - user_name = Column(String(255)) - password = Column(String(255)) + protocol = Column(String) + user_name = Column(String) + password = Column(String) start_tls = Column(Boolean) diff --git a/kontor-scripts/schema/base.py b/kontor-scripts/schema/base.py index 5ef8183..84d00ef 100644 --- a/kontor-scripts/schema/base.py +++ b/kontor-scripts/schema/base.py @@ -10,8 +10,8 @@ class Base(DeclarativeBase): class BaseMixin: - id = Column(String(255), primary_key=True, default=uuid.uuid4()) - # id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4()) + #id = Column(String, primary_key=True, default=uuid.uuid4) + id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4) # created_date = Column(DateTime) created_date: Mapped[datetime] = mapped_column(default=func.now()) # last_modified_date = Column(DateTime) @@ -21,10 +21,10 @@ class BaseMixin: class BaseVideoMixin: - cloud_link = Column(String(255)) - file_name = Column(String(255)) - path = Column(String(255)) + cloud_link = Column(String) + file_name = Column(String) + path = Column(String) review = Column(Boolean) - title = Column(String(255)) - url = Column(String(255), unique=True) + title = Column(String) + url = Column(String, unique=True) should_download = Column(Boolean) diff --git a/kontor-scripts/schema/bookshelf.py b/kontor-scripts/schema/bookshelf.py index 91e0ae4..2830ee2 100644 --- a/kontor-scripts/schema/bookshelf.py +++ b/kontor-scripts/schema/bookshelf.py @@ -6,28 +6,28 @@ from .base import Base, BaseMixin class Article(Base, BaseMixin): __tablename__ = 'article' - title = Column(String(length=255), unique=True) + title = Column(String, unique=True) article_authors = relationship("ArticleAuthor") class Author(Base, BaseMixin): __tablename__ = 'author' - first_name = Column(String(255)) - last_name = Column(String(255)) + first_name = Column(String) + last_name = Column(String) article_authors = relationship("ArticleAuthor") book_authors = relationship("BookAuthor") class BookshelfPublisher(Base, BaseMixin): __tablename__ = 'bookshelf_publisher' - name = Column(String(length=255), unique=True) + name = Column(String, unique=True) books = relationship("Book") class Book(Base, BaseMixin): __tablename__ = 'book' - isbn = Column(String(255), unique=True) - title = Column(String(255)) + isbn = Column(String, unique=True) + title = Column(String) year = Column(Integer, nullable=False) publisher_id = Column(String, ForeignKey('bookshelf_publisher.id'), nullable=False) publisher = relationship('BookshelfPublisher', back_populates="books") diff --git a/kontor-scripts/schema/comic.py b/kontor-scripts/schema/comic.py index 45cb8c3..9108605 100644 --- a/kontor-scripts/schema/comic.py +++ b/kontor-scripts/schema/comic.py @@ -6,7 +6,7 @@ from .base import Base, BaseMixin class Publisher(Base, BaseMixin): __tablename__ = "publisher" - name = Column(String(length=255), unique=True) + name = Column(String, unique=True) comics = relationship("Comic") def __repr__(self): @@ -18,7 +18,7 @@ class Publisher(Base, BaseMixin): class Comic(Base, BaseMixin): __tablename__ = 'comic' - title = Column(String(length=255), unique=True) + title = Column(String, unique=True) publisher_id = Column(String, ForeignKey('publisher.id'), nullable=False) publisher = relationship("Publisher", back_populates="comics") current_order = Column(Boolean) @@ -38,7 +38,7 @@ class Comic(Base, BaseMixin): class Volume(Base, BaseMixin): __tablename__ = "volume" - name = Column(String(length=255), nullable=False) + name = Column(String, nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic = relationship("Comic", back_populates="volumes") issues = relationship("Issue") @@ -46,7 +46,7 @@ class Volume(Base, BaseMixin): class TradePaperback(Base, BaseMixin): __tablename__ = "trade_paperback" - name = Column(String(length=255), nullable=False) + name = Column(String, nullable=False) issue_start = Column(Integer) issue_end = Column(Integer) comic_id = Column(String, ForeignKey("comic.id"), nullable=False) @@ -55,14 +55,14 @@ class TradePaperback(Base, BaseMixin): class StoryArc(Base, BaseMixin): __tablename__ = "story_arc" - name = Column(String(length=255), nullable=False) + name = Column(String, nullable=False) comic_id = Column(String, ForeignKey("comic.id"), nullable=False) comic = relationship("Comic", back_populates="story_arcs") class Issue(Base, BaseMixin): __tablename__ = "issue" - issue_number = Column(String(255)) + issue_number = Column(String) in_stock = Column(Boolean) is_read = Column(Boolean) comic_id = Column(String, ForeignKey("comic.id"), nullable=False) @@ -73,13 +73,13 @@ class Issue(Base, BaseMixin): class Artist(Base, BaseMixin): __tablename__ = "artist" - name = Column(String(length=255), nullable=False) + name = Column(String, nullable=False) comic_works = relationship("ComicWork") class WorkType(Base, BaseMixin): __tablename__ = "worktype" - name = Column(String(length=255), nullable=False, unique=True) + name = Column(String, nullable=False, unique=True) comic_works = relationship("ComicWork") def __repr__(self): diff --git a/kontor-scripts/schema/media.py b/kontor-scripts/schema/media.py index 5dcc5c6..979e8e1 100644 --- a/kontor-scripts/schema/media.py +++ b/kontor-scripts/schema/media.py @@ -69,31 +69,31 @@ class MediaFile(Base, BaseMixin, BaseVideoMixin): class MediaActor(Base, BaseMixin): __tablename__ = 'media_actor' - name = Column(String(255)) + name = Column(String) media_actor_files = relationship("MediaActorFile") class MediaActorFile(Base, BaseMixin): __tablename__ = 'media_actor_file' - media_actor_id = Column(String(255), ForeignKey("media_actor.id"), nullable=False) + media_actor_id = Column(String, ForeignKey("media_actor.id"), nullable=False) media_actor = relationship("MediaActor", back_populates="media_actor_files") - media_file_id = Column(String(255), ForeignKey("media_file.id"), nullable=True) + media_file_id = Column(String, ForeignKey("media_file.id"), nullable=True) media_file = relationship("MediaFile", back_populates="media_actor_files") class MediaArticle(Base, BaseMixin): __tablename__ = 'media_article' review = Column(Boolean) - title = Column(String(255)) - url = Column(String(255), unique=True) + title = Column(String) + url = Column(String, unique=True) class MediaVideo(Base, BaseMixin): __tablename__ = 'media_video' - cloud_link = Column(String(255)) - file_name = Column(String(255)) - path = Column(String(255)) + cloud_link = Column(String) + file_name = Column(String) + path = Column(String) review = Column(Boolean) - title = Column(String(255)) - url = Column(String(255), unique=True) + title = Column(String) + url = Column(String, unique=True) should_download = Column(Boolean) diff --git a/kontor-scripts/schema/metadata.py b/kontor-scripts/schema/metadata.py index 9ac5aa4..42dd88b 100644 --- a/kontor-scripts/schema/metadata.py +++ b/kontor-scripts/schema/metadata.py @@ -6,7 +6,7 @@ from .base import Base, BaseMixin class MetaDataTable(Base, BaseMixin): __tablename__ = 'meta_data_table' - table_name = Column(String(255), unique=True) + table_name = Column(String, unique=True) table_columns = relationship("MetaDataColumn") def __repr__(self): @@ -18,15 +18,15 @@ class MetaDataTable(Base, BaseMixin): class MetaDataColumn(Base, BaseMixin): __tablename__ = 'meta_data_column' - column_name = Column(String(255), nullable=False) - column_sync_name = Column(String(255)) - column_type = Column(String(255)) - column_modifier = Column(String(255), nullable=True) + column_name = Column(String, nullable=False) + column_sync_name = Column(String) + column_type = Column(String) + column_modifier = Column(String, nullable=True) column_order = Column(Integer) table_id = Column(String, ForeignKey('meta_data_table.id')) table = relationship("MetaDataTable", back_populates="table_columns") - column_label = Column(String(255)) - filter_label = Column(String(255)) + column_label = Column(String) + filter_label = Column(String) is_shown = Column(Boolean) show_filter = Column(Boolean) ref_column = Column(String, nullable=True) diff --git a/kontor-scripts/schema/tysc.py b/kontor-scripts/schema/tysc.py index 5ab4baa..1bc500e 100644 --- a/kontor-scripts/schema/tysc.py +++ b/kontor-scripts/schema/tysc.py @@ -9,15 +9,15 @@ class Sport(Base, BaseMixin): __table_args__ = ( UniqueConstraint("name"), ) - name = Column(String(255), nullable=False, index=True, unique=True) + name = Column(String, nullable=False, index=True, unique=True) teams = relationship("Team") positions = relationship("FieldPosition") class Team(Base, BaseMixin): __tablename__ = "team" - name = Column(String(255), nullable=False, index=True, unique=True) - short_name = Column(String(255), nullable=False, ) + name = Column(String, nullable=False, index=True, unique=True) + short_name = Column(String, nullable=False, ) sport_id = Column(String, ForeignKey("sport.id"), nullable=False) sport = relationship("Sport", back_populates="teams") roosters = relationship("Rooster") @@ -29,8 +29,8 @@ class FieldPosition(Base, BaseMixin): UniqueConstraint("name", "sport_id"), UniqueConstraint("short_name", "sport_id"), ) - name = Column(String(255), nullable=False, index=True) - short_name = Column(String(255), nullable=False) + name = Column(String, nullable=False, index=True) + short_name = Column(String, nullable=False) sport_id = Column(String, ForeignKey("sport.id"), nullable=False, index=True) sport = relationship("Sport", back_populates="positions") roosters = relationship("Rooster") @@ -41,8 +41,8 @@ class Player(Base, BaseMixin): __table_args__ = ( UniqueConstraint("first_name", "last_name"), ) - first_name = Column(String(255), nullable=False, index=True) - last_name = Column(String(255), nullable=False, index=True) + first_name = Column(String, nullable=False, index=True) + last_name = Column(String, nullable=False, index=True) roosters = relationship("Rooster") def get_full_name(self) -> str: @@ -66,7 +66,7 @@ class Rooster(Base, BaseMixin): class Vendor(Base, BaseMixin): __tablename__ = "vendor" - name = Column(String(255), nullable=False, unique=True, index=True) + name = Column(String, nullable=False, unique=True, index=True) card_sets = relationship("CardSet") cards = relationship("Card") @@ -76,7 +76,7 @@ class CardSet(Base, BaseMixin): __table_args__ = ( UniqueConstraint("name", "vendor_id"), ) - name = Column(String(255), index=True) + name = Column(String, index=True) parallel_set = Column(Boolean) insert_set = Column(Boolean) vendor_id = Column(String, ForeignKey("vendor.id"), nullable=False, index=True) diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/MetaDataColumn.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/MetaDataColumn.java index cb4baea..fcc2195 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/MetaDataColumn.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/data/MetaDataColumn.java @@ -66,4 +66,9 @@ public class MetaDataColumn extends AbstractEntity { } return "no changes for " + this.getId() + "\n"; } + + @Override + public String toString() { + return "MetaDataColumn{id=" + getId() + ", columnName=" + columnName + ", table=" + table.getTableName() +'}'; + } } diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/MetaDataColumnRepository.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/MetaDataColumnRepository.java index c0259bf..7f0af9a 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/MetaDataColumnRepository.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/repository/MetaDataColumnRepository.java @@ -12,6 +12,8 @@ public interface MetaDataColumnRepository extends JpaRepository findByTable(MetaDataTable table); + List findByTableAndColumnName(MetaDataTable table, String column_name); + @Query("select m from MetaDataColumn m " + "where lower(m.columnName) like lower(concat('%', :searchTerm, '%')) or lower(m.columnLabel) like lower(concat('%', :searchTerm, '%'))") List search(@Param("searchTerm") String searchTerm); diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/MetaDataService.java b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/MetaDataService.java index 6c45feb..89da070 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/MetaDataService.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/admin/services/MetaDataService.java @@ -67,61 +67,73 @@ public class MetaDataService { this.getColumn(table, columnName, columnSyncName, columnType, columnModifier, columnOrder, isShown, columnLabel, showFilter, filterLabel, null); } + public void checkColumnValues(MetaDataTable table, MetaDataColumn column, String columnName, String columnSyncName, String columnType, String columnModifier, Integer columnOrder, Boolean isShown, String columnLabel, Boolean showFilter, String filterLabel, String refColumn) { + log.debug("Column {} with name {} of table {} found, check Values", columnOrder, columnName, table.getTableName()); + if (!column.getColumnName().equals(columnName)) { + log.debug("columnName has to be changed to {}", columnName); + column.setColumnName(columnName); + } + if (!column.getColumnSyncName().equals(columnSyncName)) { + log.debug("columnSyncName has to be changed to {}", columnSyncName); + column.setColumnSyncName(columnSyncName); + } + if (!column.getColumnType().equals(columnType)) { + log.debug("columnType has to be changed to {}", columnType); + column.setColumnType(columnType); + } + if (columnModifier != null && !columnModifier.equals(column.getColumnModifier())) { + log.debug("columnModifier has to be changed to {}", columnModifier); + column.setColumnModifier(columnModifier); + } + if (isShown != null && !isShown.equals(column.getIsShown())) { + log.debug("isShown has to be change to {}}", isShown); + column.setIsShown(isShown); + } + if (columnLabel != null && !columnLabel.equals(column.getColumnLabel())) { + log.debug("columnLabel has to be change to {}}", columnLabel); + column.setColumnLabel(columnLabel); + } + if (showFilter != null &&!showFilter.equals(column.getShowFilter())) { + log.debug("showFilter has to be change to {}}", showFilter); + column.setShowFilter(showFilter); + } + if (filterLabel != null && !filterLabel.equals(column.getFilterLabel())) { + log.debug("filterLabel has to be change to {}}", filterLabel); + column.setFilterLabel(filterLabel); + } + if (refColumn != null && !refColumn.equals(column.getRefColumn())) { + log.debug("refColumn has to be change to {}}", filterLabel); + column.setRefColumn(refColumn); + } + saveMetaDataColumn(column); + } + public void getColumn(MetaDataTable table, String columnName, String columnSyncName, String columnType, String columnModifier, Integer columnOrder, Boolean isShown, String columnLabel, Boolean showFilter, String filterLabel, String refColumn) { - if (table.getTableColumns().stream().anyMatch(column -> column.getColumnName().equals(columnName))) { - log.debug("Column {} with name {} of table {} found, check Values", columnOrder, columnName, table.getTableName()); - MetaDataColumn column = table.getTableColumns().get(columnOrder.intValue()-1); - if (!column.getColumnName().equals(columnName)) { - log.debug("columnName has to be changed to {}", columnName); - column.setColumnName(columnName); - } - if (!column.getColumnSyncName().equals(columnSyncName)) { - log.debug("columnSyncName has to be changed to {}", columnSyncName); - column.setColumnSyncName(columnSyncName); - } - if (!column.getColumnType().equals(columnType)) { - log.debug("columnType has to be changed to {}", columnType); - column.setColumnType(columnType); - } - if (columnModifier != null && !columnModifier.equals(column.getColumnModifier())) { - log.debug("columnModifier has to be changed to {}", columnModifier); - column.setColumnModifier(columnModifier); - } - if (isShown != null && !isShown.equals(column.getIsShown())) { - log.debug("isShown has to be change to {}}", isShown); - column.setIsShown(isShown); - } - if (columnLabel != null && !columnLabel.equals(column.getColumnLabel())) { - log.debug("columnLabel has to be change to {}}", columnLabel); - column.setColumnLabel(columnLabel); - } - if (showFilter != null &&!showFilter.equals(column.getShowFilter())) { - log.debug("showFilter has to be change to {}}", showFilter); - column.setShowFilter(showFilter); - } - if (filterLabel != null && !filterLabel.equals(column.getFilterLabel())) { - log.debug("filterLabel has to be change to {}}", filterLabel); - column.setFilterLabel(filterLabel); - } - if (refColumn != null && !refColumn.equals(column.getRefColumn())) { - log.debug("refColumn has to be change to {}}", filterLabel); - column.setRefColumn(refColumn); - } - metaDataColumnRepository.save(column); + log.info("check if column {} of table {} exists", columnName, table.getTableName()); + boolean columnNameExists = table.getTableColumns().stream().anyMatch(column -> column.getColumnName().equals(columnName)); + boolean columnOrderExists = table.getTableColumns().get(columnOrder-1) != null; + List metaDataColumns = metaDataColumnRepository.findByTableAndColumnName(table, columnName); + log.debug("column found: name: {}, order: {}: table.columns: {}", columnNameExists, columnOrderExists, metaDataColumns); + if (columnOrderExists) { + MetaDataColumn column = table.getTableColumns().get(columnOrder-1); + checkColumnValues(table, column, columnName, columnSyncName, columnType, columnModifier, columnOrder, isShown, columnLabel, showFilter, filterLabel, refColumn); } else { log.info("Column {} of table {} not found, will create it", columnName, table.getTableName()); - MetaDataColumn column = new MetaDataColumn(); - column.setTable(table); - column.setColumnName(columnName); - column.setColumnSyncName(columnSyncName); - column.setColumnType(columnType); - column.setColumnModifier(columnModifier); - column.setColumnOrder(columnOrder); - column.setIsShown(Boolean.FALSE); - metaDataColumnRepository.save(column); + //addColumn(table,columnName,columnSyncName,columnType,columnModifier,columnOrder,isShown); } } + private void addColumn(MetaDataTable table, String columnName, String columnSyncName, String columnType, String columnModifier, Integer columnOrder, Boolean isShown) { + MetaDataColumn column = new MetaDataColumn(); + column.setTable(table); + column.setColumnName(columnName); + column.setColumnSyncName(columnSyncName); + column.setColumnType(columnType); + column.setColumnModifier(columnModifier); + column.setColumnOrder(columnOrder); + column.setIsShown(isShown); + saveMetaDataColumn(column); + } public List findAllMetaDataColumns(String stringFilter) { if (stringFilter == null || stringFilter.isEmpty()) { diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueView.java index f77bf99..4a8e15e 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueView.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/comics/views/IssueView.java @@ -118,7 +118,7 @@ public class IssueView extends VerticalLayout { menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); columnToggleContextMenu.addColumnToggleItem(idColumn); - columnToggleContextMenu.addColumnToggleItem(createdColumn); + columnToggleContextMenu.addColumnToggleItem(createdColumn); columnToggleContextMenu.addColumnToggleItem(modifiedColumn); columnToggleContextMenu.addColumnToggleItem(versionColumn); columnToggleContextMenu.addColumnToggleItem(titleColumn); diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/CardSet.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/CardSet.java index c72188c..8bd700d 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/CardSet.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/CardSet.java @@ -38,4 +38,8 @@ public class CardSet extends AbstractEntity { private boolean parallelSet = false; private boolean insertSet = false; + + public String getVendorName() { + return vendor.getName(); + } } diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Vendor.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Vendor.java index f405565..0bd530f 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Vendor.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/data/Vendor.java @@ -21,7 +21,6 @@ import lombok.ToString; */ @Getter @Setter -@ToString @EqualsAndHashCode(callSuper=false) @Entity @Table(indexes = {@Index(columnList = "name")}, @@ -35,4 +34,9 @@ public class Vendor extends AbstractEntity { @OneToMany(fetch = FetchType.EAGER, mappedBy = "vendor") @Nullable private List cardSets; + + @Override + public String toString() { + return "Vendor{id=" + this.getId() + ", name=" + name + '}'; + } } diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardSetView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardSetView.java index 1a49896..071e66d 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardSetView.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardSetView.java @@ -1,9 +1,12 @@ package de.thpeetz.kontor.tysc.views; +import com.vaadin.flow.component.button.*; +import de.thpeetz.kontor.comics.data.*; +import de.thpeetz.kontor.common.views.*; +import lombok.*; import org.springframework.context.annotation.Scope; import com.vaadin.flow.component.Component; -import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; @@ -13,12 +16,13 @@ import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import com.vaadin.flow.spring.annotation.SpringComponent; -import de.thpeetz.kontor.common.views.MainLayout; import de.thpeetz.kontor.tysc.TyscConstants; import de.thpeetz.kontor.tysc.data.CardSet; import de.thpeetz.kontor.tysc.services.CardService; import jakarta.annotation.security.PermitAll; +import java.util.*; + @SpringComponent @Scope("prototype") @PermitAll @@ -26,8 +30,26 @@ import jakarta.annotation.security.PermitAll; @PageTitle("CardSet | Tysc | Kontor") public class CardSetView extends VerticalLayout { - Grid grid = new Grid<>(CardSet.class); + @Getter + Grid grid = new Grid<>(CardSet.class, false); + Grid.Column idColumn = grid.addColumn(CardSet::getId) + .setHeader("ID").setResizable(true).setSortable(true); + Grid.Column createdColumn = grid.addColumn(CardSet::getCreatedDate) + .setHeader("Erstellt").setResizable(true).setSortable(true); + Grid.Column modifiedColumn = grid.addColumn(CardSet::getLastModifiedDate) + .setHeader("GeƤndert").setResizable(true).setSortable(true); + Grid.Column versionColumn = grid.addColumn(CardSet::getVersion) + .setHeader("Version").setResizable(true).setSortable(true); + Grid.Column nameColumn = grid.addColumn(CardSet::getName) + .setHeader("Comic").setResizable(true).setSortable(true); + Grid.Column vendorNameColumn = grid.addColumn(CardSet::getVendorName) + .setHeader("Hersteller").setResizable(true).setSortable(true); + Grid.Column parallelSetColumn = grid.addComponentColumn(parallelSet -> StatusIcon.create(parallelSet.isParallelSet())) + .setHeader("Parallelset?").setWidth("6rem").setSortable(true); + Grid.Column insertSetColumn = grid.addComponentColumn(insertSet -> StatusIcon.create(insertSet.isInsertSet())) + .setHeader("Parallelset?").setWidth("6rem").setSortable(true); TextField filterText = new TextField(); + @Getter CardSetForm form; CardService service; @@ -42,22 +64,18 @@ public class CardSetView extends VerticalLayout { updateList(); } - public Grid getGrid() { - return grid; - } - private void configureGrid() { grid.addClassName("cardSet-grid"); grid.setSizeFull(); - grid.setColumns("name", "vendor.name", "parallelSet", "insertSet"); + //grid.setColumns("name", "vendor.name", "parallelSet", "insertSet"); grid.getColumns().forEach(col -> col.setAutoWidth(true)); + idColumn.setVisible(false); + createdColumn.setVisible(false); + modifiedColumn.setVisible(false); + versionColumn.setVisible(false); grid.asSingleSelect().addValueChangeListener(event -> editCardSet(event.getValue())); } - public CardSetForm getForm() { - return form; - } - private void configureForm() { form = new CardSetForm(); form.setWidth("25em"); @@ -67,18 +85,6 @@ public class CardSetView extends VerticalLayout { form.addCloseListener(e -> closeEditor()); } - private void saveCardSet(CardSetForm.SaveEvent event) { - service.saveCardSet(event.getCardSet()); - updateList(); - closeEditor(); - } - - private void deleteCardSet(CardSetForm.DeleteEvent event) { - service.deleteCardSet(event.getCardSet()); - updateList(); - closeEditor(); - } - private Component getContent() { HorizontalLayout content = new HorizontalLayout(grid, form); content.setFlexGrow(2, grid); @@ -97,11 +103,34 @@ public class CardSetView extends VerticalLayout { Button addCardSetButton = new Button("Add cardSet"); addCardSetButton.addClickListener(click -> addCardSet()); - HorizontalLayout toolbar = new HorizontalLayout(filterText, addCardSetButton); + Button menuButton = new Button("Show/Hide Columns"); + menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY); + ColumnToggleContextMenu columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton); + columnToggleContextMenu.addColumnToggleItem(idColumn); + columnToggleContextMenu.addColumnToggleItem(createdColumn); + columnToggleContextMenu.addColumnToggleItem(modifiedColumn); + columnToggleContextMenu.addColumnToggleItem(versionColumn); + columnToggleContextMenu.addColumnToggleItem(nameColumn); + columnToggleContextMenu.addColumnToggleItem(vendorNameColumn); + columnToggleContextMenu.addColumnToggleItem(parallelSetColumn); + columnToggleContextMenu.addColumnToggleItem(insertSetColumn); + HorizontalLayout toolbar = new HorizontalLayout(filterText, addCardSetButton, menuButton); toolbar.addClassName("toolbar"); return toolbar; } + private void saveCardSet(CardSetForm.SaveEvent event) { + service.saveCardSet(event.getCardSet()); + updateList(); + closeEditor(); + } + + private void deleteCardSet(CardSetForm.DeleteEvent event) { + service.deleteCardSet(event.getCardSet()); + updateList(); + closeEditor(); + } + public void editCardSet(CardSet cardSet) { if (cardSet == null) { closeEditor(); diff --git a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardView.java b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardView.java index f5251da..7fd530c 100644 --- a/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardView.java +++ b/kontor-spring/src/main/java/de/thpeetz/kontor/tysc/views/CardView.java @@ -51,7 +51,6 @@ public class CardView extends VerticalLayout { .setHeader("Inserts").setWidth("6rem").setSortable(true); Grid.Column parallelSetColumn = grid.addComponentColumn(card -> StatusIcon.create(card.getCardSet().isParallelSet())) .setHeader("Parallels").setWidth("6rem").setSortable(true); - Grid.Column playerColumn = grid.addColumn(Card::getPlayerName).setHeader("Spieler").setResizable(true).setSortable(true); TextField filterText = new TextField(); @Getter @@ -128,9 +127,10 @@ public class CardView extends VerticalLayout { columnToggleContextMenu.addColumnToggleItem(yearColumn); columnToggleContextMenu.addColumnToggleItem(vendorColumn); columnToggleContextMenu.addColumnToggleItem(cardSetColumn); + columnToggleContextMenu.addColumnToggleItem(insertSetColumn); + columnToggleContextMenu.addColumnToggleItem(parallelSetColumn); columnToggleContextMenu.addColumnToggleItem(playerColumn); HorizontalLayout toolbar = new HorizontalLayout(filterText, addCardButton, menuButton); - toolbar.addClassName("toolbar"); return toolbar; }