diff --git a/API.Tests/Services/ReaderServiceTests.cs b/API.Tests/Services/ReaderServiceTests.cs
index d4edddf72..f12472c5b 100644
--- a/API.Tests/Services/ReaderServiceTests.cs
+++ b/API.Tests/Services/ReaderServiceTests.cs
@@ -1569,6 +1569,61 @@ public class ReaderServiceTests
Assert.Equal("Some Special Title", nextChapter.Range);
}
+ [Fact]
+ public async Task GetContinuePoint_ShouldReturnFirstVolumeChapter_WhenPreExistingProgress()
+ {
+ var series = new Series()
+ {
+ Name = "Test",
+ Library = new Library()
+ {
+ Name = "Test LIb",
+ Type = LibraryType.Manga,
+ },
+ Volumes = new List()
+ {
+ EntityFactory.CreateVolume("0", new List()
+ {
+ EntityFactory.CreateChapter("230", false, new List(), 1),
+ //EntityFactory.CreateChapter("231", false, new List(), 1), (added later)
+ }),
+ EntityFactory.CreateVolume("1", new List()
+ {
+ EntityFactory.CreateChapter("1", false, new List(), 1),
+ EntityFactory.CreateChapter("2", false, new List(), 1),
+ }),
+ EntityFactory.CreateVolume("2", new List()
+ {
+ EntityFactory.CreateChapter("0", false, new List(), 1),
+ //EntityFactory.CreateChapter("14.9", false, new List(), 1), (added later)
+ }),
+ }
+ };
+ _context.Series.Add(series);
+
+ _context.AppUser.Add(new AppUser()
+ {
+ UserName = "majora2007"
+ });
+
+ await _context.SaveChangesAsync();
+
+
+ var readerService = new ReaderService(_unitOfWork, Substitute.For>());
+ var user = await _unitOfWork.UserRepository.GetUserByIdAsync(1, AppUserIncludes.Progress);
+ await readerService.MarkSeriesAsRead(user, 1);
+ await _context.SaveChangesAsync();
+
+ // Add 2 new unread series to the Series
+ series.Volumes[0].Chapters.Add(EntityFactory.CreateChapter("231", false, new List(), 1));
+ series.Volumes[2].Chapters.Add(EntityFactory.CreateChapter("14.9", false, new List(), 1));
+ _context.Series.Attach(series);
+ await _context.SaveChangesAsync();
+
+ var nextChapter = await readerService.GetContinuePoint(1, 1);
+ Assert.Equal("14.9", nextChapter.Range);
+ }
+
#endregion
#region MarkChaptersUntilAsRead
@@ -1702,5 +1757,126 @@ public class ReaderServiceTests
#endregion
+ #region MarkSeriesAsRead
+ [Fact]
+ public async Task MarkSeriesAsReadTest()
+ {
+ await ResetDB();
+
+ _context.Series.Add(new Series()
+ {
+ Name = "Test",
+ Library = new Library() {
+ Name = "Test LIb",
+ Type = LibraryType.Manga,
+ },
+ Volumes = new List()
+ {
+ new Volume()
+ {
+ Chapters = new List()
+ {
+ new Chapter()
+ {
+ Pages = 1
+ },
+ new Chapter()
+ {
+ Pages = 2
+ }
+ }
+ },
+ new Volume()
+ {
+ Chapters = new List()
+ {
+ new Chapter()
+ {
+ Pages = 1
+ },
+ new Chapter()
+ {
+ Pages = 2
+ }
+ }
+ }
+ }
+ });
+
+ _context.AppUser.Add(new AppUser()
+ {
+ UserName = "majora2007"
+ });
+
+ await _context.SaveChangesAsync();
+
+ var readerService = new ReaderService(_unitOfWork, Substitute.For>());
+
+ await readerService.MarkSeriesAsRead(await _unitOfWork.UserRepository.GetUserByIdAsync(1, AppUserIncludes.Progress), 1);
+ await _context.SaveChangesAsync();
+
+ Assert.Equal(4, (await _unitOfWork.UserRepository.GetUserByIdAsync(1, AppUserIncludes.Progress)).Progresses.Count);
+ }
+
+
+ #endregion
+
+ #region MarkSeriesAsUnread
+
+ [Fact]
+ public async Task MarkSeriesAsUnreadTest()
+ {
+ await ResetDB();
+
+ _context.Series.Add(new Series()
+ {
+ Name = "Test",
+ Library = new Library() {
+ Name = "Test LIb",
+ Type = LibraryType.Manga,
+ },
+ Volumes = new List()
+ {
+ new Volume()
+ {
+ Chapters = new List()
+ {
+ new Chapter()
+ {
+ Pages = 1
+ },
+ new Chapter()
+ {
+ Pages = 2
+ }
+ }
+ }
+ }
+ });
+
+ _context.AppUser.Add(new AppUser()
+ {
+ UserName = "majora2007"
+ });
+
+ await _context.SaveChangesAsync();
+
+ var readerService = new ReaderService(_unitOfWork, Substitute.For>());
+
+ var volumes = (await _unitOfWork.VolumeRepository.GetVolumes(1)).ToList();
+ readerService.MarkChaptersAsRead(await _unitOfWork.UserRepository.GetUserByIdAsync(1, AppUserIncludes.Progress), 1, volumes.First().Chapters);
+
+ await _context.SaveChangesAsync();
+ Assert.Equal(2, (await _unitOfWork.UserRepository.GetUserByIdAsync(1, AppUserIncludes.Progress)).Progresses.Count);
+
+ await readerService.MarkSeriesAsUnread(await _unitOfWork.UserRepository.GetUserByIdAsync(1, AppUserIncludes.Progress), 1);
+ await _context.SaveChangesAsync();
+
+ var progresses = (await _unitOfWork.UserRepository.GetUserByIdAsync(1, AppUserIncludes.Progress)).Progresses;
+ Assert.Equal(0, progresses.Max(p => p.PagesRead));
+ Assert.Equal(2, progresses.Count);
+ }
+
+ #endregion
}
diff --git a/API/Controllers/AccountController.cs b/API/Controllers/AccountController.cs
index 913f53133..7fc8769e7 100644
--- a/API/Controllers/AccountController.cs
+++ b/API/Controllers/AccountController.cs
@@ -338,6 +338,12 @@ namespace API.Controllers
+ ///
+ /// Invites a user to the server. Will generate a setup link for continuing setup. If the server is not accessible, no
+ /// email will be sent.
+ ///
+ ///
+ ///
[Authorize(Policy = "RequireAdminRole")]
[HttpPost("invite")]
public async Task> InviteUser(InviteUserDto dto)
@@ -417,7 +423,9 @@ namespace API.Controllers
var emailLink = GenerateEmailLink(token, "confirm-email", dto.Email);
_logger.LogCritical("[Invite User]: Email Link for {UserName}: {Link}", user.UserName, emailLink);
- if (dto.SendEmail)
+ var host = _environment.IsDevelopment() ? "localhost:4200" : Request.Host.ToString();
+ var accessible = await _emailService.CheckIfAccessible(host);
+ if (accessible)
{
await _emailService.SendConfirmationEmail(new ConfirmationEmailDto()
{
@@ -426,7 +434,11 @@ namespace API.Controllers
ServerConfirmationLink = emailLink
});
}
- return Ok(emailLink);
+ return Ok(new InviteUserResponse
+ {
+ EmailLink = emailLink,
+ EmailSent = accessible
+ });
}
catch (Exception)
{
diff --git a/API/Controllers/ReaderController.cs b/API/Controllers/ReaderController.cs
index a8a34bdfd..fa3be9c05 100644
--- a/API/Controllers/ReaderController.cs
+++ b/API/Controllers/ReaderController.cs
@@ -109,14 +109,7 @@ namespace API.Controllers
public async Task MarkRead(MarkReadDto markReadDto)
{
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername(), AppUserIncludes.Progress);
- var volumes = await _unitOfWork.VolumeRepository.GetVolumes(markReadDto.SeriesId);
- user.Progresses ??= new List();
- foreach (var volume in volumes)
- {
- _readerService.MarkChaptersAsRead(user, markReadDto.SeriesId, volume.Chapters);
- }
-
- _unitOfWork.UserRepository.Update(user);
+ await _readerService.MarkSeriesAsRead(user, markReadDto.SeriesId);
if (await _unitOfWork.CommitAsync())
{
@@ -137,14 +130,7 @@ namespace API.Controllers
public async Task MarkUnread(MarkReadDto markReadDto)
{
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername(), AppUserIncludes.Progress);
- var volumes = await _unitOfWork.VolumeRepository.GetVolumes(markReadDto.SeriesId);
- user.Progresses ??= new List();
- foreach (var volume in volumes)
- {
- _readerService.MarkChaptersAsUnread(user, markReadDto.SeriesId, volume.Chapters);
- }
-
- _unitOfWork.UserRepository.Update(user);
+ await _readerService.MarkSeriesAsUnread(user, markReadDto.SeriesId);
if (await _unitOfWork.CommitAsync())
{
diff --git a/API/DTOs/Account/InviteUserDto.cs b/API/DTOs/Account/InviteUserDto.cs
index 04c9c1103..42d4bdf8e 100644
--- a/API/DTOs/Account/InviteUserDto.cs
+++ b/API/DTOs/Account/InviteUserDto.cs
@@ -16,6 +16,4 @@ public class InviteUserDto
/// A list of libraries to grant access to
///
public IList Libraries { get; init; }
-
- public bool SendEmail { get; init; } = true;
}
diff --git a/API/DTOs/Account/InviteUserResponse.cs b/API/DTOs/Account/InviteUserResponse.cs
new file mode 100644
index 000000000..9387b5492
--- /dev/null
+++ b/API/DTOs/Account/InviteUserResponse.cs
@@ -0,0 +1,13 @@
+namespace API.DTOs.Account;
+
+public class InviteUserResponse
+{
+ ///
+ /// Email link used to setup the user account
+ ///
+ public string EmailLink { get; set; }
+ ///
+ /// Was an email sent (ie is this server accessible)
+ ///
+ public bool EmailSent { get; set; }
+}
diff --git a/API/DTOs/Filtering/FilterDto.cs b/API/DTOs/Filtering/FilterDto.cs
index fba9a7493..90ad52759 100644
--- a/API/DTOs/Filtering/FilterDto.cs
+++ b/API/DTOs/Filtering/FilterDto.cs
@@ -25,51 +25,51 @@ namespace API.DTOs.Filtering
///
public IList Genres { get; init; } = new List();
///
- /// A list of Writers to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of Writers to restrict search to. Defaults to all Writers by passing an empty list
///
public IList Writers { get; init; } = new List();
///
- /// A list of Penciller ids to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of Penciller ids to restrict search to. Defaults to all Pencillers by passing an empty list
///
public IList Penciller { get; init; } = new List();
///
- /// A list of Inker ids to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of Inker ids to restrict search to. Defaults to all Inkers by passing an empty list
///
public IList Inker { get; init; } = new List();
///
- /// A list of Colorist ids to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of Colorist ids to restrict search to. Defaults to all Colorists by passing an empty list
///
public IList Colorist { get; init; } = new List();
///
- /// A list of Letterer ids to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of Letterer ids to restrict search to. Defaults to all Letterers by passing an empty list
///
public IList Letterer { get; init; } = new List();
///
- /// A list of CoverArtist ids to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of CoverArtist ids to restrict search to. Defaults to all CoverArtists by passing an empty list
///
public IList CoverArtist { get; init; } = new List();
///
- /// A list of Editor ids to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of Editor ids to restrict search to. Defaults to all Editors by passing an empty list
///
public IList Editor { get; init; } = new List();
///
- /// A list of Publisher ids to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of Publisher ids to restrict search to. Defaults to all Publishers by passing an empty list
///
public IList Publisher { get; init; } = new List();
///
- /// A list of Character ids to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of Character ids to restrict search to. Defaults to all Characters by passing an empty list
///
public IList Character { get; init; } = new List();
///
- /// A list of Translator ids to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of Translator ids to restrict search to. Defaults to all Translatorss by passing an empty list
///
public IList Translators { get; init; } = new List();
///
- /// A list of Collection Tag ids to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of Collection Tag ids to restrict search to. Defaults to all Collection Tags by passing an empty list
///
public IList CollectionTags { get; init; } = new List();
///
- /// A list of Tag ids to restrict search to. Defaults to all genres by passing an empty list
+ /// A list of Tag ids to restrict search to. Defaults to all Tags by passing an empty list
///
public IList Tags { get; init; } = new List();
///
diff --git a/API/DTOs/Reader/ChapterInfoDto.cs b/API/DTOs/Reader/ChapterInfoDto.cs
index 7c847d926..9f33bada7 100644
--- a/API/DTOs/Reader/ChapterInfoDto.cs
+++ b/API/DTOs/Reader/ChapterInfoDto.cs
@@ -12,6 +12,7 @@ namespace API.DTOs.Reader
public MangaFormat SeriesFormat { get; set; }
public int SeriesId { get; set; }
public int LibraryId { get; set; }
+ public LibraryType LibraryType { get; set; }
public string ChapterTitle { get; set; } = string.Empty;
public int Pages { get; set; }
public string FileName { get; set; }
diff --git a/API/Data/Repositories/ChapterRepository.cs b/API/Data/Repositories/ChapterRepository.cs
index 330aa4b5e..ab3684fa0 100644
--- a/API/Data/Repositories/ChapterRepository.cs
+++ b/API/Data/Repositories/ChapterRepository.cs
@@ -81,7 +81,8 @@ public class ChapterRepository : IChapterRepository
data.TitleName,
SeriesFormat = series.Format,
SeriesName = series.Name,
- series.LibraryId
+ series.LibraryId,
+ LibraryType = series.Library.Type
})
.Select(data => new ChapterInfoDto()
{
@@ -89,12 +90,13 @@ public class ChapterRepository : IChapterRepository
VolumeNumber = data.VolumeNumber + string.Empty,
VolumeId = data.VolumeId,
IsSpecial = data.IsSpecial,
- SeriesId =data.SeriesId,
+ SeriesId = data.SeriesId,
SeriesFormat = data.SeriesFormat,
SeriesName = data.SeriesName,
LibraryId = data.LibraryId,
Pages = data.Pages,
- ChapterTitle = data.TitleName
+ ChapterTitle = data.TitleName,
+ LibraryType = data.LibraryType
})
.AsNoTracking()
.AsSplitQuery()
diff --git a/API/Data/Repositories/SeriesRepository.cs b/API/Data/Repositories/SeriesRepository.cs
index efe2f1a27..d70681b46 100644
--- a/API/Data/Repositories/SeriesRepository.cs
+++ b/API/Data/Repositories/SeriesRepository.cs
@@ -79,8 +79,8 @@ public interface ISeriesRepository
///
Task AddSeriesModifiers(int userId, List series);
Task GetSeriesCoverImageAsync(int seriesId);
- Task> GetOnDeck(int userId, int libraryId, UserParams userParams, FilterDto filter);
- Task> GetRecentlyAdded(int libraryId, int userId, UserParams userParams, FilterDto filter); // NOTE: Probably put this in LibraryRepo
+ Task> GetOnDeck(int userId, int libraryId, UserParams userParams, FilterDto filter, bool cutoffOnDate = true);
+ Task> GetRecentlyAdded(int libraryId, int userId, UserParams userParams, FilterDto filter);
Task GetSeriesMetadata(int seriesId);
Task> GetSeriesDtoForCollectionAsync(int collectionId, int userId, UserParams userParams);
Task> GetFilesForSeries(int seriesId);
@@ -593,11 +593,11 @@ public class SeriesRepository : ISeriesRepository
/// Pagination information
/// Optional (default null) filter on query
///
- public async Task> GetOnDeck(int userId, int libraryId, UserParams userParams, FilterDto filter)
+ public async Task> GetOnDeck(int userId, int libraryId, UserParams userParams, FilterDto filter, bool cutoffOnDate = true)
{
//var allSeriesWithProgress = await _context.AppUserProgresses.Select(p => p.SeriesId).ToListAsync();
//var allChapters = await GetChapterIdsForSeriesAsync(allSeriesWithProgress);
- var cuttoffProgressPoint = DateTime.Now - TimeSpan.FromDays(30);
+ var cutoffProgressPoint = DateTime.Now - TimeSpan.FromDays(30);
var query = (await CreateFilteredSearchQueryable(userId, libraryId, filter))
.Join(_context.AppUserProgresses, s => s.Id, progress => progress.SeriesId, (s, progress) =>
new
@@ -612,8 +612,12 @@ public class SeriesRepository : ISeriesRepository
// This is only taking into account chapters that have progress on them, not all chapters in said series
LastChapterCreated = _context.Chapter.Where(c => progress.ChapterId == c.Id).Max(c => c.Created)
//LastChapterCreated = _context.Chapter.Where(c => allChapters.Contains(c.Id)).Max(c => c.Created)
- })
- .Where(d => d.LastReadingProgress >= cuttoffProgressPoint);
+ });
+ if (cutoffOnDate)
+ {
+ query = query.Where(d => d.LastReadingProgress >= cutoffProgressPoint);
+ }
+
// I think I need another Join statement. The problem is the chapters are still limited to progress
diff --git a/API/Services/EmailService.cs b/API/Services/EmailService.cs
index ab2c52a2c..c5ba90464 100644
--- a/API/Services/EmailService.cs
+++ b/API/Services/EmailService.cs
@@ -98,7 +98,7 @@ public class EmailService : IEmailService
return await SendEmailWithPost(emailLink + "/api/email/email-password-reset", data);
}
- private static async Task SendEmailWithGet(string url)
+ private static async Task SendEmailWithGet(string url, int timeoutSecs = 30)
{
try
{
@@ -108,7 +108,7 @@ public class EmailService : IEmailService
.WithHeader("x-api-key", "MsnvA2DfQqxSK5jh")
.WithHeader("x-kavita-version", BuildInfo.Version)
.WithHeader("Content-Type", "application/json")
- .WithTimeout(TimeSpan.FromSeconds(30))
+ .WithTimeout(TimeSpan.FromSeconds(timeoutSecs))
.GetStringAsync();
if (!string.IsNullOrEmpty(response) && bool.Parse(response))
@@ -124,7 +124,7 @@ public class EmailService : IEmailService
}
- private static async Task SendEmailWithPost(string url, object data)
+ private static async Task SendEmailWithPost(string url, object data, int timeoutSecs = 30)
{
try
{
@@ -134,7 +134,7 @@ public class EmailService : IEmailService
.WithHeader("x-api-key", "MsnvA2DfQqxSK5jh")
.WithHeader("x-kavita-version", BuildInfo.Version)
.WithHeader("Content-Type", "application/json")
- .WithTimeout(TimeSpan.FromSeconds(30))
+ .WithTimeout(TimeSpan.FromSeconds(timeoutSecs))
.PostJsonAsync(data);
if (response.StatusCode != StatusCodes.Status200OK)
diff --git a/API/Services/ReaderService.cs b/API/Services/ReaderService.cs
index 4e73b422e..3e6fe06a5 100644
--- a/API/Services/ReaderService.cs
+++ b/API/Services/ReaderService.cs
@@ -16,6 +16,8 @@ namespace API.Services;
public interface IReaderService
{
+ Task MarkSeriesAsRead(AppUser user, int seriesId);
+ Task MarkSeriesAsUnread(AppUser user, int seriesId);
void MarkChaptersAsRead(AppUser user, int seriesId, IEnumerable chapters);
void MarkChaptersAsUnread(AppUser user, int seriesId, IEnumerable chapters);
Task SaveReadingProgress(ProgressDto progressDto, int userId);
@@ -45,6 +47,40 @@ public class ReaderService : IReaderService
return Parser.Parser.NormalizePath(Path.Join(baseDirectory, $"{userId}", $"{seriesId}", $"{chapterId}"));
}
+ ///
+ /// Does not commit. Marks all entities under the series as read.
+ ///
+ ///
+ ///
+ public async Task MarkSeriesAsRead(AppUser user, int seriesId)
+ {
+ var volumes = await _unitOfWork.VolumeRepository.GetVolumes(seriesId);
+ user.Progresses ??= new List();
+ foreach (var volume in volumes)
+ {
+ MarkChaptersAsRead(user, seriesId, volume.Chapters);
+ }
+
+ _unitOfWork.UserRepository.Update(user);
+ }
+
+ ///
+ /// Does not commit. Marks all entities under the series as unread.
+ ///
+ ///
+ ///
+ public async Task MarkSeriesAsUnread(AppUser user, int seriesId)
+ {
+ var volumes = await _unitOfWork.VolumeRepository.GetVolumes(seriesId);
+ user.Progresses ??= new List();
+ foreach (var volume in volumes)
+ {
+ MarkChaptersAsUnread(user, seriesId, volume.Chapters);
+ }
+
+ _unitOfWork.UserRepository.Update(user);
+ }
+
///
/// Marks all Chapters as Read by creating or updating UserProgress rows. Does not commit.
///
@@ -364,7 +400,7 @@ public class ReaderService : IReaderService
.ToList();
// If there are any volumes that have progress, return those. If not, move on.
- var currentlyReadingChapter = volumeChapters.FirstOrDefault(chapter => chapter.PagesRead < chapter.Pages && chapter.PagesRead > 0);
+ var currentlyReadingChapter = volumeChapters.FirstOrDefault(chapter => chapter.PagesRead < chapter.Pages); // (removed for GetContinuePoint_ShouldReturnFirstVolumeChapter_WhenPreExistingProgress), not sure if needed && chapter.PagesRead > 0
if (currentlyReadingChapter != null) return currentlyReadingChapter;
// Check loose leaf chapters (and specials). First check if there are any
diff --git a/UI/Web/src/app/_models/invite-user-response.ts b/UI/Web/src/app/_models/invite-user-response.ts
new file mode 100644
index 000000000..a9042c555
--- /dev/null
+++ b/UI/Web/src/app/_models/invite-user-response.ts
@@ -0,0 +1,10 @@
+export interface InviteUserResponse {
+ /**
+ * Link to register new user
+ */
+ emailLink: string;
+ /**
+ * If an email was sent to the invited user
+ */
+ emailSent: boolean;
+}
\ No newline at end of file
diff --git a/UI/Web/src/app/_services/account.service.ts b/UI/Web/src/app/_services/account.service.ts
index 791c6643a..df5555f41 100644
--- a/UI/Web/src/app/_services/account.service.ts
+++ b/UI/Web/src/app/_services/account.service.ts
@@ -8,6 +8,7 @@ import { User } from '../_models/user';
import { Router } from '@angular/router';
import { MessageHubService } from './message-hub.service';
import { ThemeService } from '../theme.service';
+import { InviteUserResponse } from '../_models/invite-user-response';
@Injectable({
providedIn: 'root'
@@ -134,8 +135,8 @@ export class AccountService implements OnDestroy {
return this.httpClient.post(this.baseUrl + 'account/resend-confirmation-email?userId=' + userId, {}, {responseType: 'text' as 'json'});
}
- inviteUser(model: {email: string, roles: Array, libraries: Array, sendEmail: boolean}) {
- return this.httpClient.post(this.baseUrl + 'account/invite', model, {responseType: 'text' as 'json'});
+ inviteUser(model: {email: string, roles: Array, libraries: Array}) {
+ return this.httpClient.post(this.baseUrl + 'account/invite', model);
}
confirmEmail(model: {email: string, username: string, password: string, token: string}) {
diff --git a/UI/Web/src/app/admin/admin.module.ts b/UI/Web/src/app/admin/admin.module.ts
index 8baed6a00..d594cbff3 100644
--- a/UI/Web/src/app/admin/admin.module.ts
+++ b/UI/Web/src/app/admin/admin.module.ts
@@ -19,6 +19,7 @@ import { InviteUserComponent } from './invite-user/invite-user.component';
import { RoleSelectorComponent } from './role-selector/role-selector.component';
import { LibrarySelectorComponent } from './library-selector/library-selector.component';
import { EditUserComponent } from './edit-user/edit-user.component';
+import { UserSettingsModule } from '../user-settings/user-settings.module';
@@ -49,7 +50,8 @@ import { EditUserComponent } from './edit-user/edit-user.component';
NgbTooltipModule,
NgbDropdownModule,
SharedModule,
- PipeModule
+ PipeModule,
+ UserSettingsModule // API-key componet
],
providers: []
})
diff --git a/UI/Web/src/app/admin/invite-user/invite-user.component.html b/UI/Web/src/app/admin/invite-user/invite-user.component.html
index 83fbb86eb..495b3f6e9 100644
--- a/UI/Web/src/app/admin/invite-user/invite-user.component.html
+++ b/UI/Web/src/app/admin/invite-user/invite-user.component.html
@@ -9,13 +9,7 @@
Invite a user to your server. Enter their email in and we will send them an email to create an account.
-
-
- Checking accessibility of server...
-
-
-
-