Skip to content

Commit

Permalink
Button to update entities if they are partial (#1172)
Browse files Browse the repository at this point in the history
* feat(backend): add mutation to mark entity as partial

* fix(services/miscellaneous): remove admin guard

* chore(gql): add new mutation

* feat(frontend): add action to mark entity as partial

* feat(frontend): add button mark entity as partial

* refactor(frontend): extract component to mark entity as partial

* feat(frontend): add button to mark person as partial

* feat(frontend): add button to mark metadata group as partial

* chore(resolvers/miscellaneous): change comment for mutation
  • Loading branch information
IgnisDa authored Jan 9, 2025
1 parent 1161083 commit 45f49c4
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 9 deletions.
22 changes: 22 additions & 0 deletions apps/frontend/app/components/media.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -440,3 +440,25 @@ export const ToggleMediaMonitorMenuItem = (props: {
</Form>
);
};

export const MarkEntityAsPartialMenuItem = (props: {
entityId: string;
entityLot: EntityLot;
}) => {
const submit = useConfirmSubmit();

return (
<Form
replace
method="POST"
onSubmit={(e) => submit(e)}
action={withQuery($path("/actions"), {
intent: "markEntityAsPartial",
})}
>
<input hidden name="entityId" defaultValue={props.entityId} />
<input hidden name="entityLot" defaultValue={props.entityLot} />
<Menu.Item type="submit">Update details</Menu.Item>
</Form>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
ReviewItemDisplay,
} from "~/components/common";
import {
MarkEntityAsPartialMenuItem,
MediaScrollArea,
PartialMetadataDisplay,
ToggleMediaMonitorMenuItem,
Expand Down Expand Up @@ -197,6 +198,10 @@ export default function Page() {
formValue={loaderData.metadataGroupId}
entityLot={EntityLot.MetadataGroup}
/>
<MarkEntityAsPartialMenuItem
entityLot={EntityLot.MetadataGroup}
entityId={loaderData.metadataGroupId}
/>
</Menu.Dropdown>
</Menu>
</SimpleGrid>
Expand Down
5 changes: 5 additions & 0 deletions apps/frontend/app/routes/_dashboard.media.item.$id._index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ import {
} from "~/components/common";
import {
BaseEntityDisplay,
MarkEntityAsPartialMenuItem,
MediaScrollArea,
PartialMetadataDisplay,
ToggleMediaMonitorMenuItem,
Expand Down Expand Up @@ -996,6 +997,10 @@ export default function Page() {
Remove item
</Menu.Item>
</Form>
<MarkEntityAsPartialMenuItem
entityLot={EntityLot.Metadata}
entityId={loaderData.metadataId}
/>
</Menu.Dropdown>
</Menu>
{canCurrentUserUpdate ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
} from "~/components/common";
import {
BaseEntityDisplay,
MarkEntityAsPartialMenuItem,
MediaScrollArea,
PartialMetadataDisplay,
ToggleMediaMonitorMenuItem,
Expand Down Expand Up @@ -321,6 +322,10 @@ export default function Page() {
formValue={loaderData.personId}
entityLot={EntityLot.Person}
/>
<MarkEntityAsPartialMenuItem
entityLot={EntityLot.Person}
entityId={loaderData.personId}
/>
</Menu.Dropdown>
</Menu>
</SimpleGrid>
Expand Down
21 changes: 21 additions & 0 deletions apps/frontend/app/routes/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
DeleteS3ObjectDocument,
DeployBulkProgressUpdateDocument,
EntityLot,
MarkEntityAsPartialDocument,
MediaLot,
MediaSource,
MetadataDetailsDocument,
Expand Down Expand Up @@ -472,6 +473,21 @@ export const action = async ({ request }: ActionFunctionArgs) => {
);
}
})
.with("markEntityAsPartial", async () => {
const submission = processSubmission(formData, markEntityAsPartialSchema);
await serverGqlService.authenticatedRequest(
request,
MarkEntityAsPartialDocument,
{ input: submission },
);
extendResponseHeaders(
headers,
await createToastHeaders({
message: "Entity will be updated in the background",
type: "success",
}),
);
})
.run();
if (redirectTo) {
headers.append("Location", redirectTo.toString());
Expand Down Expand Up @@ -567,3 +583,8 @@ const bulkCollectionAction = z.object({
}),
),
});

const markEntityAsPartialSchema = z.object({
entityId: z.string(),
entityLot: z.nativeEnum(EntityLot),
});
6 changes: 6 additions & 0 deletions crates/models/media/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1372,6 +1372,12 @@ pub struct UpdateSeenItemInput {
pub provider_watched_on: Option<String>,
}

#[derive(Debug, Serialize, Deserialize, InputObject, Clone)]
pub struct MarkEntityAsPartialInput {
pub entity_id: String,
pub entity_lot: EntityLot,
}

#[derive(Debug, Serialize, Deserialize, SimpleObject, Clone)]
pub struct PresignedPutUrlResponse {
pub upload_url: String,
Expand Down
18 changes: 15 additions & 3 deletions crates/resolvers/miscellaneous/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ use dependent_models::{
use media_models::{
CommitMediaInput, CommitPersonInput, CreateCustomMetadataInput, CreateOrUpdateReviewInput,
CreateReviewCommentInput, GenreDetailsInput, GenreListItem, GraphqlCalendarEvent,
GraphqlMetadataDetails, GroupedCalendarEvent, MetadataGroupsListInput, MetadataListInput,
MetadataPartialDetails, PeopleListInput, ProgressUpdateInput, UpdateCustomMetadataInput,
UpdateSeenItemInput, UserCalendarEventInput, UserUpcomingCalendarEventInput,
GraphqlMetadataDetails, GroupedCalendarEvent, MarkEntityAsPartialInput,
MetadataGroupsListInput, MetadataListInput, MetadataPartialDetails, PeopleListInput,
ProgressUpdateInput, UpdateCustomMetadataInput, UpdateSeenItemInput, UserCalendarEventInput,
UserUpcomingCalendarEventInput,
};
use miscellaneous_service::MiscellaneousService;
use traits::AuthProvider;
Expand Down Expand Up @@ -416,6 +417,17 @@ impl MiscellaneousMutation {
service.deploy_background_job(&user_id, job_name).await
}

/// Mark an entity as partial.
async fn mark_entity_as_partial(
&self,
gql_ctx: &Context<'_>,
input: MarkEntityAsPartialInput,
) -> Result<bool> {
let service = gql_ctx.data_unchecked::<Arc<MiscellaneousService>>();
let user_id = self.user_id_from_ctx(gql_ctx).await?;
service.mark_entity_as_partial(&user_id, input).await
}

/// Use this mutation to call a function that needs to be tested for implementation.
/// It is only available in development mode.
#[cfg(debug_assertions)]
Expand Down
40 changes: 36 additions & 4 deletions crates/services/miscellaneous/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ use media_models::{
CommitMediaInput, CommitPersonInput, CreateCustomMetadataInput, CreateOrUpdateReviewInput,
CreateReviewCommentInput, GenreDetailsInput, GenreListItem, GraphqlCalendarEvent,
GraphqlMediaAssets, GraphqlMetadataDetails, GraphqlMetadataGroup, GraphqlVideoAsset,
GroupedCalendarEvent, ImportOrExportItemReviewComment, MediaAssociatedPersonStateChanges,
MediaGeneralFilter, MediaSortBy, MetadataCreator, MetadataCreatorGroupedByRole,
MetadataFreeCreator, MetadataGroupsListInput, MetadataImage, MetadataListInput,
MetadataPartialDetails, MetadataVideo, MetadataVideoSource, PartialMetadata,
GroupedCalendarEvent, ImportOrExportItemReviewComment, MarkEntityAsPartialInput,
MediaAssociatedPersonStateChanges, MediaGeneralFilter, MediaSortBy, MetadataCreator,
MetadataCreatorGroupedByRole, MetadataFreeCreator, MetadataGroupsListInput, MetadataImage,
MetadataListInput, MetadataPartialDetails, MetadataVideo, MetadataVideoSource, PartialMetadata,
PartialMetadataWithoutId, PeopleListInput, PersonAndMetadataGroupsSortBy,
PersonDetailsGroupedByRole, PersonDetailsItemWithCharacter, PodcastSpecifics,
ProgressUpdateInput, ReviewPostedEvent, SeenAnimeExtraInformation, SeenPodcastExtraInformation,
Expand Down Expand Up @@ -1074,6 +1074,38 @@ ORDER BY RANDOM() LIMIT 10;
deploy_background_job(user_id, job_name, &self.0).await
}

pub async fn mark_entity_as_partial(
&self,
_user_id: &String,
input: MarkEntityAsPartialInput,
) -> Result<bool> {
match input.entity_lot {
EntityLot::Metadata => {
Metadata::update_many()
.filter(metadata::Column::Id.eq(&input.entity_id))
.col_expr(metadata::Column::IsPartial, Expr::value(true))
.exec(&self.0.db)
.await?;
}
EntityLot::MetadataGroup => {
MetadataGroup::update_many()
.filter(metadata_group::Column::Id.eq(&input.entity_id))
.col_expr(metadata_group::Column::IsPartial, Expr::value(true))
.exec(&self.0.db)
.await?;
}
EntityLot::Person => {
Person::update_many()
.filter(person::Column::Id.eq(&input.entity_id))
.col_expr(person::Column::IsPartial, Expr::value(true))
.exec(&self.0.db)
.await?;
}
_ => return Err(Error::new("Invalid entity lot".to_owned())),
}
Ok(true)
}

async fn cleanup_user_and_metadata_association(&self) -> Result<()> {
let all_users = User::find()
.select_only()
Expand Down
Loading

0 comments on commit 45f49c4

Please sign in to comment.