From 70c3807ddc08422224407e39812bcdb37bc20884 Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Tue, 17 Oct 2023 21:48:36 +0530 Subject: [PATCH] Allow adding other entities to collections (#401) * feat(backend): add table for entity to collection * feat(backend): generate entities for new models * refactor(backend): move common stuff out of dedicated modules * feat(backend): make fk names better * feat(backend): migration to drop useless tables * chore(backend): remove useless associations * fix(backend): remove useless table code * feat(backend): mostly migrate to new models * style(backend): remove useless model variants * fix(backend): correct usage of entity of collection * chore(graphql): regenrate types * chore(frontend): adapt to new gql schema * fix(backend): skip exercises which we don't have in db * feat(backend): allow adding other entities to collections * chore(frontend, graphql): adapt to new gql schema * feat(backend): allow removing any entity from collection * chore(frontend): adapt to new gql schema * refactor(backend): change name of query * chore(frontend): adapt to new gql schema * feat(backend): allow getting collections for any entity * feat(backend): return collections for people * refactor(graphql): extract common stuff to fragment * feat(backend): include collections for people * refactor(backend): rename model to better name * feat(backend): allow adding exercises to collections * feat(backend): allow adding/removing exercises to collections * refactor(backend): change name of mutations * chore(graphql): adapt to new gql schema * refactor(backend): extract fn to add entity to collection * feat(backend): allow custom exercises to collection * fix(backend): change name of field * feat(backend): update col_to_entity association * feat(backend): return entity lot for collection contents * chore(frontend): adapt to new schema * feat(frontend): open timer drawer when rest timer enabled * feat(backend): return all data types for collection contents * fix(backend): return year for people * fix(frontend): render correct metadata * refactor(frontend): extract component to add entity to collection * feat(frontend): allow adding people to collections * feat(backend): do not clean up people that have been added to collections * refactor(frontend): component to display collections * feat(frontend): display collections for people * feat(backend): extract fn to get collections for entities * chore(graphql): use fragments where possible * feat(backend): resolver to get user's metadata group details * feat(frontend): UI to add metadata group to collection * fix(frontend): do not display entire entity lot * Revert "fix(frontend): do not display entire entity lot" This reverts commit aa8118e0c8822d990461b03d46785bbdb7b7bf81. * feat(backend): return collections for exercises * feat(backend): return exercise collections data * fix(frontend): adapt to new gql schema * feat(frontend): allow adding exercise to collection * fix(frontend): do not display useless tabs * fix(frontend): adapt to new gql schema * fix(backend): change name of column * build(backend): bump version --- Cargo.lock | 2 +- apps/backend/Cargo.toml | 2 +- apps/backend/src/entities/collection.rs | 17 +- .../src/entities/collection_to_entity.rs | 117 ++++++ apps/backend/src/entities/exercise.rs | 8 + apps/backend/src/entities/metadata.rs | 21 +- apps/backend/src/entities/metadata_group.rs | 8 + .../src/entities/metadata_to_collection.rs | 69 --- apps/backend/src/entities/mod.rs | 2 +- apps/backend/src/entities/person.rs | 8 + apps/backend/src/entities/prelude.rs | 2 +- apps/backend/src/fitness/logic.rs | 13 +- apps/backend/src/fitness/resolver.rs | 55 ++- apps/backend/src/importer/mod.rs | 13 +- apps/backend/src/main.rs | 2 +- .../migrator/m20230507_create_collection.rs | 57 +-- .../m20231016_create_collection_to_entity.rs | 106 +++++ .../migrator/m20231016_drop_useless_tables.rs | 78 ++++ apps/backend/src/migrator/mod.rs | 4 + apps/backend/src/miscellaneous/resolver.rs | 393 ++++++++++-------- apps/backend/src/models.rs | 60 +-- apps/backend/src/routes.rs | 3 +- apps/backend/src/utils.rs | 92 +++- .../src/lib/components/MediaComponents.tsx | 216 +++++++++- apps/frontend/src/lib/constants.ts | 1 + .../fitness/exercises/current-workout.tsx | 12 +- .../src/pages/fitness/exercises/details.tsx | 89 +++- .../src/pages/fitness/exercises/list.tsx | 2 +- apps/frontend/src/pages/index.tsx | 21 +- .../src/pages/media/collections/index.tsx | 10 +- .../src/pages/media/collections/list.tsx | 9 +- .../frontend/src/pages/media/groups/index.tsx | 107 ++++- apps/frontend/src/pages/media/item/index.tsx | 151 +------ apps/frontend/src/pages/media/list.tsx | 9 +- .../frontend/src/pages/media/people/index.tsx | 34 +- docs/includes/export-schema.ts | 4 +- libs/generated/src/graphql/backend/gql.ts | 43 +- libs/generated/src/graphql/backend/graphql.ts | 137 +++--- .../mutations/AddEntityToCollection.gql | 3 + .../mutations/AddMediaToCollection.gql | 3 - .../mutations/RemoveEntityFromCollection.gql | 5 + .../mutations/RemoveMediaFromCollection.gql | 5 - .../backend/queries/CollectionContents.gql | 3 +- .../src/backend/queries/Collections.gql | 9 - .../backend/queries/UserCollectionsList.gql | 9 + .../backend/queries/UserCreatorDetails.gql | 24 +- .../backend/queries/UserExerciseDetails.gql | 3 + .../src/backend/queries/UserMediaDetails.gql | 27 +- .../queries/UserMetadataGroupDetails.gql | 7 + .../graphql/src/backend/queries/fragments.gql | 31 ++ 50 files changed, 1384 insertions(+), 722 deletions(-) create mode 100644 apps/backend/src/entities/collection_to_entity.rs delete mode 100644 apps/backend/src/entities/metadata_to_collection.rs create mode 100644 apps/backend/src/migrator/m20231016_create_collection_to_entity.rs create mode 100644 apps/backend/src/migrator/m20231016_drop_useless_tables.rs create mode 100644 libs/graphql/src/backend/mutations/AddEntityToCollection.gql delete mode 100644 libs/graphql/src/backend/mutations/AddMediaToCollection.gql create mode 100644 libs/graphql/src/backend/mutations/RemoveEntityFromCollection.gql delete mode 100644 libs/graphql/src/backend/mutations/RemoveMediaFromCollection.gql delete mode 100644 libs/graphql/src/backend/queries/Collections.gql create mode 100644 libs/graphql/src/backend/queries/UserCollectionsList.gql create mode 100644 libs/graphql/src/backend/queries/UserMetadataGroupDetails.gql diff --git a/Cargo.lock b/Cargo.lock index ca5c093f25..27b1ec35b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4628,7 +4628,7 @@ checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" [[package]] name = "ryot" -version = "2.23.2" +version = "2.24.0" dependencies = [ "anyhow", "apalis", diff --git a/apps/backend/Cargo.toml b/apps/backend/Cargo.toml index 8a2b9506f5..af558c0c4e 100644 --- a/apps/backend/Cargo.toml +++ b/apps/backend/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ryot" -version = "2.23.2" +version = "2.24.0" edition = "2021" repository = "https://github.com/IgnisDa/ryot" license = "GPL-V3" diff --git a/apps/backend/src/entities/collection.rs b/apps/backend/src/entities/collection.rs index a9be77eebc..6870be98e7 100644 --- a/apps/backend/src/entities/collection.rs +++ b/apps/backend/src/entities/collection.rs @@ -22,6 +22,8 @@ pub struct Model { #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { + #[sea_orm(has_many = "super::collection_to_entity::Entity")] + CollectionToEntity, #[sea_orm( belongs_to = "super::user::Entity", from = "Column::UserId", @@ -32,22 +34,15 @@ pub enum Relation { User, } -impl Related for Entity { +impl Related for Entity { fn to() -> RelationDef { - Relation::User.def() + Relation::CollectionToEntity.def() } } -impl Related for Entity { +impl Related for Entity { fn to() -> RelationDef { - super::metadata_to_collection::Relation::Metadata.def() - } - fn via() -> Option { - Some( - super::metadata_to_collection::Relation::Collection - .def() - .rev(), - ) + Relation::User.def() } } diff --git a/apps/backend/src/entities/collection_to_entity.rs b/apps/backend/src/entities/collection_to_entity.rs new file mode 100644 index 0000000000..93248ae80f --- /dev/null +++ b/apps/backend/src/entities/collection_to_entity.rs @@ -0,0 +1,117 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.3 + +use async_trait::async_trait; +use sea_orm::entity::prelude::*; +use serde::{Deserialize, Serialize}; + +use crate::utils::associate_user_with_metadata; + +use super::prelude::Collection; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] +#[sea_orm(table_name = "collection_to_entity")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub last_updated_on: DateTimeUtc, + pub collection_id: i32, + pub metadata_id: Option, + pub person_id: Option, + pub metadata_group_id: Option, + pub exercise_id: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::collection::Entity", + from = "Column::CollectionId", + to = "super::collection::Column::Id", + on_update = "Cascade", + on_delete = "Cascade" + )] + Collection, + #[sea_orm( + belongs_to = "super::metadata::Entity", + from = "Column::MetadataId", + to = "super::metadata::Column::Id", + on_update = "Cascade", + on_delete = "Cascade" + )] + Metadata, + #[sea_orm( + belongs_to = "super::metadata_group::Entity", + from = "Column::MetadataGroupId", + to = "super::metadata_group::Column::Id", + on_update = "Cascade", + on_delete = "Cascade" + )] + MetadataGroup, + #[sea_orm( + belongs_to = "super::person::Entity", + from = "Column::PersonId", + to = "super::person::Column::Id", + on_update = "Cascade", + on_delete = "Cascade" + )] + Person, + #[sea_orm( + belongs_to = "super::exercise::Entity", + from = "Column::ExerciseId", + to = "super::exercise::Column::Id", + on_update = "Cascade", + on_delete = "Cascade" + )] + Exercise, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Collection.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Metadata.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::MetadataGroup.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Person.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Exercise.def() + } +} + +#[async_trait] +impl ActiveModelBehavior for ActiveModel { + async fn after_save(model: Model, db: &C, insert: bool) -> Result + where + C: ConnectionTrait, + { + if let Some(metadata_id) = model.metadata_id { + if insert { + let collection = Collection::find_by_id(model.collection_id) + .one(db) + .await? + .unwrap(); + associate_user_with_metadata(&collection.user_id, &metadata_id, db) + .await + .ok(); + } + } + Ok(model) + } +} diff --git a/apps/backend/src/entities/exercise.rs b/apps/backend/src/entities/exercise.rs index 27e68071d6..2d82e3f794 100644 --- a/apps/backend/src/entities/exercise.rs +++ b/apps/backend/src/entities/exercise.rs @@ -90,10 +90,18 @@ impl ExerciseListItem { #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { + #[sea_orm(has_many = "super::collection_to_entity::Entity")] + CollectionToEntity, #[sea_orm(has_many = "super::user_to_exercise::Entity")] UserToExercise, } +impl Related for Entity { + fn to() -> RelationDef { + Relation::CollectionToEntity.def() + } +} + impl Related for Entity { fn to() -> RelationDef { Relation::UserToExercise.def() diff --git a/apps/backend/src/entities/metadata.rs b/apps/backend/src/entities/metadata.rs index 12ac9a53f6..1991688ead 100644 --- a/apps/backend/src/entities/metadata.rs +++ b/apps/backend/src/entities/metadata.rs @@ -40,8 +40,8 @@ pub struct Model { pub enum Relation { #[sea_orm(has_many = "super::calendar_event::Entity")] CalendarEvent, - #[sea_orm(has_many = "super::metadata_to_collection::Entity")] - MetadataToCollection, + #[sea_orm(has_many = "super::collection_to_entity::Entity")] + CollectionToEntity, #[sea_orm(has_many = "super::metadata_to_genre::Entity")] MetadataToGenre, #[sea_orm(has_many = "super::metadata_to_partial_metadata::Entity")] @@ -64,9 +64,9 @@ impl Related for Entity { } } -impl Related for Entity { +impl Related for Entity { fn to() -> RelationDef { - Relation::MetadataToCollection.def() + Relation::CollectionToEntity.def() } } @@ -106,19 +106,6 @@ impl Related for Entity { } } -impl Related for Entity { - fn to() -> RelationDef { - super::metadata_to_collection::Relation::Collection.def() - } - fn via() -> Option { - Some( - super::metadata_to_collection::Relation::Metadata - .def() - .rev(), - ) - } -} - impl Related for Entity { fn to() -> RelationDef { super::metadata_to_genre::Relation::Genre.def() diff --git a/apps/backend/src/entities/metadata_group.rs b/apps/backend/src/entities/metadata_group.rs index 81d6ab623b..2da50607bb 100644 --- a/apps/backend/src/entities/metadata_group.rs +++ b/apps/backend/src/entities/metadata_group.rs @@ -32,10 +32,18 @@ pub struct Model { #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { + #[sea_orm(has_many = "super::collection_to_entity::Entity")] + CollectionToEntity, #[sea_orm(has_many = "super::partial_metadata_to_metadata_group::Entity")] PartialMetadataToMetadataGroup, } +impl Related for Entity { + fn to() -> RelationDef { + Relation::CollectionToEntity.def() + } +} + impl Related for Entity { fn to() -> RelationDef { Relation::PartialMetadataToMetadataGroup.def() diff --git a/apps/backend/src/entities/metadata_to_collection.rs b/apps/backend/src/entities/metadata_to_collection.rs deleted file mode 100644 index 4c9b7582e6..0000000000 --- a/apps/backend/src/entities/metadata_to_collection.rs +++ /dev/null @@ -1,69 +0,0 @@ -//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 - -use crate::utils::associate_user_with_metadata; - -use super::prelude::Collection; -use async_trait::async_trait; -use sea_orm::entity::prelude::*; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] -#[sea_orm(table_name = "metadata_to_collection")] -pub struct Model { - #[sea_orm(primary_key, auto_increment = false)] - pub metadata_id: i32, - #[sea_orm(primary_key, auto_increment = false)] - pub collection_id: i32, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation { - #[sea_orm( - belongs_to = "super::collection::Entity", - from = "Column::CollectionId", - to = "super::collection::Column::Id", - on_update = "Cascade", - on_delete = "Cascade" - )] - Collection, - #[sea_orm( - belongs_to = "super::metadata::Entity", - from = "Column::MetadataId", - to = "super::metadata::Column::Id", - on_update = "Cascade", - on_delete = "Cascade" - )] - Metadata, -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Collection.def() - } -} - -impl Related for Entity { - fn to() -> RelationDef { - Relation::Metadata.def() - } -} - -#[async_trait] -impl ActiveModelBehavior for ActiveModel { - async fn after_save(model: Model, db: &C, insert: bool) -> Result - where - C: ConnectionTrait, - { - if insert { - // get the collection - let collection = Collection::find_by_id(model.collection_id) - .one(db) - .await? - .unwrap(); - associate_user_with_metadata(&collection.user_id, &model.metadata_id, db) - .await - .ok(); - } - Ok(model) - } -} diff --git a/apps/backend/src/entities/mod.rs b/apps/backend/src/entities/mod.rs index dd07deb10f..5eb9d868a1 100644 --- a/apps/backend/src/entities/mod.rs +++ b/apps/backend/src/entities/mod.rs @@ -4,12 +4,12 @@ pub mod prelude; pub mod calendar_event; pub mod collection; +pub mod collection_to_entity; pub mod exercise; pub mod genre; pub mod import_report; pub mod metadata; pub mod metadata_group; -pub mod metadata_to_collection; pub mod metadata_to_genre; pub mod metadata_to_partial_metadata; pub mod metadata_to_person; diff --git a/apps/backend/src/entities/person.rs b/apps/backend/src/entities/person.rs index e9a5f2e0de..95ff9dda60 100644 --- a/apps/backend/src/entities/person.rs +++ b/apps/backend/src/entities/person.rs @@ -32,6 +32,8 @@ pub struct Model { #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { + #[sea_orm(has_many = "super::collection_to_entity::Entity")] + CollectionToEntity, #[sea_orm(has_many = "super::metadata_to_person::Entity")] MetadataToPerson, #[sea_orm(has_many = "super::person_to_partial_metadata::Entity")] @@ -40,6 +42,12 @@ pub enum Relation { Review, } +impl Related for Entity { + fn to() -> RelationDef { + Relation::CollectionToEntity.def() + } +} + impl Related for Entity { fn to() -> RelationDef { Relation::MetadataToPerson.def() diff --git a/apps/backend/src/entities/prelude.rs b/apps/backend/src/entities/prelude.rs index d4f45a6066..ba82f59390 100644 --- a/apps/backend/src/entities/prelude.rs +++ b/apps/backend/src/entities/prelude.rs @@ -2,12 +2,12 @@ pub use super::calendar_event::Entity as CalendarEvent; pub use super::collection::Entity as Collection; +pub use super::collection_to_entity::Entity as CollectionToEntity; pub use super::exercise::Entity as Exercise; pub use super::genre::Entity as Genre; pub use super::import_report::Entity as ImportReport; pub use super::metadata::Entity as Metadata; pub use super::metadata_group::Entity as MetadataGroup; -pub use super::metadata_to_collection::Entity as MetadataToCollection; pub use super::metadata_to_genre::Entity as MetadataToGenre; pub use super::metadata_to_partial_metadata::Entity as MetadataToPartialMetadata; pub use super::metadata_to_person::Entity as MetadataToPerson; diff --git a/apps/backend/src/fitness/logic.rs b/apps/backend/src/fitness/logic.rs index e709ee6fcc..d522a70a4d 100644 --- a/apps/backend/src/fitness/logic.rs +++ b/apps/backend/src/fitness/logic.rs @@ -1,6 +1,6 @@ use std::cmp::Ordering; -use anyhow::{anyhow, Result}; +use anyhow::Result; use chrono::Utc; use rs_utils::LengthVec; use rust_decimal::{prelude::FromPrimitive, Decimal}; @@ -91,10 +91,13 @@ impl UserWorkoutInput { let mut exercises = vec![]; let mut workout_totals = vec![]; for (idx, ex) in self.exercises.into_iter().enumerate() { - let db_ex = Exercise::find_by_id(ex.exercise_id) - .one(db) - .await? - .ok_or_else(|| anyhow!("No exercise found!"))?; + let db_ex = match Exercise::find_by_id(ex.exercise_id).one(db).await? { + None => { + tracing::error!("Exercise with id = {} not found", ex.exercise_id); + continue; + } + Some(e) => e, + }; let mut sets = vec![]; let mut total = WorkoutTotalMeasurement::default(); let association = UserToExercise::find() diff --git a/apps/backend/src/fitness/resolver.rs b/apps/backend/src/fitness/resolver.rs index 70476a0697..c84326677e 100644 --- a/apps/backend/src/fitness/resolver.rs +++ b/apps/backend/src/fitness/resolver.rs @@ -19,6 +19,7 @@ use crate::{ background::ApplicationJob, config::AppConfig, entities::{ + collection, exercise::{self, ExerciseListItem}, prelude::{Exercise, UserMeasurement, UserToExercise, Workout}, user::UserWithOnlyPreferences, @@ -29,15 +30,17 @@ use crate::{ ExerciseEquipment, ExerciseForce, ExerciseLevel, ExerciseLot, ExerciseMechanic, ExerciseMuscle, ExerciseSource, }, + miscellaneous::DefaultCollection, models::{ fitness::{ Exercise as GithubExercise, ExerciseAttributes, ExerciseCategory, ExerciseMuscles, GithubExerciseAttributes, UserWorkoutInput, WorkoutListItem, WorkoutSetRecord, }, - IdObject, SearchDetails, SearchInput, SearchResults, StoredUrl, + media::ChangeCollectionToEntityInput, + EntityLot, IdObject, SearchDetails, SearchInput, SearchResults, StoredUrl, }, traits::AuthProvider, - utils::{get_ilike_query, partial_user_by_id}, + utils::{add_entity_to_collection, entity_in_collections, get_ilike_query, partial_user_by_id}, }; static JSON_URL: &str = @@ -105,8 +108,9 @@ struct UserExerciseHistoryInformation { #[derive(Debug, Serialize, Deserialize, SimpleObject, Clone)] struct UserExerciseDetails { - details: user_to_exercise::Model, - history: Vec, + details: Option, + history: Option>, + collections: Vec, } #[derive(Debug, Serialize, Deserialize, InputObject, Clone)] @@ -175,7 +179,7 @@ impl ExerciseQuery { &self, gql_ctx: &Context<'_>, input: UserExerciseDetailsInput, - ) -> Result> { + ) -> Result { let service = gql_ctx.data_unchecked::>(); let user_id = service.user_id_from_ctx(gql_ctx).await?; service.user_exercise_details(user_id, input).await @@ -238,7 +242,8 @@ impl ExerciseMutation { input: exercise::Model, ) -> Result { let service = gql_ctx.data_unchecked::>(); - service.create_custom_exercise(input).await + let user_id = service.user_id_from_ctx(gql_ctx).await?; + service.create_custom_exercise(user_id, input).await } } @@ -333,15 +338,23 @@ impl ExerciseService { &self, user_id: i32, input: UserExerciseDetailsInput, - ) -> Result> { - if let Some(details) = UserToExercise::find_by_id((user_id, input.exercise_id)) + ) -> Result { + let collections = + entity_in_collections(&self.db, user_id, input.exercise_id, EntityLot::Exercise) + .await?; + let mut resp = UserExerciseDetails { + details: None, + history: None, + collections, + }; + if let Some(association) = UserToExercise::find_by_id((user_id, input.exercise_id)) .one(&self.db) .await? { let workouts = Workout::find() .filter( workout::Column::Id.is_in( - details + association .extra_information .history .iter() @@ -353,7 +366,7 @@ impl ExerciseService { let mut history = workouts .into_iter() .map(|w| { - let element = details + let element = association .extra_information .history .iter() @@ -370,10 +383,10 @@ impl ExerciseService { if let Some(take) = input.take_history { history = history.into_iter().take(take).collect_vec(); } - Ok(Some(UserExerciseDetails { details, history })) - } else { - Ok(None) + resp.history = Some(history); + resp.details = Some(association); } + Ok(resp) } async fn user_workout_list( @@ -651,7 +664,11 @@ impl ExerciseService { Ok(identifier) } - async fn create_custom_exercise(&self, input: exercise::Model) -> Result { + async fn create_custom_exercise( + &self, + user_id: i32, + input: exercise::Model, + ) -> Result { let mut input = input; input.source = ExerciseSource::Custom; input.attributes.internal_images = input @@ -668,6 +685,16 @@ impl ExerciseService { // FIXME: Blocked by https://github.com/async-graphql/async-graphql/issues/1396 input.id = ActiveValue::NotSet; let exercise = input.insert(&self.db).await?; + add_entity_to_collection( + &self.db, + user_id, + ChangeCollectionToEntityInput { + collection_name: DefaultCollection::Custom.to_string(), + entity_id: exercise.id, + entity_lot: EntityLot::Exercise, + }, + ) + .await?; Ok(IdObject { id: exercise.id }) } diff --git a/apps/backend/src/importer/mod.rs b/apps/backend/src/importer/mod.rs index 2a26a3afee..605894e9ee 100644 --- a/apps/backend/src/importer/mod.rs +++ b/apps/backend/src/importer/mod.rs @@ -21,9 +21,11 @@ use crate::{ models::{ fitness::UserWorkoutInput, media::{ - AddMediaToCollection, CreateOrUpdateCollectionInput, ImportOrExportItemIdentifier, - ImportOrExportMediaItem, PostReviewInput, ProgressUpdateInput, + ChangeCollectionToEntityInput, CreateOrUpdateCollectionInput, + ImportOrExportItemIdentifier, ImportOrExportMediaItem, PostReviewInput, + ProgressUpdateInput, }, + EntityLot, }, traits::AuthProvider, users::UserReviewScale, @@ -434,11 +436,12 @@ impl ImporterService { ) .await?; self.media_service - .add_media_to_collection( + .add_entity_to_collection( user_id, - AddMediaToCollection { + ChangeCollectionToEntityInput { collection_name: col.to_string(), - media_id: metadata.id, + entity_id: metadata.id, + entity_lot: EntityLot::Metadata, }, ) .await diff --git a/apps/backend/src/main.rs b/apps/backend/src/main.rs index 8152ee04ce..ce41cd5801 100644 --- a/apps/backend/src/main.rs +++ b/apps/backend/src/main.rs @@ -45,7 +45,7 @@ use crate::{ entities::prelude::Exercise, graphql::get_schema, migrator::Migrator, - models::media::ExportAllResponse, + models::ExportAllResponse, routes::{ config_handler, graphql_handler, graphql_playground, integration_webhook, json_export, static_handler, upload_file, diff --git a/apps/backend/src/migrator/m20230507_create_collection.rs b/apps/backend/src/migrator/m20230507_create_collection.rs index 1ab2da298d..3f93b6f979 100644 --- a/apps/backend/src/migrator/m20230507_create_collection.rs +++ b/apps/backend/src/migrator/m20230507_create_collection.rs @@ -1,20 +1,10 @@ use sea_orm_migration::prelude::*; -use crate::{ - migrator::{m20230417_create_user::User, Metadata}, - models::media::Visibility, -}; +use crate::{migrator::m20230417_create_user::User, models::media::Visibility}; #[derive(DeriveMigrationName)] pub struct Migration; -#[derive(Iden)] -pub enum MetadataToCollection { - Table, - MetadataId, - CollectionId, -} - #[derive(Iden)] pub enum Collection { Table, @@ -86,51 +76,6 @@ impl MigrationTrait for Migration { .to_owned(), ) .await?; - manager - .create_table( - Table::create() - .table(MetadataToCollection::Table) - .col( - ColumnDef::new(MetadataToCollection::MetadataId) - .integer() - .not_null(), - ) - .col( - ColumnDef::new(MetadataToCollection::CollectionId) - .integer() - .not_null(), - ) - .primary_key( - Index::create() - .name("pk-metadata_collection") - .col(MetadataToCollection::MetadataId) - .col(MetadataToCollection::CollectionId), - ) - .foreign_key( - ForeignKey::create() - .name("fk-metadata_id-collection_id") - .from( - MetadataToCollection::Table, - MetadataToCollection::MetadataId, - ) - .to(Metadata::Table, Metadata::Id) - .on_delete(ForeignKeyAction::Cascade) - .on_update(ForeignKeyAction::Cascade), - ) - .foreign_key( - ForeignKey::create() - .name("fk-collection_id-metadata_id") - .from( - MetadataToCollection::Table, - MetadataToCollection::CollectionId, - ) - .to(Collection::Table, Collection::Id) - .on_delete(ForeignKeyAction::Cascade) - .on_update(ForeignKeyAction::Cascade), - ) - .to_owned(), - ) - .await?; Ok(()) } diff --git a/apps/backend/src/migrator/m20231016_create_collection_to_entity.rs b/apps/backend/src/migrator/m20231016_create_collection_to_entity.rs new file mode 100644 index 0000000000..7b95b8680b --- /dev/null +++ b/apps/backend/src/migrator/m20231016_create_collection_to_entity.rs @@ -0,0 +1,106 @@ +use sea_orm_migration::prelude::*; + +use super::{ + m20230410_create_metadata::Metadata, m20230413_create_person::Person, + m20230507_create_collection::Collection, m20230622_create_exercise::Exercise, + m20230901_create_metadata_group::MetadataGroup, +}; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[derive(Iden)] +pub enum CollectionToEntity { + Table, + Id, + CollectionId, + LastUpdatedOn, + // the entities that can be added to a collection + MetadataId, + MetadataGroupId, + PersonId, + ExerciseId, +} + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(CollectionToEntity::Table) + .col( + ColumnDef::new(CollectionToEntity::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col( + ColumnDef::new(CollectionToEntity::LastUpdatedOn) + .timestamp_with_time_zone() + .not_null() + .default(Expr::current_timestamp()), + ) + .col( + ColumnDef::new(CollectionToEntity::CollectionId) + .integer() + .not_null(), + ) + .foreign_key( + ForeignKey::create() + .name("collection_to_entity-fk1") + .from(CollectionToEntity::Table, CollectionToEntity::CollectionId) + .to(Collection::Table, Collection::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), + ) + .col(ColumnDef::new(CollectionToEntity::MetadataId).integer()) + .foreign_key( + ForeignKey::create() + .name("collection_to_entity-fk2") + .from(CollectionToEntity::Table, CollectionToEntity::MetadataId) + .to(Metadata::Table, Metadata::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), + ) + .col(ColumnDef::new(CollectionToEntity::PersonId).integer()) + .foreign_key( + ForeignKey::create() + .name("collection_to_entity-fk3") + .from(CollectionToEntity::Table, CollectionToEntity::PersonId) + .to(Person::Table, Person::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), + ) + .col(ColumnDef::new(CollectionToEntity::MetadataGroupId).integer()) + .foreign_key( + ForeignKey::create() + .name("collection_to_entity-fk4") + .from( + CollectionToEntity::Table, + CollectionToEntity::MetadataGroupId, + ) + .to(MetadataGroup::Table, MetadataGroup::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), + ) + .col(ColumnDef::new(CollectionToEntity::ExerciseId).integer()) + .foreign_key( + ForeignKey::create() + .name("collection_to_entity-fk5") + .from(CollectionToEntity::Table, CollectionToEntity::ExerciseId) + .to(Exercise::Table, Exercise::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade), + ) + .to_owned(), + ) + .await?; + Ok(()) + } + + async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { + Ok(()) + } +} diff --git a/apps/backend/src/migrator/m20231016_drop_useless_tables.rs b/apps/backend/src/migrator/m20231016_drop_useless_tables.rs new file mode 100644 index 0000000000..257e4f0d1c --- /dev/null +++ b/apps/backend/src/migrator/m20231016_drop_useless_tables.rs @@ -0,0 +1,78 @@ +use sea_orm::{entity::prelude::*, ActiveValue}; +use sea_orm_migration::prelude::*; +use serde::{Deserialize, Serialize}; + +use crate::{ + entities::{ + collection, collection_to_entity, exercise, + prelude::{Collection, Exercise}, + }, + miscellaneous::DefaultCollection, +}; + +use super::ExerciseSource; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[derive(Iden)] +pub enum MetadataToCollection { + Table, +} + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] +#[sea_orm(table_name = "metadata_to_collection")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub metadata_id: i32, + #[sea_orm(primary_key, auto_increment = false)] + pub collection_id: i32, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let db = manager.get_connection(); + if manager.has_table("metadata_to_collection").await? { + for mtc in Entity::find().all(db).await? { + let to_insert = collection_to_entity::ActiveModel { + collection_id: ActiveValue::Set(mtc.collection_id), + metadata_id: ActiveValue::Set(Some(mtc.metadata_id)), + ..Default::default() + }; + to_insert.insert(db).await?; + } + manager + .drop_table(Table::drop().table(MetadataToCollection::Table).to_owned()) + .await?; + } + let collections = Collection::find() + .filter(collection::Column::Name.eq(DefaultCollection::Custom.to_string())) + .all(db) + .await?; + for ex in Exercise::find() + .filter(exercise::Column::Source.eq(ExerciseSource::Custom)) + .all(db) + .await? + { + for col in collections.iter() { + let to_insert = collection_to_entity::ActiveModel { + collection_id: ActiveValue::Set(col.id), + exercise_id: ActiveValue::Set(Some(ex.id)), + ..Default::default() + }; + to_insert.insert(db).await?; + } + } + Ok(()) + } + + async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { + Ok(()) + } +} diff --git a/apps/backend/src/migrator/mod.rs b/apps/backend/src/migrator/mod.rs index 279db1967b..029558b7cf 100644 --- a/apps/backend/src/migrator/mod.rs +++ b/apps/backend/src/migrator/mod.rs @@ -37,6 +37,8 @@ mod m20231003_create_partial_metadata_to_person; mod m20231010_change_name_field_workout_table; mod m20231012_add_source_to_exercise; mod m20231014_remove_processed_from_exercise; +mod m20231016_create_collection_to_entity; +mod m20231016_drop_useless_tables; pub use m20230410_create_metadata::{Metadata, MetadataLot, MetadataSource}; pub use m20230417_create_user::{UserLot, UserToMetadata}; @@ -92,6 +94,8 @@ impl MigratorTrait for Migrator { Box::new(m20231010_change_name_field_workout_table::Migration), Box::new(m20231012_add_source_to_exercise::Migration), Box::new(m20231014_remove_processed_from_exercise::Migration), + Box::new(m20231016_create_collection_to_entity::Migration), + Box::new(m20231016_drop_useless_tables::Migration), ] } } diff --git a/apps/backend/src/miscellaneous/resolver.rs b/apps/backend/src/miscellaneous/resolver.rs index c79f8d5a3d..1e91e7fd97 100644 --- a/apps/backend/src/miscellaneous/resolver.rs +++ b/apps/backend/src/miscellaneous/resolver.rs @@ -12,7 +12,7 @@ use argon2::{Argon2, PasswordHash, PasswordVerifier}; use async_graphql::{ Context, Enum, Error, InputObject, InputType, Object, OneofObject, Result, SimpleObject, Union, }; -use chrono::{Days, Duration as ChronoDuration, NaiveDate, Utc}; +use chrono::{Datelike, Days, Duration as ChronoDuration, NaiveDate, Utc}; use cookie::{ time::{Duration as CookieDuration, OffsetDateTime}, Cookie, SameSite, @@ -50,13 +50,13 @@ use crate::{ background::ApplicationJob, config::AppConfig, entities::{ - calendar_event, collection, genre, metadata, metadata_group, metadata_to_collection, + calendar_event, collection, collection_to_entity, genre, metadata, metadata_group, metadata_to_genre, metadata_to_partial_metadata, metadata_to_person, partial_metadata::{self, PartialMetadataWithoutId}, partial_metadata_to_metadata_group, person, person_to_partial_metadata, prelude::{ - CalendarEvent, Collection, Genre, Metadata, MetadataGroup, MetadataToCollection, - MetadataToGenre, MetadataToPartialMetadata, MetadataToPerson, + CalendarEvent, Collection, CollectionToEntity, Exercise, Genre, Metadata, + MetadataGroup, MetadataToGenre, MetadataToPartialMetadata, MetadataToPerson, PartialMetadata as PartialMetadataModel, PartialMetadataToMetadataGroup, Person, PersonToPartialMetadata, Review, Seen, User, UserMeasurement, UserToMetadata, Workout, }, @@ -78,7 +78,7 @@ use crate::{ miscellaneous::{CustomService, DefaultCollection}, models::{ media::{ - AddMediaToCollection, AnimeSpecifics, AudioBookSpecifics, BookSpecifics, + AnimeSpecifics, AudioBookSpecifics, BookSpecifics, ChangeCollectionToEntityInput, CreateOrUpdateCollectionInput, FreeMetadataCreator, ImportOrExportItemRating, ImportOrExportItemReview, ImportOrExportItemReviewComment, ImportOrExportMediaItem, ImportOrExportMediaItemSeen, ImportOrExportPersonItem, MangaSpecifics, @@ -92,7 +92,7 @@ use crate::{ SeenPodcastExtraInformation, SeenShowExtraInformation, ShowSpecifics, UserMediaReminder, UserSummary, VideoGameSpecifics, Visibility, VisualNovelSpecifics, }, - IdObject, SearchDetails, SearchInput, SearchResults, StoredUrl, + EntityLot, IdObject, SearchDetails, SearchInput, SearchResults, StoredUrl, }, providers::{ anilist::{ @@ -120,9 +120,10 @@ use crate::{ UserYankIntegrationSetting, UserYankIntegrationSettingKind, UserYankIntegrations, }, utils::{ - associate_user_with_metadata, convert_naive_to_utc, get_first_and_last_day_of_month, - get_ilike_query, get_stored_asset, get_user_and_metadata_association, partial_user_by_id, - user_by_id, user_id_from_token, AUTHOR, COOKIE_NAME, USER_AGENT_STR, VERSION, + add_entity_to_collection, associate_user_with_metadata, convert_naive_to_utc, + entity_in_collections, get_first_and_last_day_of_month, get_ilike_query, get_stored_asset, + get_user_and_metadata_association, partial_user_by_id, user_by_id, user_id_from_token, + AUTHOR, COOKIE_NAME, USER_AGENT_STR, VERSION, }, }; @@ -528,11 +529,6 @@ struct CreatorsListInput { sort: Option>, } -#[derive(Debug, Serialize, Deserialize, InputObject, Clone)] -struct CollectionInput { - name: Option, -} - #[derive(Debug, Serialize, Deserialize, InputObject, Clone)] struct MediaConsumedInput { identifier: String, @@ -575,6 +571,12 @@ struct ProgressUpdateCache { #[derive(SimpleObject)] struct UserCreatorDetails { reviews: Vec, + collections: Vec, +} + +#[derive(SimpleObject)] +struct UserMetadataGroupDetails { + collections: Vec, } #[derive(SimpleObject)] @@ -712,14 +714,14 @@ impl MiscellaneousQuery { } /// Get all collections for the currently logged in user. - async fn collections( + async fn user_collections_list( &self, gql_ctx: &Context<'_>, - input: Option, + name: Option, ) -> Result> { let service = gql_ctx.data_unchecked::>(); let user_id = service.user_id_from_ctx(gql_ctx).await?; - service.collections(user_id, input).await + service.user_collections_list(user_id, name).await } /// Get the contents of a collection and respect visibility. @@ -763,6 +765,19 @@ impl MiscellaneousQuery { service.metadata_group_details(metadata_group_id).await } + /// Get details that can be displayed to a user for a metadata group. + async fn user_metadata_group_details( + &self, + gql_ctx: &Context<'_>, + metadata_group_id: i32, + ) -> Result { + let service = gql_ctx.data_unchecked::>(); + let user_id = service.user_id_from_ctx(gql_ctx).await?; + service + .user_metadata_group_details(user_id, metadata_group_id) + .await + } + /// Get all the media items related to a user for a specific media type. async fn media_list( &self, @@ -962,29 +977,26 @@ impl MiscellaneousMutation { service.create_or_update_collection(user_id, input).await } - /// Add a media item to a collection if it is not there, otherwise do nothing. - async fn add_media_to_collection( + /// Add a entity to a collection if it is not there, otherwise do nothing. + async fn add_entity_to_collection( &self, gql_ctx: &Context<'_>, - input: AddMediaToCollection, + input: ChangeCollectionToEntityInput, ) -> Result { let service = gql_ctx.data_unchecked::>(); let user_id = service.user_id_from_ctx(gql_ctx).await?; - service.add_media_to_collection(user_id, input).await + service.add_entity_to_collection(user_id, input).await } - /// Remove a media item from a collection if it is not there, otherwise do nothing. - async fn remove_media_from_collection( + /// Remove an entity from a collection if it is not there, otherwise do nothing. + async fn remove_entity_from_collection( &self, gql_ctx: &Context<'_>, - metadata_id: i32, - collection_name: String, + input: ChangeCollectionToEntityInput, ) -> Result { let service = gql_ctx.data_unchecked::>(); let user_id = service.user_id_from_ctx(gql_ctx).await?; - service - .remove_media_from_collection(user_id, &metadata_id, &collection_name) - .await + service.remove_entity_from_collection(user_id, input).await } /// Delete a collection. @@ -1693,7 +1705,8 @@ impl MiscellaneousService { async fn user_media_details(&self, user_id: i32, metadata_id: i32) -> Result { let media_details = self.media_details(metadata_id).await?; - let collections = self.media_in_collections(user_id, metadata_id).await?; + let collections = + entity_in_collections(&self.db, user_id, metadata_id, EntityLot::Metadata).await?; let reviews = self.item_reviews(user_id, Some(metadata_id), None).await?; let history = self.seen_history(user_id, metadata_id).await?; let in_progress = history @@ -1790,7 +1803,27 @@ impl MiscellaneousService { creator_id: i32, ) -> Result { let reviews = self.item_reviews(user_id, None, Some(creator_id)).await?; - Ok(UserCreatorDetails { reviews }) + let collections = + entity_in_collections(&self.db, user_id, creator_id, EntityLot::Person).await?; + Ok(UserCreatorDetails { + reviews, + collections, + }) + } + + async fn user_metadata_group_details( + &self, + user_id: i32, + metadata_group_id: i32, + ) -> Result { + let collections = entity_in_collections( + &self.db, + user_id, + metadata_group_id, + EntityLot::MetadataGroup, + ) + .await?; + Ok(UserMetadataGroupDetails { collections }) } async fn get_calendar_events( @@ -2115,8 +2148,9 @@ impl MiscellaneousService { if let Some(f) = input.filter { if let Some(s) = f.collection { - let all_media = MetadataToCollection::find() - .filter(metadata_to_collection::Column::CollectionId.eq(s)) + let all_media = CollectionToEntity::find() + .filter(collection_to_entity::Column::CollectionId.eq(s)) + .filter(collection_to_entity::Column::MetadataId.is_not_null()) .all(&self.db) .await?; let collections = all_media.into_iter().map(|m| m.metadata_id).collect_vec(); @@ -2548,10 +2582,10 @@ impl MiscellaneousService { .all(&self.db) .await .unwrap(); - let meta_ids: Vec = MetadataToCollection::find() + let meta_ids: Vec = CollectionToEntity::find() .select_only() - .column(metadata_to_collection::Column::MetadataId) - .filter(metadata_to_collection::Column::CollectionId.is_in(collection_ids)) + .column(collection_to_entity::Column::MetadataId) + .filter(collection_to_entity::Column::CollectionId.is_in(collection_ids)) .into_tuple() .all(&self.db) .await @@ -3058,12 +3092,17 @@ impl MiscellaneousService { .count(&self.db) .await .unwrap(); + let num_col_associations = CollectionToEntity::find() + .filter(collection_to_entity::Column::PersonId.eq(creator.id)) + .count(&self.db) + .await + .unwrap(); let num_reviews = Review::find() .filter(review::Column::PersonId.eq(creator.id)) .count(&self.db) .await .unwrap(); - if num_associations + num_reviews == 0 { + if num_associations + num_col_associations + num_reviews == 0 { creator.delete(&self.db).await.ok(); } } @@ -3144,10 +3183,10 @@ impl MiscellaneousService { new_review.insert(&self.db).await?; old_review.delete(&self.db).await?; } - MetadataToCollection::update_many() - .filter(metadata_to_collection::Column::MetadataId.eq(merge_from)) - .set(metadata_to_collection::ActiveModel { - metadata_id: ActiveValue::Set(merge_into), + CollectionToEntity::update_many() + .filter(collection_to_entity::Column::MetadataId.eq(merge_from)) + .set(collection_to_entity::ActiveModel { + metadata_id: ActiveValue::Set(Some(merge_into)), ..Default::default() }) .exec(&self.db) @@ -3606,14 +3645,14 @@ impl MiscellaneousService { Ok(all_reviews) } - async fn collections( + async fn user_collections_list( &self, user_id: i32, - input: Option, + name: Option, ) -> Result> { let collections = Collection::find() .filter(collection::Column::UserId.eq(user_id)) - .apply_if(input.clone().and_then(|i| i.name), |query, v| { + .apply_if(name, |query, v| { query.filter(collection::Column::Name.eq(v)) }) .order_by_asc(collection::Column::CreatedOn) @@ -3622,7 +3661,10 @@ impl MiscellaneousService { .unwrap(); let mut data = vec![]; for collection in collections.into_iter() { - let num_items = collection.find_related(Metadata).count(&self.db).await?; + let num_items = collection + .find_related(CollectionToEntity) + .count(&self.db) + .await?; data.push(CollectionItem { id: collection.id, name: collection.name, @@ -3634,35 +3676,6 @@ impl MiscellaneousService { Ok(data) } - async fn media_in_collections( - &self, - user_id: i32, - metadata_id: i32, - ) -> Result> { - let user_collections = Collection::find() - .filter(collection::Column::UserId.eq(user_id)) - .all(&self.db) - .await - .unwrap(); - let mtc = MetadataToCollection::find() - .filter(metadata_to_collection::Column::MetadataId.eq(metadata_id)) - .filter( - metadata_to_collection::Column::CollectionId - .is_in(user_collections.into_iter().map(|c| c.id).collect_vec()), - ) - .find_also_related(Collection) - .all(&self.db) - .await - .unwrap(); - let mut resp = vec![]; - mtc.into_iter().for_each(|(_, b)| { - if let Some(m) = b { - resp.push(m); - } - }); - Ok(resp) - } - async fn collection_contents( &self, user_id: Option, @@ -3689,47 +3702,81 @@ impl MiscellaneousService { } } - let all_metadata_items = Metadata::find() - .join( - JoinType::Join, - user_to_metadata::Relation::Metadata.def().rev(), - ) - .join( - JoinType::Join, - metadata_to_collection::Relation::Metadata.def().rev(), - ) - .filter(metadata_to_collection::Column::CollectionId.eq(collection.id)) - .order_by_desc(user_to_metadata::Column::LastUpdatedOn) + let paginator = CollectionToEntity::find() + .filter(collection_to_entity::Column::CollectionId.eq(collection.id)) + .order_by_desc(collection_to_entity::Column::LastUpdatedOn) .paginate( &self.db, input .take .unwrap_or_else(|| self.config.frontend.page_size.try_into().unwrap()), ); - + let mut items = vec![]; let ItemsAndPagesNumber { number_of_items, number_of_pages, - } = all_metadata_items.num_items_and_pages().await?; - let mut meta_data = vec![]; - for m in all_metadata_items.fetch_page(page - 1).await? { - meta_data.push(( - MediaSearchItem { - identifier: m.id.to_string(), - image: self.metadata_assets(&m).await?.images.first().cloned(), - title: m.title, - publish_year: m.publish_year, - }, - m.lot, - )); + } = paginator.num_items_and_pages().await?; + for cte in paginator.fetch_page(page - 1).await? { + let item = if let Some(id) = cte.metadata_id { + let m = Metadata::find_by_id(id).one(&self.db).await?.unwrap(); + MediaSearchItemWithLot { + details: MediaSearchItem { + identifier: m.id.to_string(), + title: m.title, + image: m.images.first_as_url(&self.file_storage_service).await, + publish_year: m.publish_year, + }, + metadata_lot: Some(m.lot), + entity_lot: EntityLot::Metadata, + } + } else if let Some(id) = cte.person_id { + let p = Person::find_by_id(id).one(&self.db).await?.unwrap(); + MediaSearchItemWithLot { + details: MediaSearchItem { + identifier: p.id.to_string(), + title: p.name, + image: p.images.first_as_url(&self.file_storage_service).await, + publish_year: p.birth_date.map(|d| d.year()), + }, + metadata_lot: None, + entity_lot: EntityLot::Person, + } + } else if let Some(id) = cte.metadata_group_id { + let g = MetadataGroup::find_by_id(id).one(&self.db).await?.unwrap(); + MediaSearchItemWithLot { + details: MediaSearchItem { + identifier: g.id.to_string(), + title: g.title, + image: Some(g.images) + .first_as_url(&self.file_storage_service) + .await, + publish_year: None, + }, + metadata_lot: None, + entity_lot: EntityLot::MetadataGroup, + } + } else if let Some(id) = cte.exercise_id { + let e = Exercise::find_by_id(id).one(&self.db).await?.unwrap(); + let image = if let Some(i) = e.attributes.internal_images.first().cloned() { + Some(get_stored_asset(i, &self.file_storage_service).await) + } else { + None + }; + MediaSearchItemWithLot { + details: MediaSearchItem { + identifier: e.id.to_string(), + title: e.name, + image, + publish_year: None, + }, + metadata_lot: None, + entity_lot: EntityLot::Exercise, + } + } else { + unreachable!() + }; + items.push(item); } - let items = meta_data - .into_iter() - .map(|a| MediaSearchItemWithLot { - details: a.0, - lot: a.1, - }) - .collect(); let user = collection.find_related(User).one(&self.db).await?.unwrap(); Ok(CollectionContents { details: collection, @@ -3881,45 +3928,38 @@ impl MiscellaneousService { Ok(resp) } - pub async fn remove_media_from_collection( + pub async fn add_entity_to_collection( &self, user_id: i32, - metadata_id: &i32, - collection_name: &str, - ) -> Result { - let collect = Collection::find() - .filter(collection::Column::Name.eq(collection_name.to_owned())) - .filter(collection::Column::UserId.eq(user_id.to_owned())) - .one(&self.db) - .await - .unwrap() - .unwrap(); - let col = metadata_to_collection::ActiveModel { - metadata_id: ActiveValue::Set(metadata_id.to_owned()), - collection_id: ActiveValue::Set(collect.id), - }; - let id = col.collection_id.clone().unwrap(); - col.delete(&self.db).await.ok(); - Ok(IdObject { id }) + input: ChangeCollectionToEntityInput, + ) -> Result { + add_entity_to_collection(&self.db, user_id, input).await } - pub async fn add_media_to_collection( + pub async fn remove_entity_from_collection( &self, user_id: i32, - input: AddMediaToCollection, - ) -> Result { - let collection = Collection::find() + input: ChangeCollectionToEntityInput, + ) -> Result { + let collect = Collection::find() + .filter(collection::Column::Name.eq(input.collection_name.to_owned())) .filter(collection::Column::UserId.eq(user_id.to_owned())) - .filter(collection::Column::Name.eq(input.collection_name)) .one(&self.db) .await .unwrap() .unwrap(); - let col = metadata_to_collection::ActiveModel { - metadata_id: ActiveValue::Set(input.media_id), - collection_id: ActiveValue::Set(collection.id), + let target_column = match input.entity_lot { + EntityLot::Metadata => collection_to_entity::Column::MetadataId, + EntityLot::Person => collection_to_entity::Column::PersonId, + EntityLot::MetadataGroup => collection_to_entity::Column::MetadataGroupId, + EntityLot::Exercise => collection_to_entity::Column::ExerciseId, }; - Ok(col.clone().insert(&self.db).await.is_ok()) + CollectionToEntity::delete_many() + .filter(collection_to_entity::Column::CollectionId.eq(collect.id)) + .filter(target_column.eq(input.entity_id.to_owned())) + .exec(&self.db) + .await?; + Ok(IdObject { id: collect.id }) } pub async fn delete_seen_item(&self, seen_id: i32, user_id: i32) -> Result { @@ -3936,10 +3976,13 @@ impl MiscellaneousService { } si.delete(&self.db).await.ok(); if progress < 100 { - self.remove_media_from_collection( + self.remove_entity_from_collection( user_id, - &metadata_id, - &DefaultCollection::InProgress.to_string(), + ChangeCollectionToEntityInput { + collection_name: DefaultCollection::InProgress.to_string(), + entity_id: metadata_id, + entity_lot: EntityLot::Metadata, + }, ) .await .ok(); @@ -4439,11 +4482,12 @@ impl MiscellaneousService { people: vec![], }; let media = self.commit_media_internal(details).await?; - self.add_media_to_collection( + self.add_entity_to_collection( user_id, - AddMediaToCollection { + ChangeCollectionToEntityInput { collection_name: DefaultCollection::Custom.to_string(), - media_id: media.id, + entity_id: media.id, + entity_lot: EntityLot::Metadata, }, ) .await?; @@ -5312,30 +5356,37 @@ impl MiscellaneousService { } pub async fn after_media_seen_tasks(&self, seen: seen::Model) -> Result<()> { - self.remove_media_from_collection( + self.remove_entity_from_collection( seen.user_id, - &seen.metadata_id, - &DefaultCollection::Watchlist.to_string(), + ChangeCollectionToEntityInput { + collection_name: DefaultCollection::Watchlist.to_string(), + entity_id: seen.metadata_id, + entity_lot: EntityLot::Metadata, + }, ) .await .ok(); match seen.state { SeenState::InProgress => { - self.add_media_to_collection( + self.add_entity_to_collection( seen.user_id, - AddMediaToCollection { + ChangeCollectionToEntityInput { collection_name: DefaultCollection::InProgress.to_string(), - media_id: seen.metadata_id, + entity_id: seen.metadata_id, + entity_lot: EntityLot::Metadata, }, ) .await .ok(); } SeenState::Dropped | SeenState::OnAHold => { - self.remove_media_from_collection( + self.remove_entity_from_collection( seen.user_id, - &seen.metadata_id, - &DefaultCollection::InProgress.to_string(), + ChangeCollectionToEntityInput { + collection_name: DefaultCollection::InProgress.to_string(), + entity_id: seen.metadata_id, + entity_lot: EntityLot::Metadata, + }, ) .await .ok(); @@ -5387,19 +5438,23 @@ impl MiscellaneousService { }); let is_complete = bag.values().all(|&e| e == 1); if is_complete { - self.remove_media_from_collection( + self.remove_entity_from_collection( seen.user_id, - &seen.metadata_id, - &DefaultCollection::InProgress.to_string(), + ChangeCollectionToEntityInput { + collection_name: DefaultCollection::InProgress.to_string(), + entity_id: seen.metadata_id, + entity_lot: EntityLot::Metadata, + }, ) .await .ok(); } else { - self.add_media_to_collection( + self.add_entity_to_collection( seen.user_id, - AddMediaToCollection { + ChangeCollectionToEntityInput { collection_name: DefaultCollection::InProgress.to_string(), - media_id: seen.metadata_id, + entity_id: seen.metadata_id, + entity_lot: EntityLot::Metadata, }, ) .await @@ -5413,10 +5468,13 @@ impl MiscellaneousService { } } } else { - self.remove_media_from_collection( + self.remove_entity_from_collection( seen.user_id, - &seen.metadata_id, - &DefaultCollection::InProgress.to_string(), + ChangeCollectionToEntityInput { + collection_name: DefaultCollection::InProgress.to_string(), + entity_id: seen.metadata_id, + entity_lot: EntityLot::Metadata, + }, ) .await .ok(); @@ -5450,16 +5508,19 @@ impl MiscellaneousService { metadata_id: i32, ) -> Result> { let mut user_ids = vec![]; + // DEV: This is very inefficient but since we are running this once a day, it does not matter for your_col in [DefaultCollection::Watchlist, DefaultCollection::InProgress] { let collections = Collection::find() .filter(collection::Column::Name.eq(your_col.to_string())) - .find_with_related(Metadata) .all(&self.db) .await?; - for (col, metadatas) in collections { - for metadata in metadatas { - if metadata.id == metadata_id { - user_ids.push(col.user_id); + for col in collections { + let related_meta = col.find_related(CollectionToEntity).all(&self.db).await?; + for rel in related_meta { + if let Some(metadata) = rel.find_related(Metadata).one(&self.db).await? { + if metadata.id == metadata_id { + user_ids.push(col.user_id); + } } } } @@ -5671,7 +5732,7 @@ impl MiscellaneousService { }) .column_as( Expr::expr(Func::count(Expr::col( - metadata_to_collection::Column::MetadataId, + metadata_to_person::Column::MetadataId, ))), alias, ) @@ -5950,8 +6011,7 @@ impl MiscellaneousService { ); reviews.push(review_item); } - let collections = self - .media_in_collections(user_id, m.id) + let collections = entity_in_collections(&self.db, user_id, m.id, EntityLot::Metadata) .await? .into_iter() .map(|c| c.name) @@ -5987,9 +6047,16 @@ impl MiscellaneousService { if let Some(entry) = resp.iter_mut().find(|c| c.name == creator.name) { entry.reviews.push(review_item); } else { + let collections = + entity_in_collections(&self.db, user_id, creator.id, EntityLot::Person) + .await? + .into_iter() + .map(|c| c.name) + .collect(); resp.push(ImportOrExportPersonItem { name: creator.name, reviews: vec![review_item], + collections, }); } } diff --git a/apps/backend/src/models.rs b/apps/backend/src/models.rs index be7f9d0253..9658cf89bb 100644 --- a/apps/backend/src/models.rs +++ b/apps/backend/src/models.rs @@ -11,6 +11,7 @@ use derive_more::{Add, AddAssign, Sum}; use rust_decimal::prelude::FromPrimitive; use rust_decimal::Decimal; use rust_decimal_macros::dec; +use schematic::ConfigEnum; use schematic::Schematic; use sea_orm::{ prelude::DateTimeUtc, DeriveActiveEnum, DerivePartialModel, EnumIter, FromJsonQueryResult, @@ -22,17 +23,25 @@ use serde_with::skip_serializing_none; use crate::{ entities::{ exercise::ExerciseListItem, partial_metadata::PartialMetadataWithoutId, prelude::Workout, - user_measurement, + user_measurement, workout, }, file_storage::FileStorageService, migrator::{ - ExerciseEquipment, ExerciseForce, ExerciseLevel, ExerciseMechanic, ExerciseMuscle, - MetadataLot, MetadataSource, SeenState, + ExerciseEquipment, ExerciseForce, ExerciseLevel, ExerciseLot, ExerciseMechanic, + ExerciseMuscle, MetadataLot, MetadataSource, SeenState, }, traits::{DatabaseAssestsAsSingleUrl, DatabaseAssetsAsUrls}, utils::get_stored_asset, }; +#[derive(Enum, Clone, Debug, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum EntityLot { + Metadata, + Person, + MetadataGroup, + Exercise, +} + #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)] pub enum StoredUrl { S3(String), @@ -90,15 +99,28 @@ pub struct IdObject { pub id: i32, } -pub mod media { - use crate::entities::workout; +/// Complete export of the user. +#[skip_serializing_none] +#[derive(Debug, Serialize, Deserialize, Clone, Schematic)] +pub struct ExportAllResponse { + /// Data about user's media. + pub media: Vec, + /// Data about user's people. + pub people: Vec, + /// Data about user's measurements. + pub measurements: Vec, + /// Data about user's workouts. + pub workouts: Vec, +} +pub mod media { use super::*; #[derive(Debug, SimpleObject, Serialize, Deserialize, Clone)] pub struct MediaSearchItemWithLot { pub details: MediaSearchItem, - pub lot: MetadataLot, + pub metadata_lot: Option, + pub entity_lot: EntityLot, } #[derive(Debug, Serialize, Deserialize, SimpleObject, Clone)] @@ -672,9 +694,10 @@ pub mod media { } #[derive(Debug, InputObject)] - pub struct AddMediaToCollection { + pub struct ChangeCollectionToEntityInput { pub collection_name: String, - pub media_id: i32, + pub entity_id: i32, + pub entity_lot: EntityLot, } #[derive(Debug, InputObject)] @@ -850,24 +873,10 @@ pub mod media { pub seen_history: Vec, /// The review history for the user. pub reviews: Vec, - /// The collections to add this media to. + /// The collections this entity was added to. pub collections: Vec, } - /// Complete export of the user. - #[skip_serializing_none] - #[derive(Debug, Serialize, Deserialize, Clone, Schematic)] - pub struct ExportAllResponse { - /// Data about user's media. - pub media: Vec, - /// Data about user's people. - pub people: Vec, - /// Data about user's measurements. - pub measurements: Vec, - /// Data about user's workouts. - pub workouts: Vec, - } - /// Details about a specific creator item that needs to be exported. #[skip_serializing_none] #[derive(Debug, Serialize, Deserialize, Clone, Schematic)] @@ -876,6 +885,8 @@ pub mod media { pub name: String, /// The review history for the user. pub reviews: Vec, + /// The collections this entity was added to. + pub collections: Vec, } #[derive(Debug, Serialize, Deserialize, Clone, FromJsonQueryResult, Eq, PartialEq, Default)] @@ -1077,9 +1088,6 @@ pub mod media { } pub mod fitness { - use schematic::ConfigEnum; - - use crate::migrator::ExerciseLot; use super::*; diff --git a/apps/backend/src/routes.rs b/apps/backend/src/routes.rs index 1795e1dfec..da1aef2e40 100644 --- a/apps/backend/src/routes.rs +++ b/apps/backend/src/routes.rs @@ -15,8 +15,7 @@ use serde_json::json; use crate::{ config::AppConfig, fitness::resolver::ExerciseService, graphql::GraphqlSchema, - miscellaneous::resolver::MiscellaneousService, models::media::ExportAllResponse, - utils::AuthContext, + miscellaneous::resolver::MiscellaneousService, models::ExportAllResponse, utils::AuthContext, }; static INDEX_HTML: &str = "index.html"; diff --git a/apps/backend/src/utils.rs b/apps/backend/src/utils.rs index e341f82b38..2a93e45b6a 100644 --- a/apps/backend/src/utils.rs +++ b/apps/backend/src/utils.rs @@ -15,6 +15,7 @@ use axum_extra::extract::cookie::CookieJar; use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc}; use http::header::AUTHORIZATION; use http_types::headers::HeaderName; +use itertools::Itertools; use sea_orm::{ prelude::DateTimeUtc, ActiveModelTrait, ActiveValue, ColumnTrait, ConnectionTrait, DatabaseConnection, EntityTrait, PartialModelTrait, QueryFilter, @@ -29,7 +30,8 @@ use crate::{ background::ApplicationJob, config::AppConfig, entities::{ - prelude::{User, UserToMetadata}, + collection, collection_to_entity, + prelude::{Collection, CollectionToEntity, User, UserToMetadata}, user, user_to_metadata, }, file_storage::FileStorageService, @@ -37,7 +39,7 @@ use crate::{ importer::ImporterService, jwt, miscellaneous::resolver::MiscellaneousService, - models::StoredUrl, + models::{media::ChangeCollectionToEntityInput, EntityLot, StoredUrl}, }; pub static BASE_DIR: &str = env!("CARGO_MANIFEST_DIR"); @@ -212,6 +214,92 @@ pub async fn get_stored_asset( } } +pub async fn entity_in_collections( + db: &DatabaseConnection, + user_id: i32, + entity_id: i32, + entity_lot: EntityLot, +) -> Result> { + let user_collections = Collection::find() + .filter(collection::Column::UserId.eq(user_id)) + .all(db) + .await + .unwrap(); + let target_column = match entity_lot { + EntityLot::Metadata => collection_to_entity::Column::MetadataId, + EntityLot::Person => collection_to_entity::Column::PersonId, + EntityLot::MetadataGroup => collection_to_entity::Column::MetadataGroupId, + EntityLot::Exercise => collection_to_entity::Column::ExerciseId, + }; + let mtc = CollectionToEntity::find() + .filter( + collection_to_entity::Column::CollectionId + .is_in(user_collections.into_iter().map(|c| c.id).collect_vec()), + ) + .filter(target_column.eq(entity_id)) + .find_also_related(Collection) + .all(db) + .await + .unwrap(); + let mut resp = vec![]; + mtc.into_iter().for_each(|(_, b)| { + if let Some(m) = b { + resp.push(m); + } + }); + Ok(resp) +} + +pub async fn add_entity_to_collection( + db: &DatabaseConnection, + user_id: i32, + input: ChangeCollectionToEntityInput, +) -> Result { + let target_column = match input.entity_lot { + EntityLot::Metadata => collection_to_entity::Column::MetadataId, + EntityLot::Person => collection_to_entity::Column::PersonId, + EntityLot::MetadataGroup => collection_to_entity::Column::MetadataGroupId, + EntityLot::Exercise => collection_to_entity::Column::ExerciseId, + }; + let collection = Collection::find() + .filter(collection::Column::UserId.eq(user_id.to_owned())) + .filter(collection::Column::Name.eq(input.collection_name)) + .one(db) + .await + .unwrap() + .unwrap(); + if let Some(etc) = CollectionToEntity::find() + .filter(collection_to_entity::Column::CollectionId.eq(collection.id)) + .filter(target_column.eq(input.entity_id)) + .one(db) + .await? + { + let mut to_update: collection_to_entity::ActiveModel = etc.into(); + to_update.last_updated_on = ActiveValue::Set(Utc::now()); + Ok(to_update.update(db).await.is_ok()) + } else { + let mut created_collection = collection_to_entity::ActiveModel { + collection_id: ActiveValue::Set(collection.id), + ..Default::default() + }; + match input.entity_lot { + EntityLot::Metadata => { + created_collection.metadata_id = ActiveValue::Set(Some(input.entity_id)) + } + EntityLot::Person => { + created_collection.person_id = ActiveValue::Set(Some(input.entity_id)) + } + EntityLot::MetadataGroup => { + created_collection.metadata_group_id = ActiveValue::Set(Some(input.entity_id)) + } + EntityLot::Exercise => { + created_collection.exercise_id = ActiveValue::Set(Some(input.entity_id)) + } + }; + Ok(created_collection.insert(db).await.is_ok()) + } +} + pub async fn user_by_id(db: &DatabaseConnection, user_id: i32) -> Result { User::find_by_id(user_id) .one(db) diff --git a/apps/frontend/src/lib/components/MediaComponents.tsx b/apps/frontend/src/lib/components/MediaComponents.tsx index c582e8835a..37f97b3317 100644 --- a/apps/frontend/src/lib/components/MediaComponents.tsx +++ b/apps/frontend/src/lib/components/MediaComponents.tsx @@ -6,11 +6,18 @@ import { useUserPreferences, } from "@/lib/hooks/graphql"; import { gqlClient } from "@/lib/services/api"; -import { Verb, getFallbackImageUrl, getLot, getVerb } from "@/lib/utilities"; +import { + Verb, + getFallbackImageUrl, + getLot, + getStringAsciiValue, + getVerb, +} from "@/lib/utilities"; import { ActionIcon, Anchor, Avatar, + Badge, Box, Button, Collapse, @@ -18,24 +25,32 @@ import { Flex, Image, Loader, + Modal, Paper, ScrollArea, + Select, Stack, Text, + Title, Tooltip, useComputedColorScheme, + useMantineTheme, } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; import { notifications } from "@mantine/notifications"; import { - AddMediaToCollectionDocument, - type AddMediaToCollectionMutationVariables, + AddEntityToCollectionDocument, + type AddEntityToCollectionMutationVariables, CreateReviewCommentDocument, type CreateReviewCommentMutationVariables, + EntityLot, MetadataLot, MetadataSource, type PartialMetadata, + RemoveEntityFromCollectionDocument, + type RemoveEntityFromCollectionMutationVariables, type ReviewItem, + UserCollectionsListDocument, UserReviewScale, } from "@ryot/generated/graphql/backend/graphql"; import { changeCase, getInitials } from "@ryot/ts-utils"; @@ -44,11 +59,13 @@ import { IconEdit, IconStarFilled, IconTrash, + IconX, } from "@tabler/icons-react"; -import { useMutation } from "@tanstack/react-query"; +import { useMutation, useQuery } from "@tanstack/react-query"; import { DateTime } from "luxon"; import Link from "next/link"; import { useRouter } from "next/router"; +import { useState } from "react"; import type { DeepPartial } from "ts-essentials"; import { match } from "ts-pattern"; import { withQuery } from "ufo"; @@ -368,10 +385,11 @@ type Item = { export const MediaItemWithoutUpdateModal = (props: { item: Item; - lot: MetadataLot; + entityLot?: EntityLot | null; + href?: string; + lot?: MetadataLot | null; children?: JSX.Element; imageOverlayForLoadingIndicator?: boolean; - href: string; existsInDatabase?: boolean; averageRating?: string; noRatingLink?: boolean; @@ -382,7 +400,30 @@ export const MediaItemWithoutUpdateModal = (props: { return userPreferences.data ? ( APP_ROUTES.media.individualMediaItem.details, + ) + .with( + EntityLot.MetadataGroup, + () => APP_ROUTES.media.groups.details, + ) + .with(EntityLot.Person, () => APP_ROUTES.media.people.details) + .with( + EntityLot.Exercise, + () => APP_ROUTES.fitness.exercises.details, + ) + .exhaustive(), + { id: props.item.identifier }, + ) + } imageLink={props.item.image} imagePlaceholder={getInitials(props.item?.title || "")} topLeft={ @@ -452,7 +493,9 @@ export const MediaItemWithoutUpdateModal = (props: { ) } bottomLeft={props.item.publishYear} - bottomRight={changeCase(props.lot || "")} + bottomRight={changeCase( + props.lot ? props.lot : props.entityLot ? props.entityLot : "", + )} highlightRightText={ props.existsInDatabase ? "This media exists in the database" : undefined } @@ -476,12 +519,12 @@ export const MediaSearchItem = (props: { const commitMedia = useCommitMedia(lot); const addMediaToCollection = useMutation({ - mutationFn: async (variables: AddMediaToCollectionMutationVariables) => { - const { addMediaToCollection } = await gqlClient.request( - AddMediaToCollectionDocument, + mutationFn: async (variables: AddEntityToCollectionMutationVariables) => { + const { addEntityToCollection } = await gqlClient.request( + AddEntityToCollectionDocument, variables, ); - return addMediaToCollection; + return addEntityToCollection; }, onSuccess: () => { props.searchQueryRefetch(); @@ -567,7 +610,11 @@ export const MediaSearchItem = (props: { onClick={async () => { const id = await commitFunction(); addMediaToCollection.mutate({ - input: { collectionName: "Watchlist", mediaId: id }, + input: { + collectionName: "Watchlist", + entityId: id, + entityLot: EntityLot.Metadata, + }, }); }} disabled={addMediaToCollection.isLoading} @@ -578,3 +625,146 @@ export const MediaSearchItem = (props: { ); }; + +export const AddEntityToCollectionModal = (props: { + opened: boolean; + onClose: () => void; + entityId: number; + refetchUserMedia: () => void; + entityLot: EntityLot; +}) => { + const [selectedCollection, setSelectedCollection] = useState( + null, + ); + + const collections = useQuery({ + queryKey: ["collections"], + queryFn: async () => { + const { userCollectionsList } = await gqlClient.request( + UserCollectionsListDocument, + {}, + ); + return userCollectionsList.map((c) => c.name); + }, + }); + const addMediaToCollection = useMutation({ + mutationFn: async (variables: AddEntityToCollectionMutationVariables) => { + const { addEntityToCollection } = await gqlClient.request( + AddEntityToCollectionDocument, + variables, + ); + return addEntityToCollection; + }, + onSuccess: () => { + props.refetchUserMedia(); + props.onClose(); + }, + }); + + return collections.data ? ( + + {collections ? ( + + Select collection + {collections.data.length > 0 ? ( + - ) : undefined} - - - - ) : undefined} - - ) : undefined; -}; - const CreateReminderModal = (props: { opened: boolean; onClose: () => void; @@ -454,8 +377,6 @@ const AccordionLabel = ({ const Page: NextPageWithLayout = () => { const router = useRouter(); const metadataId = parseInt(router.query.id?.toString() || "0"); - const theme = useMantineTheme(); - const colors = Object.keys(theme.colors); const coreDetails = useCoreDetails(); const preferences = useUserPreferences(); @@ -606,20 +527,6 @@ const Page: NextPageWithLayout = () => { router.push(APP_ROUTES.dashboard); }, }); - const removeMediaFromCollection = useMutation({ - mutationFn: async ( - variables: RemoveMediaFromCollectionMutationVariables, - ) => { - const { removeMediaFromCollection } = await gqlClient.request( - RemoveMediaFromCollectionDocument, - variables, - ); - return removeMediaFromCollection; - }, - onSuccess: () => { - userMediaDetails.refetch(); - }, - }); const source = mediaDetails?.data?.source || MetadataSource.Custom; @@ -705,46 +612,15 @@ const Page: NextPageWithLayout = () => { {userMediaDetails.data && userMediaDetails.data.collections.length > 0 ? ( - + {userMediaDetails.data.collections.map((col) => ( - - - - {col.name} - - { - const yes = confirm( - "Are you sure you want to remove this media from this collection?", - ); - if (yes) - removeMediaFromCollection.mutate({ - collectionName: col.name, - metadataId, - }); - }} - > - - - - + /> ))} ) : undefined} @@ -1247,11 +1123,12 @@ const Page: NextPageWithLayout = () => { - + + diff --git a/docs/includes/export-schema.ts b/docs/includes/export-schema.ts index 4fef711c5b..827f519d1f 100644 --- a/docs/includes/export-schema.ts +++ b/docs/includes/export-schema.ts @@ -98,7 +98,7 @@ export interface ImportOrExportMediaItemSeen { export type MetadataSource = 'anilist' | 'audible' | 'custom' | 'google-books' | 'igdb' | 'itunes' | 'listennotes' | 'manga-updates' | 'mal' | 'openlibrary' | 'tmdb' | 'vndb'; export interface ImportOrExportMediaItem { - /** The collections to add this media to. */ + /** The collections this entity was added to. */ collections: string[]; /** The provider identifier. For eg: TMDB-ID, Openlibrary ID and so on. */ identifier: string; @@ -115,6 +115,8 @@ export interface ImportOrExportMediaItem { } export interface ImportOrExportPersonItem { + /** The collections this entity was added to. */ + collections: string[]; /** The name of the creator. */ name: string; /** The review history for the user. */ diff --git a/libs/generated/src/graphql/backend/gql.ts b/libs/generated/src/graphql/backend/gql.ts index 51776b1345..24b4cbb82e 100644 --- a/libs/generated/src/graphql/backend/gql.ts +++ b/libs/generated/src/graphql/backend/gql.ts @@ -13,7 +13,7 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/ * Therefore it is highly recommended to use the babel or swc plugin for production. */ const documents = { - "mutation AddMediaToCollection($input: AddMediaToCollection!) {\n addMediaToCollection(input: $input)\n}": types.AddMediaToCollectionDocument, + "mutation AddEntityToCollection($input: ChangeCollectionToEntityInput!) {\n addEntityToCollection(input: $input)\n}": types.AddEntityToCollectionDocument, "mutation BulkProgressUpdate($input: [ProgressUpdateInput!]!) {\n bulkProgressUpdate(input: $input)\n}": types.BulkProgressUpdateDocument, "mutation CommitMedia($lot: MetadataLot!, $source: MetadataSource!, $identifier: String!) {\n commitMedia(lot: $lot, source: $source, identifier: $identifier) {\n id\n }\n}": types.CommitMediaDocument, "mutation CreateCustomExercise($input: ExerciseInput!) {\n createCustomExercise(input: $input) {\n id\n }\n}": types.CreateCustomExerciseDocument, @@ -47,15 +47,14 @@ const documents = { "mutation ProgressUpdate($input: ProgressUpdateInput!) {\n progressUpdate(input: $input) {\n ... on IdObject {\n id\n }\n ... on ProgressUpdateError {\n error\n }\n }\n}": types.ProgressUpdateDocument, "mutation RegenerateUserSummary {\n regenerateUserSummary\n}": types.RegenerateUserSummaryDocument, "mutation RegisterUser($input: UserInput!) {\n registerUser(input: $input) {\n __typename\n ... on RegisterError {\n error\n }\n ... on IdObject {\n id\n }\n }\n}": types.RegisterUserDocument, - "mutation RemoveMediaFromCollection($metadataId: Int!, $collectionName: String!) {\n removeMediaFromCollection(\n metadataId: $metadataId\n collectionName: $collectionName\n ) {\n id\n }\n}": types.RemoveMediaFromCollectionDocument, + "mutation RemoveEntityFromCollection($input: ChangeCollectionToEntityInput!) {\n removeEntityFromCollection(input: $input) {\n id\n }\n}": types.RemoveEntityFromCollectionDocument, "mutation TestUserNotificationPlatforms {\n testUserNotificationPlatforms\n}": types.TestUserNotificationPlatformsDocument, "mutation ToggleMediaMonitor($toMonitorMetadataId: Int!) {\n toggleMediaMonitor(toMonitorMetadataId: $toMonitorMetadataId)\n}": types.ToggleMediaMonitorDocument, "mutation UpdateAllMetadata {\n updateAllMetadata\n}": types.UpdateAllMetadataDocument, "mutation UpdateUser($input: UpdateUserInput!) {\n updateUser(input: $input) {\n id\n }\n}": types.UpdateUserDocument, "mutation UpdateUserPreference($input: UpdateUserPreferenceInput!) {\n updateUserPreference(input: $input)\n}": types.UpdateUserPreferenceDocument, "mutation YankIntegrationData {\n yankIntegrationData\n}": types.YankIntegrationDataDocument, - "query CollectionContents($input: CollectionContentsInput!) {\n collectionContents(input: $input) {\n user {\n name\n }\n results {\n details {\n total\n nextPage\n }\n items {\n lot\n details {\n identifier\n title\n image\n publishYear\n }\n }\n }\n details {\n name\n description\n visibility\n createdOn\n }\n }\n}": types.CollectionContentsDocument, - "query Collections($input: CollectionInput) {\n collections(input: $input) {\n id\n name\n description\n visibility\n numItems\n }\n}": types.CollectionsDocument, + "query CollectionContents($input: CollectionContentsInput!) {\n collectionContents(input: $input) {\n user {\n name\n }\n results {\n details {\n total\n nextPage\n }\n items {\n metadataLot\n entityLot\n details {\n identifier\n title\n image\n publishYear\n }\n }\n }\n details {\n name\n description\n visibility\n createdOn\n }\n }\n}": types.CollectionContentsDocument, "query CoreDetails {\n coreDetails {\n version\n authorName\n repositoryLink\n docsLink\n defaultCredentials\n passwordChangeAllowed\n preferencesChangeAllowed\n usernameChangeAllowed\n itemDetailsHeight\n reviewsDisabled\n videosDisabled\n upgrade\n pageLimit\n deployAdminJobsAllowed\n }\n}": types.CoreDetailsDocument, "query CoreEnabledFeatures {\n coreEnabledFeatures {\n fileStorage\n signupAllowed\n }\n}": types.CoreEnabledFeaturesDocument, "query CreatorDetails($creatorId: Int!) {\n creatorDetails(creatorId: $creatorId) {\n sourceUrl\n details {\n id\n name\n source\n description\n birthDate\n deathDate\n place\n website\n gender\n displayImages\n }\n contents {\n name\n items {\n metadataId\n title\n image\n }\n }\n workedOn {\n lot\n source\n identifier\n title\n image\n metadataId\n }\n }\n}": types.CreatorDetailsDocument, @@ -76,19 +75,21 @@ const documents = { "query ProvidersLanguageInformation {\n providersLanguageInformation {\n supported\n default\n source\n }\n}": types.ProvidersLanguageInformationDocument, "query Review($reviewId: Int!) {\n review(reviewId: $reviewId) {\n rating\n text\n visibility\n spoiler\n showSeason\n showEpisode\n podcastEpisode\n }\n}": types.ReviewDocument, "query UserCalendarEvents($input: UserCalendarEventInput!) {\n userCalendarEvents(input: $input) {\n date\n events {\n ...CalendarEventPart\n }\n }\n}": types.UserCalendarEventsDocument, - "query UserCreatorDetails($creatorId: Int!) {\n userCreatorDetails(creatorId: $creatorId) {\n reviews {\n id\n rating\n text\n spoiler\n visibility\n postedOn\n postedBy {\n id\n name\n }\n comments {\n id\n text\n createdOn\n user {\n id\n name\n }\n likedBy\n }\n }\n }\n}": types.UserCreatorDetailsDocument, + "query UserCollectionsList($name: String) {\n userCollectionsList(name: $name) {\n id\n name\n description\n visibility\n numItems\n }\n}": types.UserCollectionsListDocument, + "query UserCreatorDetails($creatorId: Int!) {\n userCreatorDetails(creatorId: $creatorId) {\n collections {\n ...CollectionPart\n }\n reviews {\n ...ReviewItemPart\n }\n }\n}": types.UserCreatorDetailsDocument, "query UserDetails {\n userDetails {\n __typename\n ... on User {\n id\n email\n name\n lot\n }\n }\n}": types.UserDetailsDocument, - "query UserExerciseDetails($input: UserExerciseDetailsInput!) {\n userExerciseDetails(input: $input) {\n history {\n workoutId\n workoutName\n workoutTime\n sets {\n lot\n statistic {\n ...WorkoutSetStatisticPart\n }\n }\n }\n details {\n exerciseId\n numTimesPerformed\n lastUpdatedOn\n extraInformation {\n lifetimeStats {\n weight\n reps\n distance\n duration\n personalBestsAchieved\n }\n personalBests {\n lot\n sets {\n workoutId\n setIdx\n data {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n }\n }\n }\n }\n }\n }\n}": types.UserExerciseDetailsDocument, + "query UserExerciseDetails($input: UserExerciseDetailsInput!) {\n userExerciseDetails(input: $input) {\n collections {\n ...CollectionPart\n }\n history {\n workoutId\n workoutName\n workoutTime\n sets {\n lot\n statistic {\n ...WorkoutSetStatisticPart\n }\n }\n }\n details {\n exerciseId\n numTimesPerformed\n lastUpdatedOn\n extraInformation {\n lifetimeStats {\n weight\n reps\n distance\n duration\n personalBestsAchieved\n }\n personalBests {\n lot\n sets {\n workoutId\n setIdx\n data {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n }\n }\n }\n }\n }\n }\n}": types.UserExerciseDetailsDocument, "query UserIntegrations {\n userIntegrations {\n id\n lot\n description\n timestamp\n slug\n }\n}": types.UserIntegrationsDocument, "query UserMeasurementsList($input: UserMeasurementsListInput!) {\n userMeasurementsList(input: $input) {\n timestamp\n name\n comment\n stats {\n weight\n bodyMassIndex\n totalBodyWater\n muscle\n leanBodyMass\n bodyFat\n boneMass\n visceralFat\n waistCircumference\n waistToHeightRatio\n hipCircumference\n waistToHipRatio\n chestCircumference\n thighCircumference\n bicepsCircumference\n neckCircumference\n bodyFatCaliper\n chestSkinfold\n abdominalSkinfold\n thighSkinfold\n basalMetabolicRate\n totalDailyEnergyExpenditure\n calories\n custom\n }\n }\n}": types.UserMeasurementsListDocument, - "query UserMediaDetails($metadataId: Int!) {\n userMediaDetails(metadataId: $metadataId) {\n collections {\n id\n name\n }\n inProgress {\n ...SeenPart\n }\n history {\n ...SeenPart\n }\n averageRating\n reviews {\n id\n rating\n text\n spoiler\n visibility\n showSeason\n showEpisode\n podcastEpisode\n postedOn\n postedBy {\n id\n name\n }\n comments {\n id\n text\n createdOn\n user {\n id\n name\n }\n likedBy\n }\n }\n reminder {\n remindOn\n message\n }\n isMonitored\n seenBy\n nextEpisode {\n seasonNumber\n episodeNumber\n }\n }\n}": types.UserMediaDetailsDocument, + "query UserMediaDetails($metadataId: Int!) {\n userMediaDetails(metadataId: $metadataId) {\n collections {\n ...CollectionPart\n }\n inProgress {\n ...SeenPart\n }\n history {\n ...SeenPart\n }\n averageRating\n reviews {\n ...ReviewItemPart\n }\n reminder {\n remindOn\n message\n }\n isMonitored\n seenBy\n nextEpisode {\n seasonNumber\n episodeNumber\n }\n }\n}": types.UserMediaDetailsDocument, + "query UserMetadataGroupDetails($metadataGroupId: Int!) {\n userMetadataGroupDetails(metadataGroupId: $metadataGroupId) {\n collections {\n ...CollectionPart\n }\n }\n}": types.UserMetadataGroupDetailsDocument, "query UserNotificationPlatforms {\n userNotificationPlatforms {\n id\n description\n timestamp\n }\n}": types.UserNotificationPlatformsDocument, "query UserPreferences {\n userPreferences {\n general {\n reviewScale\n numGenresDisplay\n displayNsfw\n dashboard {\n section\n hidden\n numElements\n }\n }\n fitness {\n measurements {\n custom {\n name\n dataType\n }\n inbuilt {\n weight\n bodyMassIndex\n totalBodyWater\n muscle\n leanBodyMass\n bodyFat\n boneMass\n visceralFat\n waistCircumference\n waistToHeightRatio\n hipCircumference\n waistToHipRatio\n chestCircumference\n thighCircumference\n bicepsCircumference\n neckCircumference\n bodyFatCaliper\n chestSkinfold\n abdominalSkinfold\n thighSkinfold\n basalMetabolicRate\n totalDailyEnergyExpenditure\n calories\n }\n }\n exercises {\n saveHistory\n unitSystem\n }\n }\n notifications {\n episodeReleased\n episodeNameChanged\n statusChanged\n releaseDateChanged\n numberOfSeasonsChanged\n numberOfChaptersOrEpisodesChanged\n }\n featuresEnabled {\n fitness {\n enabled\n workouts\n measurements\n }\n media {\n enabled\n anime\n audioBook\n book\n manga\n movie\n podcast\n show\n videoGame\n visualNovel\n }\n }\n }\n}": types.UserPreferencesDocument, "query UserUpcomingCalendarEvents($input: UserUpcomingCalendarEventInput!) {\n userUpcomingCalendarEvents(input: $input) {\n ...CalendarEventPart\n }\n}": types.UserUpcomingCalendarEventsDocument, "query UserWorkoutList($page: Int!) {\n userWorkoutList(page: $page) {\n details {\n total\n nextPage\n }\n items {\n id\n name\n startTime\n endTime\n summary {\n ...WorkoutSummaryPart\n }\n }\n }\n}": types.UserWorkoutListDocument, "query UsersList {\n usersList {\n id\n name\n lot\n }\n}": types.UsersListDocument, "query WorkoutDetails($workoutId: String!) {\n workoutDetails(workoutId: $workoutId) {\n name\n comment\n startTime\n endTime\n summary {\n ...WorkoutSummaryPart\n }\n information {\n assets {\n ...EntityAssetsPart\n }\n exercises {\n id\n name\n lot\n notes\n restTime\n total {\n ...WorkoutTotalMeasurementPart\n }\n assets {\n ...EntityAssetsPart\n }\n sets {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n personalBests\n }\n }\n }\n }\n}": types.WorkoutDetailsDocument, - "fragment CalendarEventPart on GraphqlCalendarEvent {\n calendarEventId\n metadataId\n metadataTitle\n metadataLot\n metadataImage\n date\n showSeasonNumber\n showEpisodeNumber\n podcastEpisodeNumber\n}\n\nfragment SeenPart on Seen {\n id\n progress\n state\n startedOn\n finishedOn\n lastUpdatedOn\n numTimesUpdated\n showInformation {\n episode\n season\n }\n podcastInformation {\n episode\n }\n}\n\nfragment PartialMetadataPart on PartialMetadata {\n lot\n source\n identifier\n title\n image\n metadataId\n}\n\nfragment WorkoutTotalMeasurementPart on WorkoutTotalMeasurement {\n personalBestsAchieved\n weight\n reps\n distance\n duration\n}\n\nfragment EntityAssetsPart on EntityAssets {\n images\n videos\n}\n\nfragment WorkoutSetStatisticPart on WorkoutSetStatistic {\n duration\n distance\n reps\n weight\n}\n\nfragment WorkoutSummaryPart on WorkoutSummary {\n total {\n ...WorkoutTotalMeasurementPart\n }\n exercises {\n numSets\n name\n lot\n bestSet {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n personalBests\n }\n }\n}": types.CalendarEventPartFragmentDoc, + "fragment CalendarEventPart on GraphqlCalendarEvent {\n calendarEventId\n metadataId\n metadataTitle\n metadataLot\n metadataImage\n date\n showSeasonNumber\n showEpisodeNumber\n podcastEpisodeNumber\n}\n\nfragment SeenPart on Seen {\n id\n progress\n state\n startedOn\n finishedOn\n lastUpdatedOn\n numTimesUpdated\n showInformation {\n episode\n season\n }\n podcastInformation {\n episode\n }\n}\n\nfragment PartialMetadataPart on PartialMetadata {\n lot\n source\n identifier\n title\n image\n metadataId\n}\n\nfragment WorkoutTotalMeasurementPart on WorkoutTotalMeasurement {\n personalBestsAchieved\n weight\n reps\n distance\n duration\n}\n\nfragment EntityAssetsPart on EntityAssets {\n images\n videos\n}\n\nfragment WorkoutSetStatisticPart on WorkoutSetStatistic {\n duration\n distance\n reps\n weight\n}\n\nfragment WorkoutSummaryPart on WorkoutSummary {\n total {\n ...WorkoutTotalMeasurementPart\n }\n exercises {\n numSets\n name\n lot\n bestSet {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n personalBests\n }\n }\n}\n\nfragment CollectionPart on Collection {\n id\n name\n}\n\nfragment ReviewItemPart on ReviewItem {\n id\n rating\n text\n spoiler\n visibility\n showSeason\n showEpisode\n podcastEpisode\n postedOn\n postedBy {\n id\n name\n }\n comments {\n id\n text\n createdOn\n user {\n id\n name\n }\n likedBy\n }\n}": types.CalendarEventPartFragmentDoc, }; /** @@ -108,7 +109,7 @@ export function graphql(source: string): unknown; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "mutation AddMediaToCollection($input: AddMediaToCollection!) {\n addMediaToCollection(input: $input)\n}"): (typeof documents)["mutation AddMediaToCollection($input: AddMediaToCollection!) {\n addMediaToCollection(input: $input)\n}"]; +export function graphql(source: "mutation AddEntityToCollection($input: ChangeCollectionToEntityInput!) {\n addEntityToCollection(input: $input)\n}"): (typeof documents)["mutation AddEntityToCollection($input: ChangeCollectionToEntityInput!) {\n addEntityToCollection(input: $input)\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -244,7 +245,7 @@ export function graphql(source: "mutation RegisterUser($input: UserInput!) {\n /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "mutation RemoveMediaFromCollection($metadataId: Int!, $collectionName: String!) {\n removeMediaFromCollection(\n metadataId: $metadataId\n collectionName: $collectionName\n ) {\n id\n }\n}"): (typeof documents)["mutation RemoveMediaFromCollection($metadataId: Int!, $collectionName: String!) {\n removeMediaFromCollection(\n metadataId: $metadataId\n collectionName: $collectionName\n ) {\n id\n }\n}"]; +export function graphql(source: "mutation RemoveEntityFromCollection($input: ChangeCollectionToEntityInput!) {\n removeEntityFromCollection(input: $input) {\n id\n }\n}"): (typeof documents)["mutation RemoveEntityFromCollection($input: ChangeCollectionToEntityInput!) {\n removeEntityFromCollection(input: $input) {\n id\n }\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -272,11 +273,7 @@ export function graphql(source: "mutation YankIntegrationData {\n yankIntegrati /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "query CollectionContents($input: CollectionContentsInput!) {\n collectionContents(input: $input) {\n user {\n name\n }\n results {\n details {\n total\n nextPage\n }\n items {\n lot\n details {\n identifier\n title\n image\n publishYear\n }\n }\n }\n details {\n name\n description\n visibility\n createdOn\n }\n }\n}"): (typeof documents)["query CollectionContents($input: CollectionContentsInput!) {\n collectionContents(input: $input) {\n user {\n name\n }\n results {\n details {\n total\n nextPage\n }\n items {\n lot\n details {\n identifier\n title\n image\n publishYear\n }\n }\n }\n details {\n name\n description\n visibility\n createdOn\n }\n }\n}"]; -/** - * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function graphql(source: "query Collections($input: CollectionInput) {\n collections(input: $input) {\n id\n name\n description\n visibility\n numItems\n }\n}"): (typeof documents)["query Collections($input: CollectionInput) {\n collections(input: $input) {\n id\n name\n description\n visibility\n numItems\n }\n}"]; +export function graphql(source: "query CollectionContents($input: CollectionContentsInput!) {\n collectionContents(input: $input) {\n user {\n name\n }\n results {\n details {\n total\n nextPage\n }\n items {\n metadataLot\n entityLot\n details {\n identifier\n title\n image\n publishYear\n }\n }\n }\n details {\n name\n description\n visibility\n createdOn\n }\n }\n}"): (typeof documents)["query CollectionContents($input: CollectionContentsInput!) {\n collectionContents(input: $input) {\n user {\n name\n }\n results {\n details {\n total\n nextPage\n }\n items {\n metadataLot\n entityLot\n details {\n identifier\n title\n image\n publishYear\n }\n }\n }\n details {\n name\n description\n visibility\n createdOn\n }\n }\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -360,7 +357,11 @@ export function graphql(source: "query UserCalendarEvents($input: UserCalendarEv /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "query UserCreatorDetails($creatorId: Int!) {\n userCreatorDetails(creatorId: $creatorId) {\n reviews {\n id\n rating\n text\n spoiler\n visibility\n postedOn\n postedBy {\n id\n name\n }\n comments {\n id\n text\n createdOn\n user {\n id\n name\n }\n likedBy\n }\n }\n }\n}"): (typeof documents)["query UserCreatorDetails($creatorId: Int!) {\n userCreatorDetails(creatorId: $creatorId) {\n reviews {\n id\n rating\n text\n spoiler\n visibility\n postedOn\n postedBy {\n id\n name\n }\n comments {\n id\n text\n createdOn\n user {\n id\n name\n }\n likedBy\n }\n }\n }\n}"]; +export function graphql(source: "query UserCollectionsList($name: String) {\n userCollectionsList(name: $name) {\n id\n name\n description\n visibility\n numItems\n }\n}"): (typeof documents)["query UserCollectionsList($name: String) {\n userCollectionsList(name: $name) {\n id\n name\n description\n visibility\n numItems\n }\n}"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "query UserCreatorDetails($creatorId: Int!) {\n userCreatorDetails(creatorId: $creatorId) {\n collections {\n ...CollectionPart\n }\n reviews {\n ...ReviewItemPart\n }\n }\n}"): (typeof documents)["query UserCreatorDetails($creatorId: Int!) {\n userCreatorDetails(creatorId: $creatorId) {\n collections {\n ...CollectionPart\n }\n reviews {\n ...ReviewItemPart\n }\n }\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -368,7 +369,7 @@ export function graphql(source: "query UserDetails {\n userDetails {\n __typ /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "query UserExerciseDetails($input: UserExerciseDetailsInput!) {\n userExerciseDetails(input: $input) {\n history {\n workoutId\n workoutName\n workoutTime\n sets {\n lot\n statistic {\n ...WorkoutSetStatisticPart\n }\n }\n }\n details {\n exerciseId\n numTimesPerformed\n lastUpdatedOn\n extraInformation {\n lifetimeStats {\n weight\n reps\n distance\n duration\n personalBestsAchieved\n }\n personalBests {\n lot\n sets {\n workoutId\n setIdx\n data {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n }\n }\n }\n }\n }\n }\n}"): (typeof documents)["query UserExerciseDetails($input: UserExerciseDetailsInput!) {\n userExerciseDetails(input: $input) {\n history {\n workoutId\n workoutName\n workoutTime\n sets {\n lot\n statistic {\n ...WorkoutSetStatisticPart\n }\n }\n }\n details {\n exerciseId\n numTimesPerformed\n lastUpdatedOn\n extraInformation {\n lifetimeStats {\n weight\n reps\n distance\n duration\n personalBestsAchieved\n }\n personalBests {\n lot\n sets {\n workoutId\n setIdx\n data {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n }\n }\n }\n }\n }\n }\n}"]; +export function graphql(source: "query UserExerciseDetails($input: UserExerciseDetailsInput!) {\n userExerciseDetails(input: $input) {\n collections {\n ...CollectionPart\n }\n history {\n workoutId\n workoutName\n workoutTime\n sets {\n lot\n statistic {\n ...WorkoutSetStatisticPart\n }\n }\n }\n details {\n exerciseId\n numTimesPerformed\n lastUpdatedOn\n extraInformation {\n lifetimeStats {\n weight\n reps\n distance\n duration\n personalBestsAchieved\n }\n personalBests {\n lot\n sets {\n workoutId\n setIdx\n data {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n }\n }\n }\n }\n }\n }\n}"): (typeof documents)["query UserExerciseDetails($input: UserExerciseDetailsInput!) {\n userExerciseDetails(input: $input) {\n collections {\n ...CollectionPart\n }\n history {\n workoutId\n workoutName\n workoutTime\n sets {\n lot\n statistic {\n ...WorkoutSetStatisticPart\n }\n }\n }\n details {\n exerciseId\n numTimesPerformed\n lastUpdatedOn\n extraInformation {\n lifetimeStats {\n weight\n reps\n distance\n duration\n personalBestsAchieved\n }\n personalBests {\n lot\n sets {\n workoutId\n setIdx\n data {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n }\n }\n }\n }\n }\n }\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -380,7 +381,11 @@ export function graphql(source: "query UserMeasurementsList($input: UserMeasurem /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "query UserMediaDetails($metadataId: Int!) {\n userMediaDetails(metadataId: $metadataId) {\n collections {\n id\n name\n }\n inProgress {\n ...SeenPart\n }\n history {\n ...SeenPart\n }\n averageRating\n reviews {\n id\n rating\n text\n spoiler\n visibility\n showSeason\n showEpisode\n podcastEpisode\n postedOn\n postedBy {\n id\n name\n }\n comments {\n id\n text\n createdOn\n user {\n id\n name\n }\n likedBy\n }\n }\n reminder {\n remindOn\n message\n }\n isMonitored\n seenBy\n nextEpisode {\n seasonNumber\n episodeNumber\n }\n }\n}"): (typeof documents)["query UserMediaDetails($metadataId: Int!) {\n userMediaDetails(metadataId: $metadataId) {\n collections {\n id\n name\n }\n inProgress {\n ...SeenPart\n }\n history {\n ...SeenPart\n }\n averageRating\n reviews {\n id\n rating\n text\n spoiler\n visibility\n showSeason\n showEpisode\n podcastEpisode\n postedOn\n postedBy {\n id\n name\n }\n comments {\n id\n text\n createdOn\n user {\n id\n name\n }\n likedBy\n }\n }\n reminder {\n remindOn\n message\n }\n isMonitored\n seenBy\n nextEpisode {\n seasonNumber\n episodeNumber\n }\n }\n}"]; +export function graphql(source: "query UserMediaDetails($metadataId: Int!) {\n userMediaDetails(metadataId: $metadataId) {\n collections {\n ...CollectionPart\n }\n inProgress {\n ...SeenPart\n }\n history {\n ...SeenPart\n }\n averageRating\n reviews {\n ...ReviewItemPart\n }\n reminder {\n remindOn\n message\n }\n isMonitored\n seenBy\n nextEpisode {\n seasonNumber\n episodeNumber\n }\n }\n}"): (typeof documents)["query UserMediaDetails($metadataId: Int!) {\n userMediaDetails(metadataId: $metadataId) {\n collections {\n ...CollectionPart\n }\n inProgress {\n ...SeenPart\n }\n history {\n ...SeenPart\n }\n averageRating\n reviews {\n ...ReviewItemPart\n }\n reminder {\n remindOn\n message\n }\n isMonitored\n seenBy\n nextEpisode {\n seasonNumber\n episodeNumber\n }\n }\n}"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "query UserMetadataGroupDetails($metadataGroupId: Int!) {\n userMetadataGroupDetails(metadataGroupId: $metadataGroupId) {\n collections {\n ...CollectionPart\n }\n }\n}"): (typeof documents)["query UserMetadataGroupDetails($metadataGroupId: Int!) {\n userMetadataGroupDetails(metadataGroupId: $metadataGroupId) {\n collections {\n ...CollectionPart\n }\n }\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -408,7 +413,7 @@ export function graphql(source: "query WorkoutDetails($workoutId: String!) {\n /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "fragment CalendarEventPart on GraphqlCalendarEvent {\n calendarEventId\n metadataId\n metadataTitle\n metadataLot\n metadataImage\n date\n showSeasonNumber\n showEpisodeNumber\n podcastEpisodeNumber\n}\n\nfragment SeenPart on Seen {\n id\n progress\n state\n startedOn\n finishedOn\n lastUpdatedOn\n numTimesUpdated\n showInformation {\n episode\n season\n }\n podcastInformation {\n episode\n }\n}\n\nfragment PartialMetadataPart on PartialMetadata {\n lot\n source\n identifier\n title\n image\n metadataId\n}\n\nfragment WorkoutTotalMeasurementPart on WorkoutTotalMeasurement {\n personalBestsAchieved\n weight\n reps\n distance\n duration\n}\n\nfragment EntityAssetsPart on EntityAssets {\n images\n videos\n}\n\nfragment WorkoutSetStatisticPart on WorkoutSetStatistic {\n duration\n distance\n reps\n weight\n}\n\nfragment WorkoutSummaryPart on WorkoutSummary {\n total {\n ...WorkoutTotalMeasurementPart\n }\n exercises {\n numSets\n name\n lot\n bestSet {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n personalBests\n }\n }\n}"): (typeof documents)["fragment CalendarEventPart on GraphqlCalendarEvent {\n calendarEventId\n metadataId\n metadataTitle\n metadataLot\n metadataImage\n date\n showSeasonNumber\n showEpisodeNumber\n podcastEpisodeNumber\n}\n\nfragment SeenPart on Seen {\n id\n progress\n state\n startedOn\n finishedOn\n lastUpdatedOn\n numTimesUpdated\n showInformation {\n episode\n season\n }\n podcastInformation {\n episode\n }\n}\n\nfragment PartialMetadataPart on PartialMetadata {\n lot\n source\n identifier\n title\n image\n metadataId\n}\n\nfragment WorkoutTotalMeasurementPart on WorkoutTotalMeasurement {\n personalBestsAchieved\n weight\n reps\n distance\n duration\n}\n\nfragment EntityAssetsPart on EntityAssets {\n images\n videos\n}\n\nfragment WorkoutSetStatisticPart on WorkoutSetStatistic {\n duration\n distance\n reps\n weight\n}\n\nfragment WorkoutSummaryPart on WorkoutSummary {\n total {\n ...WorkoutTotalMeasurementPart\n }\n exercises {\n numSets\n name\n lot\n bestSet {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n personalBests\n }\n }\n}"]; +export function graphql(source: "fragment CalendarEventPart on GraphqlCalendarEvent {\n calendarEventId\n metadataId\n metadataTitle\n metadataLot\n metadataImage\n date\n showSeasonNumber\n showEpisodeNumber\n podcastEpisodeNumber\n}\n\nfragment SeenPart on Seen {\n id\n progress\n state\n startedOn\n finishedOn\n lastUpdatedOn\n numTimesUpdated\n showInformation {\n episode\n season\n }\n podcastInformation {\n episode\n }\n}\n\nfragment PartialMetadataPart on PartialMetadata {\n lot\n source\n identifier\n title\n image\n metadataId\n}\n\nfragment WorkoutTotalMeasurementPart on WorkoutTotalMeasurement {\n personalBestsAchieved\n weight\n reps\n distance\n duration\n}\n\nfragment EntityAssetsPart on EntityAssets {\n images\n videos\n}\n\nfragment WorkoutSetStatisticPart on WorkoutSetStatistic {\n duration\n distance\n reps\n weight\n}\n\nfragment WorkoutSummaryPart on WorkoutSummary {\n total {\n ...WorkoutTotalMeasurementPart\n }\n exercises {\n numSets\n name\n lot\n bestSet {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n personalBests\n }\n }\n}\n\nfragment CollectionPart on Collection {\n id\n name\n}\n\nfragment ReviewItemPart on ReviewItem {\n id\n rating\n text\n spoiler\n visibility\n showSeason\n showEpisode\n podcastEpisode\n postedOn\n postedBy {\n id\n name\n }\n comments {\n id\n text\n createdOn\n user {\n id\n name\n }\n likedBy\n }\n}"): (typeof documents)["fragment CalendarEventPart on GraphqlCalendarEvent {\n calendarEventId\n metadataId\n metadataTitle\n metadataLot\n metadataImage\n date\n showSeasonNumber\n showEpisodeNumber\n podcastEpisodeNumber\n}\n\nfragment SeenPart on Seen {\n id\n progress\n state\n startedOn\n finishedOn\n lastUpdatedOn\n numTimesUpdated\n showInformation {\n episode\n season\n }\n podcastInformation {\n episode\n }\n}\n\nfragment PartialMetadataPart on PartialMetadata {\n lot\n source\n identifier\n title\n image\n metadataId\n}\n\nfragment WorkoutTotalMeasurementPart on WorkoutTotalMeasurement {\n personalBestsAchieved\n weight\n reps\n distance\n duration\n}\n\nfragment EntityAssetsPart on EntityAssets {\n images\n videos\n}\n\nfragment WorkoutSetStatisticPart on WorkoutSetStatistic {\n duration\n distance\n reps\n weight\n}\n\nfragment WorkoutSummaryPart on WorkoutSummary {\n total {\n ...WorkoutTotalMeasurementPart\n }\n exercises {\n numSets\n name\n lot\n bestSet {\n statistic {\n ...WorkoutSetStatisticPart\n }\n lot\n personalBests\n }\n }\n}\n\nfragment CollectionPart on Collection {\n id\n name\n}\n\nfragment ReviewItemPart on ReviewItem {\n id\n rating\n text\n spoiler\n visibility\n showSeason\n showEpisode\n podcastEpisode\n postedOn\n postedBy {\n id\n name\n }\n comments {\n id\n text\n createdOn\n user {\n id\n name\n }\n likedBy\n }\n}"]; export function graphql(source: string) { return (documents as any)[source] ?? {}; diff --git a/libs/generated/src/graphql/backend/graphql.ts b/libs/generated/src/graphql/backend/graphql.ts index e21b2229cd..6cc1abb53f 100644 --- a/libs/generated/src/graphql/backend/graphql.ts +++ b/libs/generated/src/graphql/backend/graphql.ts @@ -35,11 +35,6 @@ export type Scalars = { NaiveDate: { input: string; output: string; } }; -export type AddMediaToCollection = { - collectionName: Scalars['String']['input']; - mediaId: Scalars['Int']['input']; -}; - export type AnimeSpecifics = { episodes?: Maybe; }; @@ -79,6 +74,12 @@ export type BooksSummary = { read: Scalars['Int']['output']; }; +export type ChangeCollectionToEntityInput = { + collectionName: Scalars['String']['input']; + entityId: Scalars['Int']['input']; + entityLot: EntityLot; +}; + export type Collection = { createdOn: Scalars['DateTime']['output']; description?: Maybe; @@ -99,10 +100,6 @@ export type CollectionContentsInput = { take?: InputMaybe; }; -export type CollectionInput = { - name?: InputMaybe; -}; - export type CollectionItem = { description?: Maybe; id: Scalars['Int']['output']; @@ -306,6 +303,13 @@ export type EntityAssetsInput = { videos: Array; }; +export enum EntityLot { + Exercise = 'EXERCISE', + Metadata = 'METADATA', + MetadataGroup = 'METADATA_GROUP', + Person = 'PERSON' +} + export type Exercise = { attributes: ExerciseAttributes; equipment?: Maybe; @@ -709,7 +713,8 @@ export type MediaSearchItemResponse = { export type MediaSearchItemWithLot = { details: MediaSearchItem; - lot: MetadataLot; + entityLot: EntityLot; + metadataLot?: Maybe; }; export type MediaSearchResults = { @@ -819,8 +824,8 @@ export type MoviesSummary = { }; export type MutationRoot = { - /** Add a media item to a collection if it is not there, otherwise do nothing. */ - addMediaToCollection: Scalars['Boolean']['output']; + /** Add a entity to a collection if it is not there, otherwise do nothing. */ + addEntityToCollection: Scalars['Boolean']['output']; /** Update progress in bulk. */ bulkProgressUpdate: Scalars['Boolean']['output']; /** Fetch details about a media and create a media item in the database. */ @@ -894,8 +899,8 @@ export type MutationRoot = { * they are the first user. */ registerUser: RegisterResult; - /** Remove a media item from a collection if it is not there, otherwise do nothing. */ - removeMediaFromCollection: IdObject; + /** Remove an entity from a collection if it is not there, otherwise do nothing. */ + removeEntityFromCollection: IdObject; /** Test all notification platforms for the currently logged in user. */ testUserNotificationPlatforms: Scalars['Boolean']['output']; /** Toggle the monitor on a media for a user. */ @@ -911,8 +916,8 @@ export type MutationRoot = { }; -export type MutationRootAddMediaToCollectionArgs = { - input: AddMediaToCollection; +export type MutationRootAddEntityToCollectionArgs = { + input: ChangeCollectionToEntityInput; }; @@ -1065,9 +1070,8 @@ export type MutationRootRegisterUserArgs = { }; -export type MutationRootRemoveMediaFromCollectionArgs = { - collectionName: Scalars['String']['input']; - metadataId: Scalars['Int']['input']; +export type MutationRootRemoveEntityFromCollectionArgs = { + input: ChangeCollectionToEntityInput; }; @@ -1208,8 +1212,6 @@ export type ProviderLanguageInformation = { export type QueryRoot = { /** Get the contents of a collection and respect visibility. */ collectionContents: CollectionContents; - /** Get all collections for the currently logged in user. */ - collections: Array; /** Get some primary information about the service. */ coreDetails: CoreDetails; /** Get all the features that are enabled for the service */ @@ -1248,18 +1250,22 @@ export type QueryRoot = { review: ReviewItem; /** Get calendar events for a user between a given date range. */ userCalendarEvents: Array; + /** Get all collections for the currently logged in user. */ + userCollectionsList: Array; /** Get details that can be displayed to a user for a creator. */ userCreatorDetails: UserCreatorDetails; /** Get details about the currently logged in user. */ userDetails: UserDetailsResult; /** Get information about an exercise for a user. */ - userExerciseDetails?: Maybe; + userExerciseDetails: UserExerciseDetails; /** Get all the integrations for the currently logged in user. */ userIntegrations: Array; /** Get all the measurements for a user. */ userMeasurementsList: Array; /** Get details that can be displayed to a user for a media. */ userMediaDetails: UserMediaDetails; + /** Get details that can be displayed to a user for a metadata group. */ + userMetadataGroupDetails: UserMetadataGroupDetails; /** Get all the notification platforms for the currently logged in user. */ userNotificationPlatforms: Array; /** Get a user's preferences. */ @@ -1280,11 +1286,6 @@ export type QueryRootCollectionContentsArgs = { }; -export type QueryRootCollectionsArgs = { - input?: InputMaybe; -}; - - export type QueryRootCreatorDetailsArgs = { creatorId: Scalars['Int']['input']; }; @@ -1352,6 +1353,11 @@ export type QueryRootUserCalendarEventsArgs = { }; +export type QueryRootUserCollectionsListArgs = { + name?: InputMaybe; +}; + + export type QueryRootUserCreatorDetailsArgs = { creatorId: Scalars['Int']['input']; }; @@ -1372,6 +1378,11 @@ export type QueryRootUserMediaDetailsArgs = { }; +export type QueryRootUserMetadataGroupDetailsArgs = { + metadataGroupId: Scalars['Int']['input']; +}; + + export type QueryRootUserUpcomingCalendarEventsArgs = { input: UserUpcomingCalendarEventInput; }; @@ -1572,6 +1583,7 @@ export type UserCalendarEventInput = { }; export type UserCreatorDetails = { + collections: Array; reviews: Array; }; @@ -1595,8 +1607,9 @@ export enum UserDetailsErrorVariant { export type UserDetailsResult = User | UserDetailsError; export type UserExerciseDetails = { - details: UserToExercise; - history: Array; + collections: Array; + details?: Maybe; + history?: Maybe>; }; export type UserExerciseDetailsInput = { @@ -1848,6 +1861,10 @@ export type UserMediaSummary = { visualNovels: VisualNovelsSummary; }; +export type UserMetadataGroupDetails = { + collections: Array; +}; + export enum UserNotificationSettingKind { Apprise = 'APPRISE', Discord = 'DISCORD', @@ -1979,7 +1996,6 @@ export type Workout = { id: Scalars['String']['output']; information: WorkoutInformation; name: Scalars['String']['output']; - processed: Scalars['Boolean']['output']; startTime: Scalars['DateTime']['output']; summary: WorkoutSummary; }; @@ -2050,12 +2066,12 @@ export type WorkoutTotalMeasurement = { weight: Scalars['Decimal']['output']; }; -export type AddMediaToCollectionMutationVariables = Exact<{ - input: AddMediaToCollection; +export type AddEntityToCollectionMutationVariables = Exact<{ + input: ChangeCollectionToEntityInput; }>; -export type AddMediaToCollectionMutation = { addMediaToCollection: boolean }; +export type AddEntityToCollectionMutation = { addEntityToCollection: boolean }; export type BulkProgressUpdateMutationVariables = Exact<{ input: Array | ProgressUpdateInput; @@ -2284,13 +2300,12 @@ export type RegisterUserMutationVariables = Exact<{ export type RegisterUserMutation = { registerUser: { __typename: 'IdObject', id: number } | { __typename: 'RegisterError', error: RegisterErrorVariant } }; -export type RemoveMediaFromCollectionMutationVariables = Exact<{ - metadataId: Scalars['Int']['input']; - collectionName: Scalars['String']['input']; +export type RemoveEntityFromCollectionMutationVariables = Exact<{ + input: ChangeCollectionToEntityInput; }>; -export type RemoveMediaFromCollectionMutation = { removeMediaFromCollection: { id: number } }; +export type RemoveEntityFromCollectionMutation = { removeEntityFromCollection: { id: number } }; export type TestUserNotificationPlatformsMutationVariables = Exact<{ [key: string]: never; }>; @@ -2333,14 +2348,7 @@ export type CollectionContentsQueryVariables = Exact<{ }>; -export type CollectionContentsQuery = { collectionContents: { user: { name: string }, results: { details: { total: number, nextPage?: number | null }, items: Array<{ lot: MetadataLot, details: { identifier: string, title: string, image?: string | null, publishYear?: number | null } }> }, details: { name: string, description?: string | null, visibility: Visibility, createdOn: Date } } }; - -export type CollectionsQueryVariables = Exact<{ - input?: InputMaybe; -}>; - - -export type CollectionsQuery = { collections: Array<{ id: number, name: string, description?: string | null, visibility: Visibility, numItems: number }> }; +export type CollectionContentsQuery = { collectionContents: { user: { name: string }, results: { details: { total: number, nextPage?: number | null }, items: Array<{ metadataLot?: MetadataLot | null, entityLot: EntityLot, details: { identifier: string, title: string, image?: string | null, publishYear?: number | null } }> }, details: { name: string, description?: string | null, visibility: Visibility, createdOn: Date } } }; export type CoreDetailsQueryVariables = Exact<{ [key: string]: never; }>; @@ -2472,12 +2480,19 @@ export type UserCalendarEventsQueryVariables = Exact<{ export type UserCalendarEventsQuery = { userCalendarEvents: Array<{ date: string, events: Array<{ calendarEventId: number, metadataId: number, metadataTitle: string, metadataLot: MetadataLot, metadataImage?: string | null, date: string, showSeasonNumber?: number | null, showEpisodeNumber?: number | null, podcastEpisodeNumber?: number | null }> }> }; +export type UserCollectionsListQueryVariables = Exact<{ + name?: InputMaybe; +}>; + + +export type UserCollectionsListQuery = { userCollectionsList: Array<{ id: number, name: string, description?: string | null, visibility: Visibility, numItems: number }> }; + export type UserCreatorDetailsQueryVariables = Exact<{ creatorId: Scalars['Int']['input']; }>; -export type UserCreatorDetailsQuery = { userCreatorDetails: { reviews: Array<{ id: number, rating?: string | null, text?: string | null, spoiler: boolean, visibility: Visibility, postedOn: Date, postedBy: { id: number, name: string }, comments: Array<{ id: string, text: string, createdOn: Date, likedBy: Array, user: { id: number, name: string } }> }> } }; +export type UserCreatorDetailsQuery = { userCreatorDetails: { collections: Array<{ id: number, name: string }>, reviews: Array<{ id: number, rating?: string | null, text?: string | null, spoiler: boolean, visibility: Visibility, showSeason?: number | null, showEpisode?: number | null, podcastEpisode?: number | null, postedOn: Date, postedBy: { id: number, name: string }, comments: Array<{ id: string, text: string, createdOn: Date, likedBy: Array, user: { id: number, name: string } }> }> } }; export type UserDetailsQueryVariables = Exact<{ [key: string]: never; }>; @@ -2489,7 +2504,7 @@ export type UserExerciseDetailsQueryVariables = Exact<{ }>; -export type UserExerciseDetailsQuery = { userExerciseDetails?: { history: Array<{ workoutId: string, workoutName: string, workoutTime: Date, sets: Array<{ lot: SetLot, statistic: { duration?: string | null, distance?: string | null, reps?: number | null, weight?: string | null } }> }>, details: { exerciseId: number, numTimesPerformed: number, lastUpdatedOn: Date, extraInformation: { lifetimeStats: { weight: string, reps: number, distance: string, duration: string, personalBestsAchieved: number }, personalBests: Array<{ lot: WorkoutSetPersonalBest, sets: Array<{ workoutId: string, setIdx: number, data: { lot: SetLot, statistic: { duration?: string | null, distance?: string | null, reps?: number | null, weight?: string | null } } }> }> } } } | null }; +export type UserExerciseDetailsQuery = { userExerciseDetails: { collections: Array<{ id: number, name: string }>, history?: Array<{ workoutId: string, workoutName: string, workoutTime: Date, sets: Array<{ lot: SetLot, statistic: { duration?: string | null, distance?: string | null, reps?: number | null, weight?: string | null } }> }> | null, details?: { exerciseId: number, numTimesPerformed: number, lastUpdatedOn: Date, extraInformation: { lifetimeStats: { weight: string, reps: number, distance: string, duration: string, personalBestsAchieved: number }, personalBests: Array<{ lot: WorkoutSetPersonalBest, sets: Array<{ workoutId: string, setIdx: number, data: { lot: SetLot, statistic: { duration?: string | null, distance?: string | null, reps?: number | null, weight?: string | null } } }> }> } } | null } }; export type UserIntegrationsQueryVariables = Exact<{ [key: string]: never; }>; @@ -2510,6 +2525,13 @@ export type UserMediaDetailsQueryVariables = Exact<{ export type UserMediaDetailsQuery = { userMediaDetails: { averageRating?: string | null, isMonitored: boolean, seenBy: number, collections: Array<{ id: number, name: string }>, inProgress?: { id: number, progress: number, state: SeenState, startedOn?: string | null, finishedOn?: string | null, lastUpdatedOn: Date, numTimesUpdated?: number | null, showInformation?: { episode: number, season: number } | null, podcastInformation?: { episode: number } | null } | null, history: Array<{ id: number, progress: number, state: SeenState, startedOn?: string | null, finishedOn?: string | null, lastUpdatedOn: Date, numTimesUpdated?: number | null, showInformation?: { episode: number, season: number } | null, podcastInformation?: { episode: number } | null }>, reviews: Array<{ id: number, rating?: string | null, text?: string | null, spoiler: boolean, visibility: Visibility, showSeason?: number | null, showEpisode?: number | null, podcastEpisode?: number | null, postedOn: Date, postedBy: { id: number, name: string }, comments: Array<{ id: string, text: string, createdOn: Date, likedBy: Array, user: { id: number, name: string } }> }>, reminder?: { remindOn: string, message: string } | null, nextEpisode?: { seasonNumber?: number | null, episodeNumber?: number | null } | null } }; +export type UserMetadataGroupDetailsQueryVariables = Exact<{ + metadataGroupId: Scalars['Int']['input']; +}>; + + +export type UserMetadataGroupDetailsQuery = { userMetadataGroupDetails: { collections: Array<{ id: number, name: string }> } }; + export type UserNotificationPlatformsQueryVariables = Exact<{ [key: string]: never; }>; @@ -2560,6 +2582,10 @@ export type WorkoutSetStatisticPartFragment = { duration?: string | null, distan export type WorkoutSummaryPartFragment = { total: { personalBestsAchieved: number, weight: string, reps: number, distance: string, duration: string }, exercises: Array<{ numSets: number, name: string, lot: ExerciseLot, bestSet: { lot: SetLot, personalBests: Array, statistic: { duration?: string | null, distance?: string | null, reps?: number | null, weight?: string | null } } }> }; +export type CollectionPartFragment = { id: number, name: string }; + +export type ReviewItemPartFragment = { id: number, rating?: string | null, text?: string | null, spoiler: boolean, visibility: Visibility, showSeason?: number | null, showEpisode?: number | null, podcastEpisode?: number | null, postedOn: Date, postedBy: { id: number, name: string }, comments: Array<{ id: string, text: string, createdOn: Date, likedBy: Array, user: { id: number, name: string } }> }; + export const CalendarEventPartFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CalendarEventPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"GraphqlCalendarEvent"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"calendarEventId"}},{"kind":"Field","name":{"kind":"Name","value":"metadataId"}},{"kind":"Field","name":{"kind":"Name","value":"metadataTitle"}},{"kind":"Field","name":{"kind":"Name","value":"metadataLot"}},{"kind":"Field","name":{"kind":"Name","value":"metadataImage"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"showSeasonNumber"}},{"kind":"Field","name":{"kind":"Name","value":"showEpisodeNumber"}},{"kind":"Field","name":{"kind":"Name","value":"podcastEpisodeNumber"}}]}}]} as unknown as DocumentNode; export const SeenPartFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Seen"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"progress"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"startedOn"}},{"kind":"Field","name":{"kind":"Name","value":"finishedOn"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdatedOn"}},{"kind":"Field","name":{"kind":"Name","value":"numTimesUpdated"}},{"kind":"Field","name":{"kind":"Name","value":"showInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}},{"kind":"Field","name":{"kind":"Name","value":"season"}}]}},{"kind":"Field","name":{"kind":"Name","value":"podcastInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}}]}}]} as unknown as DocumentNode; export const PartialMetadataPartFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PartialMetadataPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PartialMetadata"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"metadataId"}}]}}]} as unknown as DocumentNode; @@ -2567,7 +2593,9 @@ export const EntityAssetsPartFragmentDoc = {"kind":"Document","definitions":[{"k export const WorkoutTotalMeasurementPartFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutTotalMeasurementPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutTotalMeasurement"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"personalBestsAchieved"}},{"kind":"Field","name":{"kind":"Name","value":"weight"}},{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}}]} as unknown as DocumentNode; export const WorkoutSetStatisticPartFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutSetStatisticPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutSetStatistic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}},{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"weight"}}]}}]} as unknown as DocumentNode; export const WorkoutSummaryPartFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutSummaryPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutSummary"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutTotalMeasurementPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"exercises"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"numSets"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"bestSet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"statistic"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSetStatisticPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"personalBests"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutTotalMeasurementPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutTotalMeasurement"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"personalBestsAchieved"}},{"kind":"Field","name":{"kind":"Name","value":"weight"}},{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutSetStatisticPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutSetStatistic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}},{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"weight"}}]}}]} as unknown as DocumentNode; -export const AddMediaToCollectionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"AddMediaToCollection"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AddMediaToCollection"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addMediaToCollection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode; +export const CollectionPartFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CollectionPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Collection"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]} as unknown as DocumentNode; +export const ReviewItemPartFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ReviewItemPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ReviewItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"spoiler"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"showSeason"}},{"kind":"Field","name":{"kind":"Name","value":"showEpisode"}},{"kind":"Field","name":{"kind":"Name","value":"podcastEpisode"}},{"kind":"Field","name":{"kind":"Name","value":"postedOn"}},{"kind":"Field","name":{"kind":"Name","value":"postedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"likedBy"}}]}}]}}]} as unknown as DocumentNode; +export const AddEntityToCollectionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"AddEntityToCollection"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ChangeCollectionToEntityInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addEntityToCollection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode; export const BulkProgressUpdateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"BulkProgressUpdate"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ProgressUpdateInput"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"bulkProgressUpdate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode; export const CommitMediaDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CommitMedia"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"lot"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"MetadataLot"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"source"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"MetadataSource"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"commitMedia"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"lot"},"value":{"kind":"Variable","name":{"kind":"Name","value":"lot"}}},{"kind":"Argument","name":{"kind":"Name","value":"source"},"value":{"kind":"Variable","name":{"kind":"Name","value":"source"}}},{"kind":"Argument","name":{"kind":"Name","value":"identifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; export const CreateCustomExerciseDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateCustomExercise"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ExerciseInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createCustomExercise"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; @@ -2601,15 +2629,14 @@ export const PresignedPutS3UrlDocument = {"kind":"Document","definitions":[{"kin export const ProgressUpdateDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ProgressUpdate"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ProgressUpdateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"progressUpdate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"IdObject"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ProgressUpdateError"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}}]}}]}}]}}]} as unknown as DocumentNode; export const RegenerateUserSummaryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RegenerateUserSummary"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"regenerateUserSummary"}}]}}]} as unknown as DocumentNode; export const RegisterUserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RegisterUser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"registerUser"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"RegisterError"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"error"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"IdObject"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; -export const RemoveMediaFromCollectionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RemoveMediaFromCollection"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionName"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"removeMediaFromCollection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"metadataId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionName"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; +export const RemoveEntityFromCollectionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RemoveEntityFromCollection"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ChangeCollectionToEntityInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"removeEntityFromCollection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; export const TestUserNotificationPlatformsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"TestUserNotificationPlatforms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"testUserNotificationPlatforms"}}]}}]} as unknown as DocumentNode; export const ToggleMediaMonitorDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ToggleMediaMonitor"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"toMonitorMetadataId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"toggleMediaMonitor"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"toMonitorMetadataId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"toMonitorMetadataId"}}}]}]}}]} as unknown as DocumentNode; export const UpdateAllMetadataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateAllMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateAllMetadata"}}]}}]} as unknown as DocumentNode; export const UpdateUserDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateUser"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateUserInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateUser"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; export const UpdateUserPreferenceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateUserPreference"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateUserPreferenceInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateUserPreference"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode; export const YankIntegrationDataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"YankIntegrationData"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"yankIntegrationData"}}]}}]} as unknown as DocumentNode; -export const CollectionContentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CollectionContents"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CollectionContentsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collectionContents"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"results"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"publishYear"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}}]}}]}}]}}]} as unknown as DocumentNode; -export const CollectionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Collections"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"CollectionInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collections"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"numItems"}}]}}]}}]} as unknown as DocumentNode; +export const CollectionContentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CollectionContents"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CollectionContentsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collectionContents"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"results"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"nextPage"}}]}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataLot"}},{"kind":"Field","name":{"kind":"Name","value":"entityLot"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"publishYear"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}}]}}]}}]}}]} as unknown as DocumentNode; export const CoreDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CoreDetails"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"coreDetails"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"authorName"}},{"kind":"Field","name":{"kind":"Name","value":"repositoryLink"}},{"kind":"Field","name":{"kind":"Name","value":"docsLink"}},{"kind":"Field","name":{"kind":"Name","value":"defaultCredentials"}},{"kind":"Field","name":{"kind":"Name","value":"passwordChangeAllowed"}},{"kind":"Field","name":{"kind":"Name","value":"preferencesChangeAllowed"}},{"kind":"Field","name":{"kind":"Name","value":"usernameChangeAllowed"}},{"kind":"Field","name":{"kind":"Name","value":"itemDetailsHeight"}},{"kind":"Field","name":{"kind":"Name","value":"reviewsDisabled"}},{"kind":"Field","name":{"kind":"Name","value":"videosDisabled"}},{"kind":"Field","name":{"kind":"Name","value":"upgrade"}},{"kind":"Field","name":{"kind":"Name","value":"pageLimit"}},{"kind":"Field","name":{"kind":"Name","value":"deployAdminJobsAllowed"}}]}}]}}]} as unknown as DocumentNode; export const CoreEnabledFeaturesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CoreEnabledFeatures"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"coreEnabledFeatures"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fileStorage"}},{"kind":"Field","name":{"kind":"Name","value":"signupAllowed"}}]}}]}}]} as unknown as DocumentNode; export const CreatorDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"CreatorDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"creatorId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"creatorDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"creatorId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"creatorId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sourceUrl"}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"birthDate"}},{"kind":"Field","name":{"kind":"Name","value":"deathDate"}},{"kind":"Field","name":{"kind":"Name","value":"place"}},{"kind":"Field","name":{"kind":"Name","value":"website"}},{"kind":"Field","name":{"kind":"Name","value":"gender"}},{"kind":"Field","name":{"kind":"Name","value":"displayImages"}}]}},{"kind":"Field","name":{"kind":"Name","value":"contents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"metadataId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"image"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"workedOn"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"source"}},{"kind":"Field","name":{"kind":"Name","value":"identifier"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"image"}},{"kind":"Field","name":{"kind":"Name","value":"metadataId"}}]}}]}}]}}]} as unknown as DocumentNode; @@ -2630,12 +2657,14 @@ export const MetadataGroupsListDocument = {"kind":"Document","definitions":[{"ki export const ProvidersLanguageInformationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProvidersLanguageInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"providersLanguageInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"supported"}},{"kind":"Field","name":{"kind":"Name","value":"default"}},{"kind":"Field","name":{"kind":"Name","value":"source"}}]}}]}}]} as unknown as DocumentNode; export const ReviewDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Review"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"reviewId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"review"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"reviewId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"reviewId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"spoiler"}},{"kind":"Field","name":{"kind":"Name","value":"showSeason"}},{"kind":"Field","name":{"kind":"Name","value":"showEpisode"}},{"kind":"Field","name":{"kind":"Name","value":"podcastEpisode"}}]}}]}}]} as unknown as DocumentNode; export const UserCalendarEventsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserCalendarEvents"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserCalendarEventInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userCalendarEvents"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"events"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CalendarEventPart"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CalendarEventPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"GraphqlCalendarEvent"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"calendarEventId"}},{"kind":"Field","name":{"kind":"Name","value":"metadataId"}},{"kind":"Field","name":{"kind":"Name","value":"metadataTitle"}},{"kind":"Field","name":{"kind":"Name","value":"metadataLot"}},{"kind":"Field","name":{"kind":"Name","value":"metadataImage"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"showSeasonNumber"}},{"kind":"Field","name":{"kind":"Name","value":"showEpisodeNumber"}},{"kind":"Field","name":{"kind":"Name","value":"podcastEpisodeNumber"}}]}}]} as unknown as DocumentNode; -export const UserCreatorDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserCreatorDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"creatorId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userCreatorDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"creatorId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"creatorId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"reviews"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"spoiler"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"postedOn"}},{"kind":"Field","name":{"kind":"Name","value":"postedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"likedBy"}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const UserCollectionsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserCollectionsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userCollectionsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"numItems"}}]}}]}}]} as unknown as DocumentNode; +export const UserCreatorDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserCreatorDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"creatorId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userCreatorDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"creatorId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"creatorId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CollectionPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"reviews"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ReviewItemPart"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CollectionPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Collection"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ReviewItemPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ReviewItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"spoiler"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"showSeason"}},{"kind":"Field","name":{"kind":"Name","value":"showEpisode"}},{"kind":"Field","name":{"kind":"Name","value":"podcastEpisode"}},{"kind":"Field","name":{"kind":"Name","value":"postedOn"}},{"kind":"Field","name":{"kind":"Name","value":"postedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"likedBy"}}]}}]}}]} as unknown as DocumentNode; export const UserDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserDetails"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userDetails"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}}]}}]}}]}}]} as unknown as DocumentNode; -export const UserExerciseDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserExerciseDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserExerciseDetailsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userExerciseDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"history"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workoutId"}},{"kind":"Field","name":{"kind":"Name","value":"workoutName"}},{"kind":"Field","name":{"kind":"Name","value":"workoutTime"}},{"kind":"Field","name":{"kind":"Name","value":"sets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"statistic"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSetStatisticPart"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"exerciseId"}},{"kind":"Field","name":{"kind":"Name","value":"numTimesPerformed"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdatedOn"}},{"kind":"Field","name":{"kind":"Name","value":"extraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lifetimeStats"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"weight"}},{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"personalBestsAchieved"}}]}},{"kind":"Field","name":{"kind":"Name","value":"personalBests"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"sets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workoutId"}},{"kind":"Field","name":{"kind":"Name","value":"setIdx"}},{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"statistic"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSetStatisticPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lot"}}]}}]}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutSetStatisticPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutSetStatistic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}},{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"weight"}}]}}]} as unknown as DocumentNode; +export const UserExerciseDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserExerciseDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserExerciseDetailsInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userExerciseDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CollectionPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"history"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workoutId"}},{"kind":"Field","name":{"kind":"Name","value":"workoutName"}},{"kind":"Field","name":{"kind":"Name","value":"workoutTime"}},{"kind":"Field","name":{"kind":"Name","value":"sets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"statistic"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSetStatisticPart"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"details"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"exerciseId"}},{"kind":"Field","name":{"kind":"Name","value":"numTimesPerformed"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdatedOn"}},{"kind":"Field","name":{"kind":"Name","value":"extraInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lifetimeStats"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"weight"}},{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"personalBestsAchieved"}}]}},{"kind":"Field","name":{"kind":"Name","value":"personalBests"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"sets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"workoutId"}},{"kind":"Field","name":{"kind":"Name","value":"setIdx"}},{"kind":"Field","name":{"kind":"Name","value":"data"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"statistic"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"WorkoutSetStatisticPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"lot"}}]}}]}}]}}]}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CollectionPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Collection"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"WorkoutSetStatisticPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkoutSetStatistic"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"distance"}},{"kind":"Field","name":{"kind":"Name","value":"reps"}},{"kind":"Field","name":{"kind":"Name","value":"weight"}}]}}]} as unknown as DocumentNode; export const UserIntegrationsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserIntegrations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userIntegrations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lot"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"timestamp"}},{"kind":"Field","name":{"kind":"Name","value":"slug"}}]}}]}}]} as unknown as DocumentNode; export const UserMeasurementsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserMeasurementsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserMeasurementsListInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userMeasurementsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"timestamp"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"comment"}},{"kind":"Field","name":{"kind":"Name","value":"stats"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"weight"}},{"kind":"Field","name":{"kind":"Name","value":"bodyMassIndex"}},{"kind":"Field","name":{"kind":"Name","value":"totalBodyWater"}},{"kind":"Field","name":{"kind":"Name","value":"muscle"}},{"kind":"Field","name":{"kind":"Name","value":"leanBodyMass"}},{"kind":"Field","name":{"kind":"Name","value":"bodyFat"}},{"kind":"Field","name":{"kind":"Name","value":"boneMass"}},{"kind":"Field","name":{"kind":"Name","value":"visceralFat"}},{"kind":"Field","name":{"kind":"Name","value":"waistCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"waistToHeightRatio"}},{"kind":"Field","name":{"kind":"Name","value":"hipCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"waistToHipRatio"}},{"kind":"Field","name":{"kind":"Name","value":"chestCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"thighCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"bicepsCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"neckCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"bodyFatCaliper"}},{"kind":"Field","name":{"kind":"Name","value":"chestSkinfold"}},{"kind":"Field","name":{"kind":"Name","value":"abdominalSkinfold"}},{"kind":"Field","name":{"kind":"Name","value":"thighSkinfold"}},{"kind":"Field","name":{"kind":"Name","value":"basalMetabolicRate"}},{"kind":"Field","name":{"kind":"Name","value":"totalDailyEnergyExpenditure"}},{"kind":"Field","name":{"kind":"Name","value":"calories"}},{"kind":"Field","name":{"kind":"Name","value":"custom"}}]}}]}}]}}]} as unknown as DocumentNode; -export const UserMediaDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserMediaDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userMediaDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"metadataId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"inProgress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"history"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"averageRating"}},{"kind":"Field","name":{"kind":"Name","value":"reviews"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"spoiler"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"showSeason"}},{"kind":"Field","name":{"kind":"Name","value":"showEpisode"}},{"kind":"Field","name":{"kind":"Name","value":"podcastEpisode"}},{"kind":"Field","name":{"kind":"Name","value":"postedOn"}},{"kind":"Field","name":{"kind":"Name","value":"postedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"likedBy"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"reminder"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"remindOn"}},{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isMonitored"}},{"kind":"Field","name":{"kind":"Name","value":"seenBy"}},{"kind":"Field","name":{"kind":"Name","value":"nextEpisode"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"seasonNumber"}},{"kind":"Field","name":{"kind":"Name","value":"episodeNumber"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Seen"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"progress"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"startedOn"}},{"kind":"Field","name":{"kind":"Name","value":"finishedOn"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdatedOn"}},{"kind":"Field","name":{"kind":"Name","value":"numTimesUpdated"}},{"kind":"Field","name":{"kind":"Name","value":"showInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}},{"kind":"Field","name":{"kind":"Name","value":"season"}}]}},{"kind":"Field","name":{"kind":"Name","value":"podcastInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}}]}}]} as unknown as DocumentNode; +export const UserMediaDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserMediaDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userMediaDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"metadataId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"metadataId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CollectionPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"inProgress"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"history"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SeenPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"averageRating"}},{"kind":"Field","name":{"kind":"Name","value":"reviews"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ReviewItemPart"}}]}},{"kind":"Field","name":{"kind":"Name","value":"reminder"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"remindOn"}},{"kind":"Field","name":{"kind":"Name","value":"message"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isMonitored"}},{"kind":"Field","name":{"kind":"Name","value":"seenBy"}},{"kind":"Field","name":{"kind":"Name","value":"nextEpisode"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"seasonNumber"}},{"kind":"Field","name":{"kind":"Name","value":"episodeNumber"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CollectionPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Collection"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SeenPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Seen"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"progress"}},{"kind":"Field","name":{"kind":"Name","value":"state"}},{"kind":"Field","name":{"kind":"Name","value":"startedOn"}},{"kind":"Field","name":{"kind":"Name","value":"finishedOn"}},{"kind":"Field","name":{"kind":"Name","value":"lastUpdatedOn"}},{"kind":"Field","name":{"kind":"Name","value":"numTimesUpdated"}},{"kind":"Field","name":{"kind":"Name","value":"showInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}},{"kind":"Field","name":{"kind":"Name","value":"season"}}]}},{"kind":"Field","name":{"kind":"Name","value":"podcastInformation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episode"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ReviewItemPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ReviewItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"rating"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"spoiler"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"showSeason"}},{"kind":"Field","name":{"kind":"Name","value":"showEpisode"}},{"kind":"Field","name":{"kind":"Name","value":"podcastEpisode"}},{"kind":"Field","name":{"kind":"Name","value":"postedOn"}},{"kind":"Field","name":{"kind":"Name","value":"postedBy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"comments"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"text"}},{"kind":"Field","name":{"kind":"Name","value":"createdOn"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"likedBy"}}]}}]}}]} as unknown as DocumentNode; +export const UserMetadataGroupDetailsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserMetadataGroupDetails"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"metadataGroupId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userMetadataGroupDetails"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"metadataGroupId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"metadataGroupId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"collections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CollectionPart"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CollectionPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Collection"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]} as unknown as DocumentNode; export const UserNotificationPlatformsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserNotificationPlatforms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userNotificationPlatforms"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"timestamp"}}]}}]}}]} as unknown as DocumentNode; export const UserPreferencesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserPreferences"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userPreferences"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"general"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"reviewScale"}},{"kind":"Field","name":{"kind":"Name","value":"numGenresDisplay"}},{"kind":"Field","name":{"kind":"Name","value":"displayNsfw"}},{"kind":"Field","name":{"kind":"Name","value":"dashboard"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"section"}},{"kind":"Field","name":{"kind":"Name","value":"hidden"}},{"kind":"Field","name":{"kind":"Name","value":"numElements"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"fitness"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"measurements"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"custom"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"dataType"}}]}},{"kind":"Field","name":{"kind":"Name","value":"inbuilt"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"weight"}},{"kind":"Field","name":{"kind":"Name","value":"bodyMassIndex"}},{"kind":"Field","name":{"kind":"Name","value":"totalBodyWater"}},{"kind":"Field","name":{"kind":"Name","value":"muscle"}},{"kind":"Field","name":{"kind":"Name","value":"leanBodyMass"}},{"kind":"Field","name":{"kind":"Name","value":"bodyFat"}},{"kind":"Field","name":{"kind":"Name","value":"boneMass"}},{"kind":"Field","name":{"kind":"Name","value":"visceralFat"}},{"kind":"Field","name":{"kind":"Name","value":"waistCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"waistToHeightRatio"}},{"kind":"Field","name":{"kind":"Name","value":"hipCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"waistToHipRatio"}},{"kind":"Field","name":{"kind":"Name","value":"chestCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"thighCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"bicepsCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"neckCircumference"}},{"kind":"Field","name":{"kind":"Name","value":"bodyFatCaliper"}},{"kind":"Field","name":{"kind":"Name","value":"chestSkinfold"}},{"kind":"Field","name":{"kind":"Name","value":"abdominalSkinfold"}},{"kind":"Field","name":{"kind":"Name","value":"thighSkinfold"}},{"kind":"Field","name":{"kind":"Name","value":"basalMetabolicRate"}},{"kind":"Field","name":{"kind":"Name","value":"totalDailyEnergyExpenditure"}},{"kind":"Field","name":{"kind":"Name","value":"calories"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"exercises"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"saveHistory"}},{"kind":"Field","name":{"kind":"Name","value":"unitSystem"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"notifications"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"episodeReleased"}},{"kind":"Field","name":{"kind":"Name","value":"episodeNameChanged"}},{"kind":"Field","name":{"kind":"Name","value":"statusChanged"}},{"kind":"Field","name":{"kind":"Name","value":"releaseDateChanged"}},{"kind":"Field","name":{"kind":"Name","value":"numberOfSeasonsChanged"}},{"kind":"Field","name":{"kind":"Name","value":"numberOfChaptersOrEpisodesChanged"}}]}},{"kind":"Field","name":{"kind":"Name","value":"featuresEnabled"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fitness"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"enabled"}},{"kind":"Field","name":{"kind":"Name","value":"workouts"}},{"kind":"Field","name":{"kind":"Name","value":"measurements"}}]}},{"kind":"Field","name":{"kind":"Name","value":"media"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"enabled"}},{"kind":"Field","name":{"kind":"Name","value":"anime"}},{"kind":"Field","name":{"kind":"Name","value":"audioBook"}},{"kind":"Field","name":{"kind":"Name","value":"book"}},{"kind":"Field","name":{"kind":"Name","value":"manga"}},{"kind":"Field","name":{"kind":"Name","value":"movie"}},{"kind":"Field","name":{"kind":"Name","value":"podcast"}},{"kind":"Field","name":{"kind":"Name","value":"show"}},{"kind":"Field","name":{"kind":"Name","value":"videoGame"}},{"kind":"Field","name":{"kind":"Name","value":"visualNovel"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const UserUpcomingCalendarEventsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserUpcomingCalendarEvents"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UserUpcomingCalendarEventInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userUpcomingCalendarEvents"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CalendarEventPart"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CalendarEventPart"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"GraphqlCalendarEvent"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"calendarEventId"}},{"kind":"Field","name":{"kind":"Name","value":"metadataId"}},{"kind":"Field","name":{"kind":"Name","value":"metadataTitle"}},{"kind":"Field","name":{"kind":"Name","value":"metadataLot"}},{"kind":"Field","name":{"kind":"Name","value":"metadataImage"}},{"kind":"Field","name":{"kind":"Name","value":"date"}},{"kind":"Field","name":{"kind":"Name","value":"showSeasonNumber"}},{"kind":"Field","name":{"kind":"Name","value":"showEpisodeNumber"}},{"kind":"Field","name":{"kind":"Name","value":"podcastEpisodeNumber"}}]}}]} as unknown as DocumentNode; diff --git a/libs/graphql/src/backend/mutations/AddEntityToCollection.gql b/libs/graphql/src/backend/mutations/AddEntityToCollection.gql new file mode 100644 index 0000000000..d093bca8c9 --- /dev/null +++ b/libs/graphql/src/backend/mutations/AddEntityToCollection.gql @@ -0,0 +1,3 @@ +mutation AddEntityToCollection($input: ChangeCollectionToEntityInput!) { + addEntityToCollection(input: $input) +} diff --git a/libs/graphql/src/backend/mutations/AddMediaToCollection.gql b/libs/graphql/src/backend/mutations/AddMediaToCollection.gql deleted file mode 100644 index 76150b7236..0000000000 --- a/libs/graphql/src/backend/mutations/AddMediaToCollection.gql +++ /dev/null @@ -1,3 +0,0 @@ -mutation AddMediaToCollection($input: AddMediaToCollection!) { - addMediaToCollection(input: $input) -} diff --git a/libs/graphql/src/backend/mutations/RemoveEntityFromCollection.gql b/libs/graphql/src/backend/mutations/RemoveEntityFromCollection.gql new file mode 100644 index 0000000000..95c0926799 --- /dev/null +++ b/libs/graphql/src/backend/mutations/RemoveEntityFromCollection.gql @@ -0,0 +1,5 @@ +mutation RemoveEntityFromCollection($input: ChangeCollectionToEntityInput!) { + removeEntityFromCollection(input: $input) { + id + } +} diff --git a/libs/graphql/src/backend/mutations/RemoveMediaFromCollection.gql b/libs/graphql/src/backend/mutations/RemoveMediaFromCollection.gql deleted file mode 100644 index c6af9ed359..0000000000 --- a/libs/graphql/src/backend/mutations/RemoveMediaFromCollection.gql +++ /dev/null @@ -1,5 +0,0 @@ -mutation RemoveMediaFromCollection($metadataId: Int!, $collectionName: String!) { - removeMediaFromCollection(metadataId: $metadataId, collectionName: $collectionName) { - id - } -} diff --git a/libs/graphql/src/backend/queries/CollectionContents.gql b/libs/graphql/src/backend/queries/CollectionContents.gql index d4b36342e9..9e6baa0b7d 100644 --- a/libs/graphql/src/backend/queries/CollectionContents.gql +++ b/libs/graphql/src/backend/queries/CollectionContents.gql @@ -9,7 +9,8 @@ query CollectionContents($input: CollectionContentsInput!) { nextPage } items { - lot + metadataLot + entityLot details { identifier title diff --git a/libs/graphql/src/backend/queries/Collections.gql b/libs/graphql/src/backend/queries/Collections.gql deleted file mode 100644 index a79474db99..0000000000 --- a/libs/graphql/src/backend/queries/Collections.gql +++ /dev/null @@ -1,9 +0,0 @@ -query Collections($input: CollectionInput) { - collections(input: $input) { - id - name - description - visibility - numItems - } -} diff --git a/libs/graphql/src/backend/queries/UserCollectionsList.gql b/libs/graphql/src/backend/queries/UserCollectionsList.gql new file mode 100644 index 0000000000..dd100dce1f --- /dev/null +++ b/libs/graphql/src/backend/queries/UserCollectionsList.gql @@ -0,0 +1,9 @@ +query UserCollectionsList($name: String) { + userCollectionsList(name: $name) { + id + name + description + visibility + numItems + } +} diff --git a/libs/graphql/src/backend/queries/UserCreatorDetails.gql b/libs/graphql/src/backend/queries/UserCreatorDetails.gql index e15f1ab7eb..4f5a42f303 100644 --- a/libs/graphql/src/backend/queries/UserCreatorDetails.gql +++ b/libs/graphql/src/backend/queries/UserCreatorDetails.gql @@ -1,26 +1,10 @@ query UserCreatorDetails($creatorId: Int!) { userCreatorDetails(creatorId: $creatorId) { + collections { + ...CollectionPart + } reviews { - id - rating - text - spoiler - visibility - postedOn - postedBy { - id - name - } - comments { - id - text - createdOn - user { - id - name - } - likedBy - } + ...ReviewItemPart } } } diff --git a/libs/graphql/src/backend/queries/UserExerciseDetails.gql b/libs/graphql/src/backend/queries/UserExerciseDetails.gql index b05943ba65..5f06e9f48b 100644 --- a/libs/graphql/src/backend/queries/UserExerciseDetails.gql +++ b/libs/graphql/src/backend/queries/UserExerciseDetails.gql @@ -1,5 +1,8 @@ query UserExerciseDetails($input: UserExerciseDetailsInput!) { userExerciseDetails(input: $input) { + collections { + ...CollectionPart + } history { workoutId workoutName diff --git a/libs/graphql/src/backend/queries/UserMediaDetails.gql b/libs/graphql/src/backend/queries/UserMediaDetails.gql index cb9af114ef..6e27ef251b 100644 --- a/libs/graphql/src/backend/queries/UserMediaDetails.gql +++ b/libs/graphql/src/backend/queries/UserMediaDetails.gql @@ -1,8 +1,7 @@ query UserMediaDetails($metadataId: Int!) { userMediaDetails(metadataId: $metadataId) { collections { - id - name + ...CollectionPart } inProgress { ...SeenPart @@ -12,29 +11,7 @@ query UserMediaDetails($metadataId: Int!) { } averageRating reviews { - id - rating - text - spoiler - visibility - showSeason - showEpisode - podcastEpisode - postedOn - postedBy { - id - name - } - comments { - id - text - createdOn - user { - id - name - } - likedBy - } + ...ReviewItemPart } reminder { remindOn diff --git a/libs/graphql/src/backend/queries/UserMetadataGroupDetails.gql b/libs/graphql/src/backend/queries/UserMetadataGroupDetails.gql new file mode 100644 index 0000000000..7bcb01079a --- /dev/null +++ b/libs/graphql/src/backend/queries/UserMetadataGroupDetails.gql @@ -0,0 +1,7 @@ +query UserMetadataGroupDetails($metadataGroupId: Int!) { + userMetadataGroupDetails(metadataGroupId: $metadataGroupId) { + collections { + ...CollectionPart + } + } +} diff --git a/libs/graphql/src/backend/queries/fragments.gql b/libs/graphql/src/backend/queries/fragments.gql index 483bf2792c..f73c14a205 100644 --- a/libs/graphql/src/backend/queries/fragments.gql +++ b/libs/graphql/src/backend/queries/fragments.gql @@ -73,3 +73,34 @@ fragment WorkoutSummaryPart on WorkoutSummary { } } } + +fragment CollectionPart on Collection { + id + name +} + +fragment ReviewItemPart on ReviewItem { + id + rating + text + spoiler + visibility + showSeason + showEpisode + podcastEpisode + postedOn + postedBy { + id + name + } + comments { + id + text + createdOn + user { + id + name + } + likedBy + } +}