Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Convert manage tag usage pages to React #1414

Merged
merged 6 commits into from
May 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Tests/GitHubIssues/Issue789/TagUsageQueriesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ public void RemoveTagUsage()
var usage = _repository.Save(_entry.AddTag(tag).Result);
_repository.Save(_entry.AddTag(tag2).Result);

Invoking(() => _queries.RemoveTagUsage<SongTagUsage, Song>(usage.Id, _repository.OfType<Song>())).Should().Throw<NotAllowedException>();
Invoking(() => _queries.RemoveTagUsage<SongTagUsage, Song>(usage.Id, _repository.OfType<User>())).Should().Throw<NotAllowedException>();
}

[TestMethod]
Expand Down
2 changes: 1 addition & 1 deletion Tests/Service/Queries/TagUsageQueriesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public void RemoveTagUsage()
var usage = _repository.Save(_entry.AddTag(tag).Result);
_repository.Save(_entry.AddTag(tag2).Result);

_queries.RemoveTagUsage<SongTagUsage, Song>(usage.Id, _repository.OfType<Song>());
_queries.RemoveTagUsage<SongTagUsage, Song>(usage.Id, _repository.OfType<User>());

_entry.Tags.Usages.Count.Should().Be(1, "Number of tag usages for entry");
tag.UsageCount.Should().Be(0, "Number of usages for tag");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace VocaDb.Model.DataContracts.Tags;

[Obsolete]
public class TagUsageWithVotesContract
{
public TagUsageWithVotesContract(TagUsage usage, ContentLanguagePreference languagePreference, IUserIconFactory userIconFactory)
Expand Down
35 changes: 35 additions & 0 deletions VocaDbModel/DataContracts/Tags/TagUsageWithVotesForApiContract.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Runtime.Serialization;
using VocaDb.Model.DataContracts.Users;
using VocaDb.Model.Domain.Globalization;
using VocaDb.Model.Domain.Tags;

namespace VocaDb.Model.DataContracts.Tags;

[DataContract(Namespace = Schemas.VocaDb)]
public sealed record TagUsageWithVotesForApiContract
{
[DataMember]
public DateTime Date { get; init; }

[DataMember]
public int Count { get; init; }

[DataMember]
public long Id { get; init; }

[DataMember]
public TagBaseContract Tag { get; init; }

[DataMember]
public UserForApiContract[] Votes { get; init; }

public TagUsageWithVotesForApiContract(TagUsage usage, ContentLanguagePreference languagePreference, IUserIconFactory userIconFactory)
{
Count = usage.Count;
Date = usage.Date;
Id = usage.Id;
Tag = new TagBaseContract(usage.Tag, languagePreference);

Votes = usage.VotesBase.Select(v => new UserForApiContract(v.User, userIconFactory, UserOptionalFields.MainPicture)).ToArray();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace VocaDb.Model.DataContracts.UseCases;

[Obsolete]
public class EntryWithTagUsagesContract : EntryBaseContract
{
public EntryWithTagUsagesContract() { }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Runtime.Serialization;
using VocaDb.Model.DataContracts.Tags;
using VocaDb.Model.DataContracts.Users;
using VocaDb.Model.Domain;
using VocaDb.Model.Domain.Globalization;
using VocaDb.Model.Domain.Security;
using VocaDb.Model.Domain.Tags;

namespace VocaDb.Model.DataContracts.UseCases;

[DataContract(Namespace = Schemas.VocaDb)]
public sealed record EntryWithTagUsagesForApiContract : IEntryWithIntId
{
public EntryWithTagUsagesForApiContract(
IEntryWithStatus entry,
IEnumerable<TagUsage> tagUsages,
ContentLanguagePreference languagePreference,
IUserPermissionContext userContext,
IUserIconFactory userIconFactory
)
{
CanRemoveTagUsages = EntryPermissionManager.CanRemoveTagUsages(userContext, entry);
TagUsages = tagUsages.Select(u => new TagUsageWithVotesForApiContract(u, languagePreference, userIconFactory)).ToArray();
DefaultName = entry.DefaultName;
Id = entry.Id;
}

[DataMember]
public int Id { get; set; }

[DataMember]
public string DefaultName { get; init; }

[DataMember]
public bool CanRemoveTagUsages { get; init; }

[DataMember]
public TagUsageWithVotesForApiContract[] TagUsages { get; init; }
}
5 changes: 0 additions & 5 deletions VocaDbModel/Database/Queries/AlbumQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -834,11 +834,6 @@ public int MoveToTrash(int albumId)
});
}

public int RemoveTagUsage(long tagUsageId)
{
return new TagUsageQueries(PermissionContext).RemoveTagUsage<AlbumTagUsage, Album>(tagUsageId, _repository);
}

public EntryRevertedContract RevertToVersion(int archivedAlbumVersionId)
{
PermissionContext.VerifyPermission(PermissionToken.RestoreRevisions);
Expand Down
5 changes: 0 additions & 5 deletions VocaDbModel/Database/Queries/ArtistQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -552,11 +552,6 @@ public TagUsageForApiContract[] GetTagSuggestions(int artistId)
});
}

public int RemoveTagUsage(long tagUsageId)
{
return new TagUsageQueries(PermissionContext).RemoveTagUsage<ArtistTagUsage, Artist>(tagUsageId, _repository);
}

/// <summary>
/// Reverts an album to an earlier archived version.
/// </summary>
Expand Down
9 changes: 2 additions & 7 deletions VocaDbModel/Database/Queries/EventQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,12 @@ public ReleaseEventDetailsForApiContract GetDetails(int id)
});
}

public EntryWithTagUsagesContract GetEntryWithTagUsages(int eventId)
public EntryWithTagUsagesForApiContract GetEntryWithTagUsages(int eventId)
{
return HandleQuery(session =>
{
var releaseEvent = session.Load<ReleaseEvent>(eventId);
return new EntryWithTagUsagesContract(releaseEvent, releaseEvent.Tags.ActiveUsages, LanguagePreference, PermissionContext, _userIconFactory);
return new EntryWithTagUsagesForApiContract(releaseEvent, releaseEvent.Tags.ActiveUsages, LanguagePreference, PermissionContext, _userIconFactory);
});
}

Expand Down Expand Up @@ -500,11 +500,6 @@ public void MoveToTrash(int eventId, string notes)
});
}

public int RemoveTagUsage(long tagUsageId)
{
return new TagUsageQueries(PermissionContext).RemoveTagUsage<EventTagUsage, ReleaseEvent>(tagUsageId, _repository);
}

public void Restore(int eventId)
{
PermissionContext.VerifyPermission(PermissionToken.DeleteEntries);
Expand Down
5 changes: 0 additions & 5 deletions VocaDbModel/Database/Queries/SongQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1169,11 +1169,6 @@ await _repository.HandleTransactionAsync(async ctx =>
});
}

public int RemoveTagUsage(long tagUsageId)
{
return new TagUsageQueries(PermissionContext).RemoveTagUsage<SongTagUsage, Song>(tagUsageId, _repository);
}

public EntryRevertedContract RevertToVersion(int archivedSongVersionId)
{
PermissionContext.VerifyPermission(PermissionToken.RestoreRevisions);
Expand Down
20 changes: 20 additions & 0 deletions VocaDbModel/Database/Queries/UserQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1423,6 +1423,26 @@ public TagSelectionContract[] GetSongTagSelections(int songId, int userId)
});
}

public void DeleteSongTag(long tagUsageId)
{
new TagUsageQueries(PermissionContext).RemoveTagUsage<SongTagUsage, Song>(tagUsageId, _repository);
}

public void DeleteArtistTag(long tagUsageId)
{
new TagUsageQueries(PermissionContext).RemoveTagUsage<ArtistTagUsage, Artist>(tagUsageId, _repository);
}

public void DeleteEventTag(long tagUsageId)
{
new TagUsageQueries(PermissionContext).RemoveTagUsage<EventTagUsage, ReleaseEvent>(tagUsageId, _repository);
}

public void DeleteAlbumTag(long tagUsageId)
{
new TagUsageQueries(PermissionContext).RemoveTagUsage<AlbumTagUsage, Album>(tagUsageId, _repository);
}

public UserForApiContract GetUser(int id, UserOptionalFields fields)
{
return HandleQuery(ctx => new UserForApiContract(ctx.Load<User>(id), _userIconFactory, fields));
Expand Down
4 changes: 2 additions & 2 deletions VocaDbModel/Service/AlbumService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,12 @@ public EntryForPictureDisplayContract GetCoverPicture(int id)
EntryForPictureDisplayContract.Create(session.Load<Album>(id), PermissionContext.LanguagePreference));
}

public EntryWithTagUsagesContract GetEntryWithTagUsages(int albumId)
public EntryWithTagUsagesForApiContract GetEntryWithTagUsages(int albumId)
{
return HandleQuery(session =>
{
var album = session.Load<Album>(albumId);
return new EntryWithTagUsagesContract(album, album.Tags.ActiveUsages, LanguagePreference, PermissionContext, _userIconFactory);
return new EntryWithTagUsagesForApiContract(album, album.Tags.ActiveUsages, LanguagePreference, PermissionContext, _userIconFactory);
});
}

Expand Down
4 changes: 2 additions & 2 deletions VocaDbModel/Service/ArtistService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,12 @@ public ArtistForApiContract[] GetArtistsWithYoutubeChannels(ContentLanguagePrefe
});
}

public EntryWithTagUsagesContract GetEntryWithTagUsages(int artistId)
public EntryWithTagUsagesForApiContract GetEntryWithTagUsages(int artistId)
{
return HandleQuery(session =>
{
var artist = session.Load<Artist>(artistId);
return new EntryWithTagUsagesContract(artist, artist.Tags.ActiveUsages, LanguagePreference, PermissionContext, _userIconFactory);
return new EntryWithTagUsagesForApiContract(artist, artist.Tags.ActiveUsages, LanguagePreference, PermissionContext, _userIconFactory);
});
}

Expand Down
2 changes: 1 addition & 1 deletion VocaDbModel/Service/Queries/TagUsageQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Func<TEntry, IDatabaseContext<TTag>, ITagUsageFactory<TTag>> tagUsageFactoryFact
});
}

public int RemoveTagUsage<TUsage, TEntry>(long tagUsageId, IRepository<TEntry> repository)
public int RemoveTagUsage<TUsage, TEntry>(long tagUsageId, IRepository<User> repository)
where TUsage : TagUsage
where TEntry : class, IDatabaseObject
{
Expand Down
4 changes: 2 additions & 2 deletions VocaDbModel/Service/SongService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,12 @@ public string[] FindNames(SearchTextQuery textQuery, int maxResults)
});
}

public EntryWithTagUsagesContract GetEntryWithTagUsages(int songId)
public EntryWithTagUsagesForApiContract GetEntryWithTagUsages(int songId)
{
return HandleQuery(session =>
{
var song = session.Load<Song>(songId);
return new EntryWithTagUsagesContract(song, song.Tags.ActiveUsages, LanguagePreference, PermissionContext, _userIconFactory);
return new EntryWithTagUsagesForApiContract(song, song.Tags.ActiveUsages, LanguagePreference, PermissionContext, _userIconFactory);
});
}

Expand Down
19 changes: 0 additions & 19 deletions VocaDbWeb/Controllers/AlbumController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,6 @@ public ActionResult Related(int id = InvalidId)
return PartialView("RelatedAlbums", related);
}

[Authorize]
public ActionResult RemoveTagUsage(long id)
{
var albumId = _queries.RemoveTagUsage(id);
TempData.SetStatusMessage("Tag usage removed");

return RedirectToAction("ManageTagUsages", new { id = albumId });
}

public ActionResult Restore(int id)
{
Service.Restore(id);
Expand All @@ -276,16 +267,6 @@ public ActionResult Deleted()
return File("index.html", "text/html") ;
}

[Authorize]
public ActionResult ManageTagUsages(int id)
{
var album = Service.GetEntryWithTagUsages(id);

PageProperties.Title = "Manage tag usages - " + album.DefaultName;

return View(album);
}

public ActionResult Merge()
{
return File("index.html", "text/html") ;
Expand Down
5 changes: 4 additions & 1 deletion VocaDbWeb/Controllers/Api/AlbumApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,10 @@ public IEnumerable<AlbumForApiContract> GetTopAlbums(
[HttpGet("{id:int}/tagSuggestions")]
public Task<TagUsageForApiContract[]> GetTagSuggestions(int id) => _queries.GetTagSuggestions(id);

/// <summary>
[HttpGet("{id:int}/tagUsages")]
[ApiExplorerSettings(IgnoreApi = true)]
public EntryWithTagUsagesForApiContract GetTagUsages(int id) => _service.GetEntryWithTagUsages(id); /// <summary>

/// Gets tracks for an album.
/// </summary>
/// <param name="id">Album ID (required).</param>
Expand Down
6 changes: 5 additions & 1 deletion VocaDbWeb/Controllers/Api/ArtistApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,11 @@ public string[] GetNames(
[HttpGet("{id:int}/tagSuggestions")]
public IEnumerable<TagUsageForApiContract> GetTagSuggestions(int id) =>
_queries.GetTagSuggestions(id);


[HttpGet("{id:int}/tagUsages")]
[ApiExplorerSettings(IgnoreApi = true)]
public EntryWithTagUsagesForApiContract GetTagUsages(int id) => _service.GetEntryWithTagUsages(id);

[HttpGet("versions")]
[ApiExplorerSettings(IgnoreApi = true)]
public EntryIdAndVersionContract[] GetVersions() =>
Expand Down
7 changes: 6 additions & 1 deletion VocaDbWeb/Controllers/Api/ReleaseEventApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using VocaDb.Model.DataContracts.Albums;
using VocaDb.Model.DataContracts.ReleaseEvents;
using VocaDb.Model.DataContracts.Songs;
using VocaDb.Model.DataContracts.UseCases;
using VocaDb.Model.DataContracts.Venues;
using VocaDb.Model.DataContracts.Versioning;
using VocaDb.Model.Domain;
Expand Down Expand Up @@ -312,7 +313,11 @@ public VenueForApiContract[] GetReleaseEventsByVenue()
{
return _queries.GetReleaseEventsByVenue();
}


[HttpGet("{id:int}/tagUsages")]
[ApiExplorerSettings(IgnoreApi = true)]
public EntryWithTagUsagesForApiContract GetTagUsages(int id) => _queries.GetEntryWithTagUsages(id);

[HttpPost("versions/{archivedVersionId:int}/update-visibility")]
[Authorize]
[EnableCors(AuthenticationConstants.AuthenticatedCorsApiPolicy)]
Expand Down
6 changes: 5 additions & 1 deletion VocaDbWeb/Controllers/Api/SongApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -472,10 +472,14 @@ public CountPerDayContract[] GetSongsOverTime(
) =>
_songAggregateQueries.SongsOverTime(timeUnit, true, null, artistId, tagId);

[ApiExplorerSettings(IgnoreApi = true)]
[HttpGet("{id:int}/tagSuggestions")]
[ApiExplorerSettings(IgnoreApi = true)]
public async Task<IEnumerable<TagUsageForApiContract>> GetTagSuggestions(int id) =>
await _queries.GetTagSuggestionsAsync(id);

[HttpGet("{id:int}/tagUsages")]
[ApiExplorerSettings(IgnoreApi = true)]
public EntryWithTagUsagesForApiContract GetTagUsages(int id) => _service.GetEntryWithTagUsages(id);

/// <summary>
/// Gets top rated songs.
Expand Down
31 changes: 31 additions & 0 deletions VocaDbWeb/Controllers/Api/UserApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,37 @@ public Tuple<string, int>[] GetSongsPerGenre(int id) =>
public TagSelectionContract[] GetSongTags(int songId) =>
_queries.GetSongTagSelections(songId, _permissionContext.LoggedUserId);

[HttpDelete("current/songTags/{tagUsageId:long}")]
[Authorize]
[ApiExplorerSettings(IgnoreApi = true)]
public ActionResult RemoveSongTagUsage(long tagUsageId) {
_queries.DeleteSongTag(tagUsageId);
return NoContent();
}

[HttpDelete("current/artistTags/{tagUsageId:long}")]
[Authorize]
[ApiExplorerSettings(IgnoreApi = true)]
public ActionResult RemoveArtistTagUsage(long tagUsageId) {
_queries.DeleteArtistTag(tagUsageId);
return NoContent();
}

[HttpDelete("current/albumTags/{tagUsageId:long}")]
[Authorize]
[ApiExplorerSettings(IgnoreApi = true)]
public ActionResult RemoveAlbumTagUsage(long tagUsageId) {
_queries.DeleteAlbumTag(tagUsageId);
return NoContent();
}

[HttpDelete("current/eventTags/{tagUsageId:long}")]
[Authorize]
[ApiExplorerSettings(IgnoreApi = true)]
public ActionResult RemoveEventTagUsage(long tagUsageId) {
_queries.DeleteEventTag(tagUsageId);
return NoContent();
}
/// <summary>
/// Add or update collection status, media type and rating for a specific album, for the currently logged in user.
/// </summary>
Expand Down
Loading