SHA256
feat StayExport - Stay Export Pages - Initial implementation
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
<ReconnectModal />
|
||||
<script src="@Assets["_framework/blazor.web.js"]"></script>
|
||||
<script src="@Assets["_content/MudBlazor/MudBlazor.min.js"]"></script>
|
||||
<script src="js/App.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -13,4 +13,7 @@
|
||||
<MudNavLink Href="@GuestConsts.Page_StayEntry_List" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Book">
|
||||
@LanguageLocale.navMenu_StayEntryList
|
||||
</MudNavLink>
|
||||
<MudNavLink Href="@GuestConsts.Page_StayExport_List" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.ImportExport">
|
||||
@LanguageLocale.navMenu_StayExport
|
||||
</MudNavLink>
|
||||
</MudNavMenu>
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
@attribute [Route($"{GuestConsts.Page_StayExport_List}")]
|
||||
|
||||
@using FluentStorage;
|
||||
@using FluentStorage.Storage;
|
||||
@using System.Text.Json;
|
||||
@using Microsoft.Extensions.Options;
|
||||
@using Somnia.GuestLog.Models.DTOs;
|
||||
@using Somnia.GuestLog.Models.Configuration;
|
||||
@using Somnia.GuestLog.Services;
|
||||
|
||||
@inject IStayExportFileEntityService stayExportEntityService
|
||||
@inject NavigationManager Navigation
|
||||
@inject IUserMessageService userMessage
|
||||
@inject IDialogService DialogService
|
||||
@inject IDataListService dataListService;
|
||||
@inject ILocalizerService Localizer;
|
||||
|
||||
@inject IOptions<StayExportConfig> exportConfig
|
||||
@inject IJSRuntime JS
|
||||
|
||||
|
||||
<PageTitle>Somnia - Stay Export Files</PageTitle>
|
||||
|
||||
<MudStack Row="true" Class="my-4">
|
||||
<MudText Typo="Typo.h4" GutterBottom="true">@LanguageLocale.page_StayExportList_pageTitle</MudText>
|
||||
<MudSpacer />
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" Size="Size.Small"
|
||||
StartIcon="@Icons.Material.Filled.Search" OnClick="() => BtnSearchDataAsync()">
|
||||
@LanguageLocale.general_btnSearch
|
||||
</MudButton>
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" Size="Size.Small" StartIcon="@Icons.Material.Filled.Add"
|
||||
OnClick="() => BtnNewExport()">
|
||||
@LanguageLocale.page_StayExportList_btnNewExport
|
||||
</MudButton>
|
||||
</MudStack>
|
||||
|
||||
@* <MudPaper Class="pa-4 my-4" Elevation="2" Height="100%">
|
||||
FILTER
|
||||
</MudPaper> *@
|
||||
|
||||
<MudDataGrid @ref="_dataGrid" T="StayExportFileDTO" Items="@stayExportList" Loading="@_dataLoading" ReadOnly="true"
|
||||
Elevation="2">
|
||||
<ToolBarContent>
|
||||
<MudText Typo="Typo.subtitle1">@LanguageLocale.page_StayExportList_exportList</MudText>
|
||||
</ToolBarContent>
|
||||
<Columns>
|
||||
<PropertyColumn Property="x => x.Id" Hideable="false" Title="@LanguageLocale.dto_StayExportFile_Id" />
|
||||
<PropertyColumn Property="x => Localizer.GetEnumValue(x.ExportFormat)"
|
||||
Title="@LanguageLocale.dto_StayExportFile_ExportFormat" />
|
||||
<TemplateColumn Title="@LanguageLocale.dto_StayExportFile_ExportParams">
|
||||
<CellTemplate>
|
||||
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Info"
|
||||
OnClick="() => ShowExportParams(context.Item)" />
|
||||
</CellTemplate>
|
||||
</TemplateColumn>
|
||||
<PropertyColumn Property="x => Localizer.GetEnumValue(x.ExportResult)"
|
||||
Title="@LanguageLocale.dto_StayExportFile_ExportResult" />
|
||||
<PropertyColumn Property="x => x.ExportedPath" Title="@LanguageLocale.dto_StayExportFile_ExportedPath" Hidden />
|
||||
<PropertyColumn Property="x => x.ExportTime" Title="@LanguageLocale.dto_StayExportFile_ExportTime" />
|
||||
|
||||
<TemplateColumn CellClass="d-flex justify-between" Title="Options" StickyRight Hideable="false"
|
||||
ShowColumnOptions="false">
|
||||
<CellTemplate>
|
||||
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Download"
|
||||
OnClick="() => BtnDownloadFile(context.Item)" />
|
||||
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Delete"
|
||||
OnClick="() => BtnDeleteItem(context.Item)" />
|
||||
</CellTemplate>
|
||||
</TemplateColumn>
|
||||
</Columns>
|
||||
<PagerContent>
|
||||
<MudDataGridPager T="StayExportFileDTO" />
|
||||
</PagerContent>
|
||||
</MudDataGrid>
|
||||
|
||||
<ConfirmDeleteMsgBox @ref="_confirmDeleteMsgBox" />
|
||||
|
||||
@code {
|
||||
private bool _dataLoading = true;
|
||||
private const int resultLimit = 200;
|
||||
|
||||
private IEnumerable<StayExportFileDTO> stayExportList = [];
|
||||
|
||||
private MudDataGrid<StayExportFileDTO> _dataGrid = null!;
|
||||
private ConfirmDeleteMsgBox _confirmDeleteMsgBox = null!;
|
||||
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await LoadDataAsync(showMsg: false);
|
||||
}
|
||||
|
||||
private async Task LoadDataAsync(bool showMsg = true)
|
||||
{
|
||||
_dataLoading = true;
|
||||
|
||||
stayExportList = await stayExportEntityService.GetDtoListAsync(limit: resultLimit);
|
||||
|
||||
if (showMsg)
|
||||
{
|
||||
userMessage.ShowMessage("Data loaded from DB", MessageKind.Info);
|
||||
}
|
||||
_dataLoading = false;
|
||||
}
|
||||
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
private async Task BtnSearchDataAsync()
|
||||
{
|
||||
await LoadDataAsync();
|
||||
}
|
||||
|
||||
private void BtnNewExport()
|
||||
{
|
||||
Navigation.NavigateTo(GuestConsts.Page_StayExport_New);
|
||||
}
|
||||
|
||||
|
||||
private async Task ShowExportParams(StayExportFileDTO dto)
|
||||
{
|
||||
string jsonParams = JsonSerializer.Serialize(dto.ExportParams, options: new() { WriteIndented = true });
|
||||
|
||||
await DialogService.ShowMessageBoxAsync("Details", jsonParams);
|
||||
}
|
||||
|
||||
private async Task BtnDownloadFile(StayExportFileDTO item)
|
||||
{
|
||||
if(item.ExportResult == Enums.Models.StayExportFileResult.NoData)
|
||||
{
|
||||
userMessage.ShowMessage("A Export without data can't be downloaded!", MessageKind.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(item.ExportedPath))
|
||||
{
|
||||
userMessage.ShowMessage("File can't be downloaded: no path found!", MessageKind.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
IStore store = StorageFactory.FromConnectionString(exportConfig.Value.ExportStorageConnectionString);
|
||||
|
||||
using Stream objectStream = new MemoryStream();
|
||||
await store.GetObject(item.ExportedPath, objectStream);
|
||||
objectStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using var streamRef = new DotNetStreamReference(stream: objectStream);
|
||||
|
||||
var fileName = Path.GetFileName(item.ExportedPath);
|
||||
await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
|
||||
}
|
||||
|
||||
private async Task BtnDeleteItem(StayExportFileDTO item)
|
||||
{
|
||||
userMessage.ShowMessage("Not Implemented!", MessageKind.Normal);
|
||||
@* bool? confirmDelete = await _confirmDeleteMsgBox.MsgBox.ShowAsync();
|
||||
|
||||
if (confirmDelete is null || confirmDelete.Value == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Result deleteResult = await stayExportEntityService.Delete(item);
|
||||
if (!deleteResult.IsSuccess)
|
||||
{
|
||||
string errorMsg = $"Error deleting Stay {item.Id}";
|
||||
userMessage.ShowResultWithMessage(deleteResult, errorMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
userMessage.ShowMessage($"Stay {item.Id} deleted!", MessageKind.Success);
|
||||
await LoadDataAsync(); *@
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
@attribute [Route($"{GuestConsts.Page_StayExport_New}")]
|
||||
|
||||
@using FluentValidation;
|
||||
@using FluentStorage;
|
||||
@using FluentStorage.Storage;
|
||||
@using Microsoft.Extensions.Options;
|
||||
@using Somnia.GuestLog.Models.DTOs;
|
||||
@using Somnia.GuestLog.Models.Configuration;
|
||||
@using Somnia.GuestLog.Enums.Models;
|
||||
@using Somnia.GuestLog.Services;
|
||||
@using Somnia.GuestLog.Validators;
|
||||
@using Somnia.GuestLog.Services.StayExport;
|
||||
|
||||
|
||||
@inject IUserMessageService userMessage
|
||||
@inject IDialogService DialogService
|
||||
@inject NavigationManager Navigation
|
||||
@inject IValidator<StayExportParamsDTO> ExportParamsValidator;
|
||||
@inject ILocalizerService Localizer;
|
||||
@inject IStayExportServiceFactory ExportServiceFactory;
|
||||
|
||||
@inject IOptions<StayExportConfig> exportConfig
|
||||
@inject IJSRuntime JS
|
||||
|
||||
|
||||
<PageTitle>Somnia - Stay Export - New</PageTitle>
|
||||
|
||||
<MudStack Row="true" Class="my-4">
|
||||
<MudText Typo="Typo.h4" GutterBottom="true">
|
||||
@LanguageLocale.page_StayExportNew_pageTitle
|
||||
</MudText>
|
||||
<MudSpacer />
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Success" Size="Size.Small" StartIcon="@Icons.Material.Filled.Add"
|
||||
OnClick="() => BtnCreateExport()" Disabled="@_isExported">
|
||||
@LanguageLocale.general_btnCreate
|
||||
</MudButton>
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Default" Size="Size.Small"
|
||||
StartIcon="@Icons.Material.Filled.ArrowBack" OnClick="() => BtnReturn()">
|
||||
@LanguageLocale.general_btnReturn
|
||||
</MudButton>
|
||||
</MudStack>
|
||||
|
||||
<MudForm @ref="@_form" Model="@exportParams"
|
||||
Validation="@((ExportParamsValidator as StayExportParamsDTOValidator)!.ValidateValue)" ReadOnly="@_isExported">
|
||||
<MudPaper Class="pa-4 my-4" Elevation="3" Height="100%">
|
||||
<MudStack Row style="margin-block: 0.2em;">
|
||||
<MudSelect @bind-Value="exportFormat" Label="@LanguageLocale.dto_StayExportFile_ExportFormat" FullWidth
|
||||
Clearable>
|
||||
@foreach (StayExportFormat option in Enum.GetValues<StayExportFormat>())
|
||||
{
|
||||
<MudSelectItem Value="new Nullable<StayExportFormat>(option)">
|
||||
@Localizer.GetEnumValue(option)
|
||||
</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
<MudSelect @bind-Value="exportParams.ExportType" For="@(() => exportParams.ExportType)"
|
||||
Label="@LanguageLocale.dto_StayExportParams_ExportType" FullWidth Clearable>
|
||||
@foreach (StayExportParamType option in Enum.GetValues<StayExportParamType>())
|
||||
{
|
||||
<MudSelectItem Value="new Nullable<StayExportParamType>(option)">
|
||||
@Localizer.GetEnumValue(option)
|
||||
</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
@if (_showPeriodFields)
|
||||
{
|
||||
<MudPaper Class="pa-4" Elevation="3" Height="100%">
|
||||
<MudStack Row>
|
||||
<MudDatePicker @bind-Date="exportParams.ExportPeriodStart" For="@(() => exportParams.ExportPeriodStart)"
|
||||
Label="@LanguageLocale.dto_StayExportParams_ExportPeriodStart" Clearable OpenTo="OpenTo.Date" Editable
|
||||
AutoClose="true" />
|
||||
<MudDatePicker @bind-Date="exportParams.ExportPeriodEnd" For="@(() => exportParams.ExportPeriodEnd)"
|
||||
Label="@LanguageLocale.dto_StayExportParams_ExportPeriodEnd" Clearable OpenTo="OpenTo.Date" Editable
|
||||
AutoClose="true" />
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
}
|
||||
|
||||
</MudForm>
|
||||
|
||||
@if (_isExported && exportedFile != null)
|
||||
{
|
||||
<MudPaper Class="pa-4 my-6" Elevation="3" Height="100%">
|
||||
<MudStack>
|
||||
<MudText Typo="Typo.h4">File Exported!</MudText>
|
||||
<MudTextField Value="@Localizer.GetEnumValue(exportedFile.ExportResult)"
|
||||
Label="@LanguageLocale.dto_StayExportFile_ExportResult" FullWidth ReadOnly="true" />
|
||||
<MudTextField Value="@Localizer.GetEnumValue(exportedFile.ExportFormat)"
|
||||
Label="@LanguageLocale.dto_StayExportFile_ExportFormat" FullWidth ReadOnly="true" />
|
||||
<MudButton OnClick="BtnDownloadExportedFile">Download Exported File</MudButton>
|
||||
</MudStack>
|
||||
</MudPaper>
|
||||
}
|
||||
|
||||
@code {
|
||||
MudForm _form = null!;
|
||||
|
||||
StayExportFormat? exportFormat = null;
|
||||
StayExportParamsDTO exportParams = new();
|
||||
StayExportFileDTO? exportedFile = null;
|
||||
|
||||
bool _showPeriodFields => exportParams.ExportType == StayExportParamType.PeriodDateIn;
|
||||
bool _isExported => exportedFile != null;
|
||||
|
||||
|
||||
private void BtnReturn()
|
||||
{
|
||||
Navigation.NavigateTo(GuestConsts.Page_StayExport_List);
|
||||
}
|
||||
|
||||
private async Task BtnCreateExport()
|
||||
{
|
||||
await _form.ValidateAsync();
|
||||
if (!_form.IsValid || exportFormat == null)
|
||||
{
|
||||
userMessage.ShowMessage("Invalid Form!", MessageKind.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var loadingDialog = await DialogService.ShowAsync<LoadingDialog>();
|
||||
|
||||
var exportService = ExportServiceFactory.GetService(exportFormat.Value);
|
||||
var exportResult = await exportService.ExportStaysByParams(exportParams);
|
||||
|
||||
exportedFile = exportResult.Value;
|
||||
userMessage.ShowMessage(
|
||||
$"Stay exported: {exportResult.ResultCode} with export result: {exportedFile?.ExportResult} to '{exportedFile?.ExportedPath ?? "???"}'",
|
||||
MessageKind.Info);
|
||||
|
||||
loadingDialog.Close();
|
||||
|
||||
@* Result createResult = await stayService.CreateEntryAsync(model);
|
||||
if (!createResult.IsSuccess)
|
||||
{
|
||||
userMessage.ShowResultWithMessage(createResult, $"Error creating StayEntry");
|
||||
return;
|
||||
} *@
|
||||
}
|
||||
|
||||
private async Task BtnDownloadExportedFile()
|
||||
{
|
||||
Debug.Assert(exportedFile != null);
|
||||
Debug.Assert(exportConfig.Value.ExportStorageConnectionString != null);
|
||||
|
||||
if (string.IsNullOrEmpty(exportedFile.ExportedPath))
|
||||
{
|
||||
userMessage.ShowMessage("Exported File can't be downloaded as no file was saved", MessageKind.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
IStore store = StorageFactory.FromConnectionString(exportConfig.Value.ExportStorageConnectionString);
|
||||
|
||||
using Stream objectStream = new MemoryStream();
|
||||
await store.GetObject(exportedFile.ExportedPath, objectStream);
|
||||
objectStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
var fileName = Path.GetFileName(exportedFile.ExportedPath);
|
||||
|
||||
using var streamRef = new DotNetStreamReference(stream: objectStream);
|
||||
|
||||
await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
@using Somnia.GuestLog.Components.Controls
|
||||
@using Somnia.GuestLog.Services.Entity;
|
||||
@using System.Diagnostics;
|
||||
@@ -13,6 +13,9 @@ public static class GuestConsts
|
||||
public const string Page_StayEntry_Detail = $"/stayEntries/d/{Page_StayEntry_Detail_Param_Id}";
|
||||
public const string Page_StayEntry_Detail_Param_Id = "{StayId:long}";
|
||||
|
||||
public const string Page_StayExport_List = "/stayExport";
|
||||
public const string Page_StayExport_New = "/stayExport/new";
|
||||
|
||||
|
||||
public const string QueryParam_ReturnUrl = "returnUrl";
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ builder.Services.AddHttpClient();
|
||||
builder.Services.AddSingleton<IValidator<GuestDocumentDTO>, GuestDocumentDTOValidator>();
|
||||
builder.Services.AddSingleton<IValidator<GuestDocIdDTO>, GuestDocIdDTOValidator>();
|
||||
builder.Services.AddSingleton<IValidator<StayEntryDTO>, StayEntryDTOValidator>();
|
||||
builder.Services.AddSingleton<IValidator<StayExportParamsDTO>, StayExportParamsDTOValidator>();
|
||||
|
||||
// Add Entity Services
|
||||
builder.Services.AddSingleton<IGuestDocumentEntityService, GuestDocumentEntityService>();
|
||||
|
||||
@@ -149,6 +149,17 @@
|
||||
<data name="dto.StayEntry.CreateTime" xml:space="preserve"><value>Creation Time</value></data>
|
||||
<data name="dto.StayEntry.UpdateTime" xml:space="preserve"><value>Update Time</value></data>
|
||||
|
||||
<data name="dto.StayExportFile.Id" xml:space="preserve"><value>Id</value></data>
|
||||
<data name="dto.StayExportFile.ExportFormat" xml:space="preserve"><value>Export Format</value></data>
|
||||
<data name="dto.StayExportFile.ExportParams" xml:space="preserve"><value>Export Params</value></data>
|
||||
<data name="dto.StayExportFile.ExportResult" xml:space="preserve"><value>Export Result</value></data>
|
||||
<data name="dto.StayExportFile.ExportedPath" xml:space="preserve"><value>Export Path</value></data>
|
||||
<data name="dto.StayExportFile.ExportTime" xml:space="preserve"><value>Export Time</value></data>
|
||||
|
||||
<data name="dto.StayExportParams.ExportType" xml:space="preserve"><value>Export Type</value></data>
|
||||
<data name="dto.StayExportParams.ExportPeriodStart" xml:space="preserve"><value>Date From</value></data>
|
||||
<data name="dto.StayExportParams.ExportPeriodEnd" xml:space="preserve"><value>Date To</value></data>
|
||||
|
||||
<data name="tmp" xml:space="preserve"><value>TMP</value></data>
|
||||
|
||||
<data name="general.actions" xml:space="preserve"><value>Actions</value></data>
|
||||
@@ -188,9 +199,20 @@
|
||||
<data name="enum.ResultCode.GuestInStay" xml:space="preserve"><value>Guest (ID: '{0}') is in a stay.</value></data>
|
||||
<data name="enum.ResultCode.GuestCurrentlyInStay" xml:space="preserve"><value>Guest (ID: '{0}') is already in one stay during the period: {1}</value></data>
|
||||
|
||||
<data name="enum.StayExportFileResult.OK" xml:space="preserve"><value>OK</value></data>
|
||||
<data name="enum.StayExportFileResult.NoData" xml:space="preserve"><value>No Data</value></data>
|
||||
<data name="enum.StayExportFileResult.ExportError" xml:space="preserve"><value>Export Error</value></data>
|
||||
<data name="enum.StayExportFileResult.UploadError" xml:space="preserve"><value>File Error</value></data>
|
||||
|
||||
<data name="enum.StayExportFormat.GuestLogJson" xml:space="preserve"><value>GuestLog JSON</value></data>
|
||||
<data name="enum.StayExportFormat.SpainParteViajeros" xml:space="preserve"><value>Spain Parte Viajeros</value></data>
|
||||
|
||||
<data name="enum.StayExportParamType.PeriodDateIn" xml:space="preserve"><value>Stay 'Date In' Period</value></data>
|
||||
|
||||
|
||||
<data name="navMenu.GuestDocumentList" xml:space="preserve"><value>Guests</value></data>
|
||||
<data name="navMenu.StayEntryList" xml:space="preserve"><value>Stays</value></data>
|
||||
<data name="navMenu.StayExport" xml:space="preserve"><value>Stay Export</value></data>
|
||||
|
||||
|
||||
<data name="page.GuestDocList.pageTitle" xml:space="preserve"><value>Guest Documents</value></data>
|
||||
@@ -206,6 +228,13 @@
|
||||
|
||||
<data name="page.StayEntryNew.pageTitle" xml:space="preserve"><value>New Stay</value></data>
|
||||
|
||||
<data name="page.StayExportList.pageTitle" xml:space="preserve"><value>Stay Export Files</value></data>
|
||||
<data name="page.StayExportList.exportList" xml:space="preserve"><value>Export List</value></data>
|
||||
<data name="page.StayExportList.btnNewExport" xml:space="preserve"><value>New Export</value></data>
|
||||
|
||||
<data name="page.StayExportNew.pageTitle" xml:space="preserve"><value>New Stay Export</value></data>
|
||||
|
||||
|
||||
<data name="control.GuestDocForm.sectionDocument" xml:space="preserve"><value>Document Details</value></data>
|
||||
<data name="control.GuestDocForm.sectionGuest" xml:space="preserve"><value>Guest Details</value></data>
|
||||
<data name="control.GuestDocForm.sectionContact" xml:space="preserve"><value>Contact Details</value></data>
|
||||
|
||||
@@ -9,5 +9,5 @@ public interface IStayExportFileEntityService
|
||||
|
||||
public Task<StayExportFileDTO?> GetDtoByIdAsync(long id);
|
||||
//public Task<IEnumerable<StayExportFileDTO>> GetDtoListByFilterAsync(StayExportFileFilterDTO filter, int limit = 0);
|
||||
public Task<IEnumerable<StayExportFileDTO>> GetDtoListAsync();
|
||||
public Task<IEnumerable<StayExportFileDTO>> GetDtoListAsync(int limit = 0);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using Somnia.GuestLog.Infrastructure;
|
||||
using Somnia.GuestLog.Models;
|
||||
using Somnia.GuestLog.Models.DTOs;
|
||||
using Somnia.GuestLog.Models.Entities;
|
||||
using Somnia.GuestLog.Utils;
|
||||
|
||||
namespace Somnia.GuestLog.Services.Entity;
|
||||
|
||||
@@ -69,13 +70,15 @@ public class StayExportFileEntityService(
|
||||
return dbItem is not null ? GetDtoFromDb(dbItem) : null;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<StayExportFileDTO>> GetDtoListAsync()
|
||||
public async Task<IEnumerable<StayExportFileDTO>> GetDtoListAsync(int limit = 0)
|
||||
{
|
||||
using var dbContext = contextFactory.CreateDbContext();
|
||||
|
||||
var dbList = await dbContext.StayExportFiles
|
||||
IQueryable<StayExportFile> query = dbContext.StayExportFiles
|
||||
.OrderByDescending(e => e.ExportTime)
|
||||
.ToListAsync();
|
||||
.WithLimit(limit);
|
||||
|
||||
var dbList = await query.ToListAsync();
|
||||
|
||||
return dbList.Select(e => GetDtoFromDb(e));
|
||||
}
|
||||
|
||||
@@ -8,4 +8,9 @@ public static class QueryExtensions
|
||||
{
|
||||
return condition ? source.Where(predicate) : source;
|
||||
}
|
||||
|
||||
public static IQueryable<T> WithLimit<T>(this IQueryable<T> source, int limit)
|
||||
{
|
||||
return limit > 0 ? source.Take(limit) : source;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using FluentValidation;
|
||||
using Somnia.GuestLog.Enums.Models;
|
||||
using Somnia.GuestLog.Models.DTOs;
|
||||
|
||||
namespace Somnia.GuestLog.Validators;
|
||||
|
||||
public class StayExportParamsDTOValidator : ValueValidator<StayExportParamsDTO>
|
||||
{
|
||||
public StayExportParamsDTOValidator()
|
||||
{
|
||||
RuleFor(e => e.ExportType)
|
||||
.NotEmpty();
|
||||
|
||||
RuleFor(e => e.ExportPeriodStart)
|
||||
.NotEmpty()
|
||||
.When(e => e.ExportType == StayExportParamType.PeriodDateIn);
|
||||
|
||||
RuleFor(e => e.ExportPeriodEnd)
|
||||
.NotEmpty()
|
||||
.When(e => e.ExportType == StayExportParamType.PeriodDateIn);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
// Function to download files from Blazor pages
|
||||
window.downloadFileFromStream = async (fileName, contentStreamReference) => {
|
||||
const arrayBuffer = await contentStreamReference.arrayBuffer();
|
||||
const blob = new Blob([arrayBuffer]);
|
||||
const url = URL.createObjectURL(blob);
|
||||
const anchorElement = document.createElement('a');
|
||||
anchorElement.href = url;
|
||||
anchorElement.download = fileName ?? '';
|
||||
anchorElement.click();
|
||||
anchorElement.remove();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
Reference in New Issue
Block a user