chore(client): delete old service files replaced by API clients

Delete old service interfaces and implementations that have been
replaced by the new typed API clients:
- ISearchService/SearchService -> ISearchApiClient/SearchApiClient
- ILookupService/LookupService -> ILookupApiClient/LookupApiClient
- IFileService/FileService -> IFileApiClient/FileApiClient

Also remove unused IFileService injection from SearchEdit.razor
(download functionality now uses SearchApi.GetResultsAsync).
This commit is contained in:
Joseph Doherty
2026-01-06 10:38:41 -05:00
parent 6701da137d
commit 4e1cd2c221
7 changed files with 0 additions and 448 deletions
@@ -5,7 +5,6 @@
@using JdeScoping.Client.Extensions
@inject ISearchApiClient SearchApi
@inject IHubConnectionService HubConnection
@inject IFileService FileService
@inject AuthStateProvider AuthStateProvider
@inject NavigationManager NavigationManager
@inject DialogService DialogService
@@ -1,115 +0,0 @@
using System.Net.Http.Json;
using JdeScoping.Client.Models;
using JdeScoping.Core.ViewModels;
using Microsoft.JSInterop;
namespace JdeScoping.Client.Services;
/// <summary>
/// Handles file upload/download operations via the api/fileio endpoints.
/// Authentication is handled via cookies (sent automatically by the browser).
/// </summary>
public class FileService : IFileService
{
private readonly HttpClient _httpClient;
private readonly IJSRuntime _jsRuntime;
public FileService(HttpClient httpClient, IJSRuntime jsRuntime)
{
_httpClient = httpClient;
_jsRuntime = jsRuntime;
}
public async Task DownloadTemplateAsync(string templateType, object? existingData = null)
{
try
{
// Map template type to API endpoint
var endpoint = templateType switch
{
"work-orders" or "workorders" => "api/fileio/workorders/download",
"items" or "part-numbers" => "api/fileio/items/download",
"component-lots" or "componentlots" => "api/fileio/componentlots/download",
"part-operations" or "partoperations" => "api/fileio/partoperations/download",
_ => throw new ArgumentException($"Unknown template type: {templateType}")
};
var fileName = templateType switch
{
"work-orders" or "workorders" => "work_order_template.xlsx",
"items" or "part-numbers" => "item_number_template.xlsx",
"component-lots" or "componentlots" => "component_lot_template.xlsx",
"part-operations" or "partoperations" => "item_operations_mis_template.xlsx",
_ => $"{templateType}_template.xlsx"
};
// POST with existing data to get the Excel file
var response = await _httpClient.PostAsJsonAsync(endpoint, existingData);
if (response.IsSuccessStatusCode)
{
var bytes = await response.Content.ReadAsByteArrayAsync();
await _jsRuntime.InvokeVoidAsync("downloadFile", fileName, bytes);
}
else
{
Console.WriteLine($"Failed to download template: {response.StatusCode}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Failed to download template: {ex.Message}");
}
}
public async Task DownloadPartNumberTemplateAsync(List<ItemViewModel>? existingItems = null)
{
await DownloadTemplateAsync("items", existingItems);
}
public async Task<UploadResult<T>> UploadAsync<T>(string uploadType, Stream fileStream, string fileName)
{
try
{
// Map upload type to API endpoint
var endpoint = uploadType switch
{
"work-orders" or "workorders" => "api/fileio/workorders/upload",
"items" or "part-numbers" => "api/fileio/items/upload",
"component-lots" or "componentlots" => "api/fileio/componentlots/upload",
"part-operations" or "partoperations" => "api/fileio/partoperations/upload",
_ => throw new ArgumentException($"Unknown upload type: {uploadType}")
};
using var content = new MultipartFormDataContent();
using var streamContent = new StreamContent(fileStream);
content.Add(streamContent, "file", fileName);
var response = await _httpClient.PostAsync(endpoint, content);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadFromJsonAsync<UploadResult<T>>();
return result ?? new UploadResult<T>
{
WasSuccessful = false,
ErrorMessage = "Invalid response from server"
};
}
return new UploadResult<T>
{
WasSuccessful = false,
ErrorMessage = $"Upload failed: {response.StatusCode}"
};
}
catch (Exception ex)
{
return new UploadResult<T>
{
WasSuccessful = false,
ErrorMessage = $"Upload failed: {ex.Message}"
};
}
}
}
@@ -1,35 +0,0 @@
using JdeScoping.Client.Models;
using JdeScoping.Core.ViewModels;
namespace JdeScoping.Client.Services;
/// <summary>
/// Service for file upload/download operations.
/// </summary>
public interface IFileService
{
/// <summary>
/// Downloads the work order template file.
/// </summary>
Task DownloadTemplateAsync(string templateType, object? existingData = null);
/// <summary>
/// Downloads the part number template file.
/// </summary>
Task DownloadPartNumberTemplateAsync(List<ItemViewModel>? existingItems = null);
/// <summary>
/// Uploads a file and returns parsed data.
/// </summary>
Task<UploadResult<T>> UploadAsync<T>(string uploadType, Stream fileStream, string fileName);
}
/// <summary>
/// Result of a file upload operation.
/// </summary>
public class UploadResult<T>
{
public bool WasSuccessful { get; set; }
public string? ErrorMessage { get; set; }
public List<T> Data { get; set; } = [];
}
@@ -1,30 +0,0 @@
using JdeScoping.Client.Models;
using JdeScoping.Core.ViewModels;
namespace JdeScoping.Client.Services;
/// <summary>
/// Service for lookup/autocomplete API operations.
/// </summary>
public interface ILookupService
{
/// <summary>
/// Finds items matching the search term.
/// </summary>
Task<List<ItemViewModel>> FindItemsAsync(string searchTerm);
/// <summary>
/// Finds profit centers matching the search term.
/// </summary>
Task<List<ProfitCenterViewModel>> FindProfitCentersAsync(string searchTerm);
/// <summary>
/// Finds work centers matching the search term.
/// </summary>
Task<List<WorkCenterViewModel>> FindWorkCentersAsync(string searchTerm);
/// <summary>
/// Finds operators matching the search term.
/// </summary>
Task<List<OperatorViewModel>> FindOperatorsAsync(string searchTerm);
}
@@ -1,39 +0,0 @@
using JdeScoping.Client.Models;
namespace JdeScoping.Client.Services;
/// <summary>
/// Service for search-related API operations.
/// </summary>
public interface ISearchService
{
/// <summary>
/// Gets all searches for the current user.
/// </summary>
Task<List<SearchViewModel>> GetUserSearchesAsync();
/// <summary>
/// Gets a specific search by ID.
/// </summary>
Task<SearchViewModel?> GetSearchAsync(int id);
/// <summary>
/// Copies an existing search to create a new one.
/// </summary>
Task<SearchViewModel?> CopySearchAsync(int id);
/// <summary>
/// Saves and submits a search.
/// </summary>
Task<int?> SaveSearchAsync(SearchViewModel search);
/// <summary>
/// Gets all searches in the queue.
/// </summary>
Task<List<SearchViewModel>> GetQueueAsync();
/// <summary>
/// Downloads the results for a completed search.
/// </summary>
Task<byte[]?> DownloadResultsAsync(int id);
}
@@ -1,99 +0,0 @@
using System.Net.Http.Json;
using JdeScoping.Client.Models;
using JdeScoping.Core.ViewModels;
namespace JdeScoping.Client.Services;
/// <summary>
/// Handles lookup/autocomplete API calls.
/// Authentication is handled via cookies (sent automatically by the browser).
/// </summary>
public class LookupService : ILookupService
{
private readonly HttpClient _httpClient;
public LookupService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<List<ItemViewModel>> FindItemsAsync(string searchTerm)
{
if (string.IsNullOrEmpty(searchTerm) || searchTerm.Length < 3)
{
return [];
}
try
{
var result = await _httpClient.GetFromJsonAsync<List<ItemViewModel>>(
$"api/lookup/items?q={Uri.EscapeDataString(searchTerm)}");
return result ?? [];
}
catch (Exception ex)
{
Console.WriteLine($"Failed to find items: {ex.Message}");
return [];
}
}
public async Task<List<ProfitCenterViewModel>> FindProfitCentersAsync(string searchTerm)
{
if (string.IsNullOrEmpty(searchTerm) || searchTerm.Length < 3)
{
return [];
}
try
{
var result = await _httpClient.GetFromJsonAsync<List<ProfitCenterViewModel>>(
$"api/lookup/profit-centers?q={Uri.EscapeDataString(searchTerm)}");
return result ?? [];
}
catch (Exception ex)
{
Console.WriteLine($"Failed to find profit centers: {ex.Message}");
return [];
}
}
public async Task<List<WorkCenterViewModel>> FindWorkCentersAsync(string searchTerm)
{
if (string.IsNullOrEmpty(searchTerm) || searchTerm.Length < 3)
{
return [];
}
try
{
var result = await _httpClient.GetFromJsonAsync<List<WorkCenterViewModel>>(
$"api/lookup/work-centers?q={Uri.EscapeDataString(searchTerm)}");
return result ?? [];
}
catch (Exception ex)
{
Console.WriteLine($"Failed to find work centers: {ex.Message}");
return [];
}
}
public async Task<List<OperatorViewModel>> FindOperatorsAsync(string searchTerm)
{
if (string.IsNullOrEmpty(searchTerm) || searchTerm.Length < 3)
{
return [];
}
try
{
var result = await _httpClient.GetFromJsonAsync<List<OperatorViewModel>>(
$"api/lookup/operators?q={Uri.EscapeDataString(searchTerm)}");
return result ?? [];
}
catch (Exception ex)
{
Console.WriteLine($"Failed to find operators: {ex.Message}");
return [];
}
}
}
@@ -1,129 +0,0 @@
using System.Net.Http.Json;
using JdeScoping.Client.Models;
namespace JdeScoping.Client.Services;
/// <summary>
/// Handles search-related API calls.
/// Authentication is handled via cookies (sent automatically by the browser).
/// </summary>
public class SearchService : ISearchService
{
private readonly HttpClient _httpClient;
public SearchService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<List<SearchViewModel>> GetUserSearchesAsync()
{
try
{
var result = await _httpClient.GetFromJsonAsync<List<SearchViewModel>>("api/search");
return result ?? [];
}
catch (Exception ex)
{
Console.WriteLine($"Failed to get searches: {ex.Message}");
return [];
}
}
public async Task<SearchViewModel?> GetSearchAsync(int id)
{
try
{
return await _httpClient.GetFromJsonAsync<SearchViewModel>($"api/search/{id}");
}
catch (Exception ex)
{
Console.WriteLine($"Failed to get search {id}: {ex.Message}");
return null;
}
}
public async Task<SearchViewModel?> CopySearchAsync(int id)
{
try
{
return await _httpClient.GetFromJsonAsync<SearchViewModel>($"api/search/{id}/copy");
}
catch (Exception ex)
{
Console.WriteLine($"Failed to copy search {id}: {ex.Message}");
return null;
}
}
public async Task<int?> SaveSearchAsync(SearchViewModel search)
{
try
{
var response = await _httpClient.PostAsJsonAsync("api/search", new
{
search.Name,
search.UserName,
Criteria = new
{
MinimumDT = search.Criteria.MinimumDt,
MaximumDT = search.Criteria.MaximumDt,
WorkOrders = search.Criteria.WorkOrders.Select(wo => new { wo.WorkOrderNumber }),
Items = search.Criteria.Items.Select(i => new { i.ItemNumber }),
ProfitCenters = search.Criteria.ProfitCenters.Select(pc => new { pc.Code }),
WorkCenters = search.Criteria.WorkCenters.Select(wc => new { wc.Code }),
ComponentLots = search.Criteria.ComponentLots.Select(cl => new { cl.LotNumber, cl.ItemNumber }),
Operators = search.Criteria.Operators.Select(op => new { op.AddressNumber, UserID = op.UserId }),
PartOperations = search.Criteria.PartOperations.Select(po => new
{
po.ItemNumber,
po.OperationNumber,
po.MisNumber,
po.MisRevision
}),
search.Criteria.ExtractMisData
}
});
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadFromJsonAsync<int>();
}
Console.WriteLine($"Failed to save search: {response.StatusCode}");
return null;
}
catch (Exception ex)
{
Console.WriteLine($"Failed to save search: {ex.Message}");
return null;
}
}
public async Task<List<SearchViewModel>> GetQueueAsync()
{
try
{
var result = await _httpClient.GetFromJsonAsync<List<SearchViewModel>>("api/search/queue");
return result ?? [];
}
catch (Exception ex)
{
Console.WriteLine($"Failed to get queue: {ex.Message}");
return [];
}
}
public async Task<byte[]?> DownloadResultsAsync(int id)
{
try
{
return await _httpClient.GetByteArrayAsync($"api/search/{id}/results");
}
catch (Exception ex)
{
Console.WriteLine($"Failed to download results for {id}: {ex.Message}");
return null;
}
}
}