v0.8.5.2 - Hotfix (#3608)

This commit is contained in:
Joe Milazzo 2025-03-09 11:21:43 -05:00 committed by GitHub
parent 56e84fc235
commit 401fa3e611
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 524 additions and 23 deletions

View File

@ -0,0 +1,456 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
using API.DTOs.Update;
using API.Extensions;
using API.Services;
using API.Services.Tasks;
using API.SignalR;
using Flurl.Http;
using Flurl.Http.Testing;
using Kavita.Common.EnvironmentInfo;
using Microsoft.Extensions.Logging;
using NSubstitute;
using Xunit;
namespace API.Tests.Services;
public class VersionUpdaterServiceTests : IDisposable
{
private readonly ILogger<VersionUpdaterService> _logger;
private readonly IEventHub _eventHub;
private readonly IDirectoryService _directoryService;
private readonly VersionUpdaterService _service;
private readonly string _tempPath;
private readonly HttpTest _httpTest;
public VersionUpdaterServiceTests()
{
_logger = Substitute.For<ILogger<VersionUpdaterService>>();
_eventHub = Substitute.For<IEventHub>();
_directoryService = Substitute.For<IDirectoryService>();
// Create temp directory for cache
_tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(_tempPath);
_directoryService.LongTermCacheDirectory.Returns(_tempPath);
_service = new VersionUpdaterService(_logger, _eventHub, _directoryService);
// Setup HTTP testing
_httpTest = new HttpTest();
// Mock BuildInfo.Version for consistent testing
typeof(BuildInfo).GetProperty(nameof(BuildInfo.Version))?.SetValue(null, new Version("0.5.0.0"));
}
public void Dispose()
{
_httpTest.Dispose();
// Cleanup temp directory
if (Directory.Exists(_tempPath))
{
Directory.Delete(_tempPath, true);
}
// Reset BuildInfo.Version
typeof(BuildInfo).GetProperty(nameof(BuildInfo.Version))?.SetValue(null, null);
}
[Fact]
public async Task CheckForUpdate_ShouldReturnNull_WhenGithubApiReturnsNull()
{
// Arrange
_httpTest.RespondWith("null");
// Act
var result = await _service.CheckForUpdate();
// Assert
Assert.Null(result);
}
// Depends on BuildInfo.CurrentVersion
//[Fact]
public async Task CheckForUpdate_ShouldReturnUpdateNotification_WhenNewVersionIsAvailable()
{
// Arrange
var githubResponse = new
{
tag_name = "v0.6.0",
name = "Release 0.6.0",
body = "# Added\n- Feature 1\n- Feature 2\n# Fixed\n- Bug 1\n- Bug 2",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.6.0",
published_at = DateTime.UtcNow.ToString("o")
};
_httpTest.RespondWithJson(githubResponse);
// Act
var result = await _service.CheckForUpdate();
// Assert
Assert.NotNull(result);
Assert.Equal("0.6.0", result.UpdateVersion);
Assert.Equal("0.5.0.0", result.CurrentVersion);
Assert.True(result.IsReleaseNewer);
Assert.Equal(2, result.Added.Count);
Assert.Equal(2, result.Fixed.Count);
}
//[Fact]
public async Task CheckForUpdate_ShouldDetectEqualVersion()
{
// I can't figure this out
typeof(BuildInfo).GetProperty(nameof(BuildInfo.Version))?.SetValue(null, new Version("0.5.0.0"));
var githubResponse = new
{
tag_name = "v0.5.0",
name = "Release 0.5.0",
body = "# Added\n- Feature 1",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.5.0",
published_at = DateTime.UtcNow.ToString("o")
};
_httpTest.RespondWithJson(githubResponse);
// Act
var result = await _service.CheckForUpdate();
// Assert
Assert.NotNull(result);
Assert.True(result.IsReleaseEqual);
Assert.False(result.IsReleaseNewer);
}
//[Fact]
public async Task PushUpdate_ShouldSendUpdateEvent_WhenNewerVersionAvailable()
{
// Arrange
var update = new UpdateNotificationDto
{
UpdateVersion = "0.6.0",
CurrentVersion = "0.5.0.0",
UpdateBody = "",
UpdateTitle = null,
UpdateUrl = null,
PublishDate = null
};
// Act
await _service.PushUpdate(update);
// Assert
await _eventHub.Received(1).SendMessageAsync(
Arg.Is(MessageFactory.UpdateAvailable),
Arg.Any<SignalRMessage>(),
Arg.Is(true)
);
}
[Fact]
public async Task PushUpdate_ShouldNotSendUpdateEvent_WhenVersionIsEqual()
{
// Arrange
var update = new UpdateNotificationDto
{
UpdateVersion = "0.5.0.0",
CurrentVersion = "0.5.0.0",
UpdateBody = "",
UpdateTitle = null,
UpdateUrl = null,
PublishDate = null
};
// Act
await _service.PushUpdate(update);
// Assert
await _eventHub.DidNotReceive().SendMessageAsync(
Arg.Any<string>(),
Arg.Any<SignalRMessage>(),
Arg.Any<bool>()
);
}
[Fact]
public async Task GetAllReleases_ShouldReturnReleases_LimitedByCount()
{
// Arrange
var releases = new List<object>
{
new
{
tag_name = "v0.7.0",
name = "Release 0.7.0",
body = "# Added\n- Feature A",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.7.0",
published_at = DateTime.UtcNow.AddDays(-1).ToString("o")
},
new
{
tag_name = "v0.6.0",
name = "Release 0.6.0",
body = "# Added\n- Feature B",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.6.0",
published_at = DateTime.UtcNow.AddDays(-10).ToString("o")
},
new
{
tag_name = "v0.5.0",
name = "Release 0.5.0",
body = "# Added\n- Feature C",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.5.0",
published_at = DateTime.UtcNow.AddDays(-20).ToString("o")
}
};
_httpTest.RespondWithJson(releases);
// Act
var result = await _service.GetAllReleases(2);
// Assert
Assert.Equal(2, result.Count);
Assert.Equal("0.7.0.0", result[0].UpdateVersion);
Assert.Equal("0.6.0", result[1].UpdateVersion);
}
[Fact]
public async Task GetAllReleases_ShouldUseCachedData_WhenCacheIsValid()
{
// Arrange
var releases = new List<UpdateNotificationDto>
{
new()
{
UpdateVersion = "0.6.0",
CurrentVersion = "0.5.0.0",
PublishDate = DateTime.UtcNow.AddDays(-10)
.ToString("o"),
UpdateBody = "",
UpdateTitle = null,
UpdateUrl = null
}
};
releases.Add(new()
{
UpdateVersion = "0.7.0",
CurrentVersion = "0.5.0.0",
PublishDate = DateTime.UtcNow.AddDays(-1)
.ToString("o"),
UpdateBody = "",
UpdateTitle = null,
UpdateUrl = null
});
// Create cache file
var cacheFilePath = Path.Combine(_tempPath, "github_releases_cache.json");
await File.WriteAllTextAsync(cacheFilePath, System.Text.Json.JsonSerializer.Serialize(releases));
File.SetLastWriteTimeUtc(cacheFilePath, DateTime.UtcNow); // Ensure it's fresh
// Act
var result = await _service.GetAllReleases();
// Assert
Assert.Equal(2, result.Count);
Assert.Empty(_httpTest.CallLog); // No HTTP calls made
}
[Fact]
public async Task GetAllReleases_ShouldFetchNewData_WhenCacheIsExpired()
{
// Arrange
var releases = new List<UpdateNotificationDto>
{
new()
{
UpdateVersion = "0.6.0",
CurrentVersion = "0.5.0.0",
PublishDate = DateTime.UtcNow.AddDays(-10)
.ToString("o"),
UpdateBody = null,
UpdateTitle = null,
UpdateUrl = null
}
};
// Create expired cache file
var cacheFilePath = Path.Combine(_tempPath, "github_releases_cache.json");
await File.WriteAllTextAsync(cacheFilePath, System.Text.Json.JsonSerializer.Serialize(releases));
File.SetLastWriteTimeUtc(cacheFilePath, DateTime.UtcNow.AddHours(-2)); // Expired (older than 1 hour)
// Setup HTTP response for new fetch
var newReleases = new List<object>
{
new
{
tag_name = "v0.7.0",
name = "Release 0.7.0",
body = "# Added\n- Feature A",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.7.0",
published_at = DateTime.UtcNow.ToString("o")
}
};
_httpTest.RespondWithJson(newReleases);
// Act
var result = await _service.GetAllReleases();
// Assert
Assert.Equal(1, result.Count);
Assert.Equal("0.7.0.0", result[0].UpdateVersion);
Assert.NotEmpty(_httpTest.CallLog); // HTTP call was made
}
[Fact]
public async Task GetNumberOfReleasesBehind_ShouldReturnCorrectCount()
{
// Arrange
var releases = new List<object>
{
new
{
tag_name = "v0.7.0",
name = "Release 0.7.0",
body = "# Added\n- Feature A",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.7.0",
published_at = DateTime.UtcNow.AddDays(-1).ToString("o")
},
new
{
tag_name = "v0.6.0",
name = "Release 0.6.0",
body = "# Added\n- Feature B",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.6.0",
published_at = DateTime.UtcNow.AddDays(-10).ToString("o")
},
new
{
tag_name = "v0.5.0",
name = "Release 0.5.0",
body = "# Added\n- Feature C",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.5.0",
published_at = DateTime.UtcNow.AddDays(-20).ToString("o")
}
};
_httpTest.RespondWithJson(releases);
// Act
var result = await _service.GetNumberOfReleasesBehind();
// Assert
Assert.Equal(2 + 1, result); // Behind 0.7.0 and 0.6.0 - We have to add 1 because the current release is > 0.7.0
}
[Fact]
public async Task GetNumberOfReleasesBehind_ShouldReturnCorrectCount_WithNightlies()
{
// Arrange
var releases = new List<object>
{
new
{
tag_name = "v0.7.1",
name = "Release 0.7.1",
body = "# Added\n- Feature A",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.7.1",
published_at = DateTime.UtcNow.AddDays(-1).ToString("o")
},
new
{
tag_name = "v0.7.0",
name = "Release 0.7.0",
body = "# Added\n- Feature A",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.7.0",
published_at = DateTime.UtcNow.AddDays(-10).ToString("o")
},
};
_httpTest.RespondWithJson(releases);
// Act
var result = await _service.GetNumberOfReleasesBehind();
// Assert
Assert.Equal(2, result); // We have to add 1 because the current release is > 0.7.0
}
[Fact]
public async Task ParseReleaseBody_ShouldExtractSections()
{
// Arrange
var githubResponse = new
{
tag_name = "v0.6.0",
name = "Release 0.6.0",
body = "This is a great release with many improvements!\n\n# Added\n- Feature 1\n- Feature 2\n# Fixed\n- Bug 1\n- Bug 2\n# Changed\n- Change 1\n# Developer\n- Dev note 1",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.6.0",
published_at = DateTime.UtcNow.ToString("o")
};
_httpTest.RespondWithJson(githubResponse);
// Act
var result = await _service.CheckForUpdate();
// Assert
Assert.NotNull(result);
Assert.Equal(2, result.Added.Count);
Assert.Equal(2, result.Fixed.Count);
Assert.Equal(1, result.Changed.Count);
Assert.Equal(1, result.Developer.Count);
Assert.Contains("This is a great release", result.BlogPart);
}
[Fact]
public async Task GetAllReleases_ShouldHandleNightlyBuilds()
{
// Arrange
// Set BuildInfo.Version to a nightly build version
typeof(BuildInfo).GetProperty(nameof(BuildInfo.Version))?.SetValue(null, new Version("0.7.1.0"));
// Mock regular releases
var releases = new List<object>
{
new
{
tag_name = "v0.7.0",
name = "Release 0.7.0",
body = "# Added\n- Feature A",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.7.0",
published_at = DateTime.UtcNow.AddDays(-1).ToString("o")
},
new
{
tag_name = "v0.6.0",
name = "Release 0.6.0",
body = "# Added\n- Feature B",
html_url = "https://github.com/Kareadita/Kavita/releases/tag/v0.6.0",
published_at = DateTime.UtcNow.AddDays(-10).ToString("o")
}
};
_httpTest.RespondWithJson(releases);
// Mock commit info for develop branch
_httpTest.RespondWithJson(new List<object>());
// Act
var result = await _service.GetAllReleases();
// Assert
Assert.NotNull(result);
Assert.True(result[0].IsOnNightlyInRelease);
}
}

View File

@ -40,8 +40,7 @@ public class UpdateNotificationDto
/// <summary> /// <summary>
/// Date of the publish /// Date of the publish
/// </summary> /// </summary>
public required string PublishDate { get; set public required string PublishDate { get; set; }
; }
/// <summary> /// <summary>
/// Is the server on a nightly within this release /// Is the server on a nightly within this release
/// </summary> /// </summary>

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.Json;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using API.DTOs.Update; using API.DTOs.Update;
@ -68,13 +69,19 @@ public partial class VersionUpdaterService : IVersionUpdaterService
[GeneratedRegex(@"^\n*(.*?)\n+#{1,2}\s", RegexOptions.Singleline)] [GeneratedRegex(@"^\n*(.*?)\n+#{1,2}\s", RegexOptions.Singleline)]
private static partial Regex BlogPartRegex(); private static partial Regex BlogPartRegex();
private readonly string _cacheFilePath; private readonly string _cacheFilePath;
/// <summary>
/// The latest release cache
/// </summary>
private readonly string _cacheLatestReleaseFilePath;
private static readonly TimeSpan CacheDuration = TimeSpan.FromHours(1); private static readonly TimeSpan CacheDuration = TimeSpan.FromHours(1);
private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true };
public VersionUpdaterService(ILogger<VersionUpdaterService> logger, IEventHub eventHub, IDirectoryService directoryService) public VersionUpdaterService(ILogger<VersionUpdaterService> logger, IEventHub eventHub, IDirectoryService directoryService)
{ {
_logger = logger; _logger = logger;
_eventHub = eventHub; _eventHub = eventHub;
_cacheFilePath = Path.Combine(directoryService.LongTermCacheDirectory, "github_releases_cache.json"); _cacheFilePath = Path.Combine(directoryService.LongTermCacheDirectory, "github_releases_cache.json");
_cacheLatestReleaseFilePath = Path.Combine(directoryService.LongTermCacheDirectory, "github_latest_release_cache.json");
FlurlConfiguration.ConfigureClientForUrl(GithubLatestReleasesUrl); FlurlConfiguration.ConfigureClientForUrl(GithubLatestReleasesUrl);
FlurlConfiguration.ConfigureClientForUrl(GithubAllReleasesUrl); FlurlConfiguration.ConfigureClientForUrl(GithubAllReleasesUrl);
@ -86,9 +93,21 @@ public partial class VersionUpdaterService : IVersionUpdaterService
/// <returns>Latest update</returns> /// <returns>Latest update</returns>
public async Task<UpdateNotificationDto?> CheckForUpdate() public async Task<UpdateNotificationDto?> CheckForUpdate()
{ {
// Attempt to fetch from cache
var cachedRelease = await TryGetCachedLatestRelease();
if (cachedRelease != null)
{
return cachedRelease;
}
var update = await GetGithubRelease(); var update = await GetGithubRelease();
var dto = CreateDto(update); var dto = CreateDto(update);
if (dto != null)
{
await CacheLatestReleaseAsync(dto);
}
return dto; return dto;
} }
@ -273,6 +292,13 @@ public partial class VersionUpdaterService : IVersionUpdaterService
var updateDtos = query.ToList(); var updateDtos = query.ToList();
// Sometimes a release can be 0.8.5.0 on disk, but 0.8.5 from Github
var versionParts = updateDtos[0].UpdateVersion.Split('.');
if (versionParts.Length < 4)
{
updateDtos[0].UpdateVersion += ".0"; // Append missing parts
}
// If we're on a nightly build, enrich the information // If we're on a nightly build, enrich the information
if (updateDtos.Count != 0 && BuildInfo.Version > new Version(updateDtos[0].UpdateVersion)) if (updateDtos.Count != 0 && BuildInfo.Version > new Version(updateDtos[0].UpdateVersion))
{ {
@ -321,11 +347,25 @@ public partial class VersionUpdaterService : IVersionUpdaterService
return null; return null;
} }
private async Task<UpdateNotificationDto?> TryGetCachedLatestRelease()
{
if (!File.Exists(_cacheLatestReleaseFilePath)) return null;
var fileInfo = new FileInfo(_cacheLatestReleaseFilePath);
if (DateTime.UtcNow - fileInfo.LastWriteTimeUtc <= CacheDuration)
{
var cachedData = await File.ReadAllTextAsync(_cacheLatestReleaseFilePath);
return System.Text.Json.JsonSerializer.Deserialize<UpdateNotificationDto>(cachedData);
}
return null;
}
private async Task CacheReleasesAsync(IList<UpdateNotificationDto> updates) private async Task CacheReleasesAsync(IList<UpdateNotificationDto> updates)
{ {
try try
{ {
var json = System.Text.Json.JsonSerializer.Serialize(updates, new System.Text.Json.JsonSerializerOptions { WriteIndented = true }); var json = System.Text.Json.JsonSerializer.Serialize(updates, JsonOptions);
await File.WriteAllTextAsync(_cacheFilePath, json); await File.WriteAllTextAsync(_cacheFilePath, json);
} }
catch (Exception ex) catch (Exception ex)
@ -334,6 +374,19 @@ public partial class VersionUpdaterService : IVersionUpdaterService
} }
} }
private async Task CacheLatestReleaseAsync(UpdateNotificationDto update)
{
try
{
var json = System.Text.Json.JsonSerializer.Serialize(update, JsonOptions);
await File.WriteAllTextAsync(_cacheLatestReleaseFilePath, json);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to cache latest release");
}
}
private static bool IsVersionEqualToBuildVersion(Version updateVersion) private static bool IsVersionEqualToBuildVersion(Version updateVersion)
@ -346,7 +399,10 @@ public partial class VersionUpdaterService : IVersionUpdaterService
public async Task<int> GetNumberOfReleasesBehind() public async Task<int> GetNumberOfReleasesBehind()
{ {
var updates = await GetAllReleases(); var updates = await GetAllReleases();
return updates.TakeWhile(update => update.UpdateVersion != update.CurrentVersion).Count(); return updates
.Where(update => !update.IsPrerelease)
.TakeWhile(update => update.UpdateVersion != update.CurrentVersion)
.Count();
} }
private UpdateNotificationDto? CreateDto(GithubReleaseMetadata? update) private UpdateNotificationDto? CreateDto(GithubReleaseMetadata? update)
@ -370,6 +426,7 @@ public partial class VersionUpdaterService : IVersionUpdaterService
PublishDate = update.Published_At, PublishDate = update.Published_At,
IsReleaseEqual = IsVersionEqualToBuildVersion(updateVersion), IsReleaseEqual = IsVersionEqualToBuildVersion(updateVersion),
IsReleaseNewer = BuildInfo.Version < updateVersion, IsReleaseNewer = BuildInfo.Version < updateVersion,
IsPrerelease = false,
Added = parsedSections.TryGetValue("Added", out var added) ? added : [], Added = parsedSections.TryGetValue("Added", out var added) ? added : [],
Removed = parsedSections.TryGetValue("Removed", out var removed) ? removed : [], Removed = parsedSections.TryGetValue("Removed", out var removed) ? removed : [],

View File

@ -3,7 +3,7 @@
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<Company>kavitareader.com</Company> <Company>kavitareader.com</Company>
<Product>Kavita</Product> <Product>Kavita</Product>
<AssemblyVersion>0.8.5.0</AssemblyVersion> <AssemblyVersion>0.8.5.1</AssemblyVersion>
<NeutralLanguage>en</NeutralLanguage> <NeutralLanguage>en</NeutralLanguage>
<InvariantGlobalization>true</InvariantGlobalization> <InvariantGlobalization>true</InvariantGlobalization>
<TieredPGO>true</TieredPGO> <TieredPGO>true</TieredPGO>
@ -21,4 +21,4 @@
</PackageReference> </PackageReference>
<PackageReference Include="xunit.assert" Version="2.9.3" /> <PackageReference Include="xunit.assert" Version="2.9.3" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -19,6 +19,6 @@ export enum WikiLink {
Library = 'https://wiki.kavitareader.com/guides/admin-settings/libraries', Library = 'https://wiki.kavitareader.com/guides/admin-settings/libraries',
UpdateNative = 'https://wiki.kavitareader.com/guides/updating/updating-native', UpdateNative = 'https://wiki.kavitareader.com/guides/updating/updating-native',
UpdateDocker = 'https://wiki.kavitareader.com/guides/updating/updating-docker', UpdateDocker = 'https://wiki.kavitareader.com/guides/updating/updating-docker',
OpdsClients = 'https://wiki.kavitareader.com/guides/opds#opds-capable-clients', OpdsClients = 'https://wiki.kavitareader.com/guides/features/opds/#opds-capable-clients',
Guides = 'https://wiki.kavitareader.com/guides' Guides = 'https://wiki.kavitareader.com/guides'
} }

View File

@ -18,8 +18,7 @@ import { EVENTS, MessageHubService } from 'src/app/_services/message-hub.service
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import {takeUntilDestroyed} from "@angular/core/rxjs-interop"; import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
import { FilterPipe } from '../../_pipes/filter.pipe'; import { FilterPipe } from '../../_pipes/filter.pipe';
import { LoadingComponent } from '../../shared/loading/loading.component'; import {TranslocoDirective} from "@jsverse/transloco";
import {translate, TranslocoDirective} from "@jsverse/transloco";
import {WikiLink} from "../../_models/wiki"; import {WikiLink} from "../../_models/wiki";
import {UtcToLocalTimePipe} from "../../_pipes/utc-to-local-time.pipe"; import {UtcToLocalTimePipe} from "../../_pipes/utc-to-local-time.pipe";
import {DefaultDatePipe} from "../../_pipes/default-date.pipe"; import {DefaultDatePipe} from "../../_pipes/default-date.pipe";
@ -31,10 +30,12 @@ import {ColumnMode, NgxDatatableModule} from "@siemens/ngx-datatable";
styleUrls: ['./manage-media-issues.component.scss'], styleUrls: ['./manage-media-issues.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true, standalone: true,
imports: [ReactiveFormsModule, LoadingComponent, FilterPipe, SortableHeader, TranslocoDirective, UtcToLocalTimePipe, DefaultDatePipe, NgxDatatableModule] imports: [ReactiveFormsModule, FilterPipe, TranslocoDirective, UtcToLocalTimePipe, DefaultDatePipe, NgxDatatableModule]
}) })
export class ManageMediaIssuesComponent implements OnInit { export class ManageMediaIssuesComponent implements OnInit {
protected readonly ColumnMode = ColumnMode;
@Output() alertCount = new EventEmitter<number>(); @Output() alertCount = new EventEmitter<number>();
@ViewChildren(SortableHeader<KavitaMediaError>) headers!: QueryList<SortableHeader<KavitaMediaError>>; @ViewChildren(SortableHeader<KavitaMediaError>) headers!: QueryList<SortableHeader<KavitaMediaError>>;
@ -70,17 +71,6 @@ export class ManageMediaIssuesComponent implements OnInit {
}); });
} }
onSort(evt: any) {
//SortEvent<KavitaMediaError>
this.currentSort.next(evt);
// Must clear out headers here
this.headers.forEach((header) => {
if (header.sortable !== evt.column) {
header.direction = '';
}
});
}
loadData() { loadData() {
this.isLoading = true; this.isLoading = true;
@ -101,6 +91,5 @@ export class ManageMediaIssuesComponent implements OnInit {
const query = (this.formGroup.get('filter')?.value || '').toLowerCase(); const query = (this.formGroup.get('filter')?.value || '').toLowerCase();
return listItem.comment.toLowerCase().indexOf(query) >= 0 || listItem.filePath.toLowerCase().indexOf(query) >= 0 || listItem.details.indexOf(query) >= 0; return listItem.comment.toLowerCase().indexOf(query) >= 0 || listItem.filePath.toLowerCase().indexOf(query) >= 0 || listItem.details.indexOf(query) >= 0;
} }
protected readonly ColumnMode = ColumnMode;
protected readonly translate = translate;
} }