From 1a1c8e71fcd14858f595029f089b2d4a00202b32 Mon Sep 17 00:00:00 2001
From: ogi <Administrator@S-OGI-PC>
Date: Fri, 05 Dec 2025 09:24:16 +0900
Subject: [PATCH] プロジェクトファイルを追加。

---
 HotelPms.Client.Blazor/Pages/Pages/RoomView/List.razor |  480 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 480 insertions(+), 0 deletions(-)

diff --git a/HotelPms.Client.Blazor/Pages/Pages/RoomView/List.razor b/HotelPms.Client.Blazor/Pages/Pages/RoomView/List.razor
new file mode 100644
index 0000000..16e4c16
--- /dev/null
+++ b/HotelPms.Client.Blazor/Pages/Pages/RoomView/List.razor
@@ -0,0 +1,480 @@
+@page "/roomview/list"
+@inject GrpcChannel Channel
+@inject IJSRuntime JSRuntime
+@inject IGlobalLoadingSpinner LoadingSpinner
+@using Grpc.Net.Client.Web
+@using HotelPms.Client.Blazor.Models
+@using HotelPms.Client.Blazor.Services
+@using HotelPms.Data.Common
+@using HotelPms.Data.Common.Pagination
+@using Google.Protobuf.WellKnownTypes
+@using System.Text.Json
+@using System.Text
+@using ViewModel = HotelPms.Client.Blazor.ViewModel
+@using static HotelPms.Client.Blazor.Util.SystemEnum
+@inject IDialogService DialogService
+@inject NavigationManager NavigationManager
+@*@implements IDisposable*@
+@implements IAsyncDisposable
+
+<h3>客室状況</h3>
+<MudGrid Spacing="@spacing" Justify="Justify.FlexStart" Class="align-center mt-1 mb-1">
+    <MudItem>
+        <MudDatePicker Label="利用日" Editable="true" @bind-Date="useDate" Placeholder="利用日" />
+    </MudItem>
+    <MudItem>
+        <MudButton Variant="Variant.Filled" Style="@buttonStyle" StartIcon="@Icons.Filled.ReadMore" OnClick="ReadHotelDate">ホテル日</MudButton>
+    </MudItem>
+    <MudItem>
+        <MudButton Variant="Variant.Filled" Style="@buttonStyle" StartIcon="@Icons.Filled.ReadMore" OnClick="Read">読込</MudButton>
+    </MudItem>
+    <MudItem>
+        <MudButton Variant="Variant.Filled" Style="@buttonStyle" StartIcon="@Icons.Filled.PostAdd" OnClick="ColSetting">列設定</MudButton>
+    </MudItem>
+    <MudItem>
+        <MudButton Variant="Variant.Filled" Style="@buttonStyle" StartIcon="@Icons.Filled.Input">インポート</MudButton>
+    </MudItem>
+</MudGrid>
+<MudTabs Elevation="4" Rounded="true" Color="@Color.Success" PrevIcon="@Icons.Filled.SkipPrevious" NextIcon="@Icons.Filled.SkipNext" SliderColor="@Color.Error" ActivePanelIndexChanged="TabChanged">
+    @foreach (Data.Master.RoomViewTab tab in roomViewData.Tabs)
+    {
+        <MudTabPanel Text="@tab.Name" />
+    }
+</MudTabs>
+@if (visibled)
+{
+    <div id="scrollTable" class="pt-2" @ref="scrollDiv">
+        <div class="table">
+            <div class="table-column-group">
+                @for (var i = 0; i < roomViewData.ColCount; i++)
+                {
+                    var col = i;
+                    <div class="table-column" style="@($"width:{roomViewData.Data[0][col].ColWidth}px;")"></div>
+                }
+            </div>
+            <div class="table-row-group">
+                @for (var r = 0; r < roomViewData.RowCount; r++)
+                {
+                    var row = r;
+                    //EnvironmentSetting.Debug(row);
+
+                    <ul class="table-row" style="@($"height:{roomViewData.Data[row][0].RowHeight}px;")">
+                        @for (var i = 0; i < roomViewData.ColCount; i++)
+                        {
+                            var col = i;  //大事!!!そうじゃないと、iは最後の値しかない                        
+                            HotelPms.Data.Master.RoomViewLayout item = roomViewData.Data[row][col];
+                            if (item.RoomID > 0)
+                            {
+                                <li @ref="cellLi" class="table-cell" style="position:relative;@roomViewData.GetCellColor(item)" @onmousedown="async(e) => await CellMouseDown(cellLi, item.RoomID, e)">
+                                    @*                                <MudBadge Color="MudBlazor.ColorSuccess" Overlap="true" Bordered="true" Style="position: absolute;left: 5px;top: 150px;">
+                                    <MudAvatar Image="images/avatar_jonny.jpg" />
+                                </MudBadge>
+                                <MudText Style="position: absolute;left: 5px;top: 5px;color: blue;">@roomViewData.Data[row][col].RoomID</MudText>*@
+                                    @foreach (Data.Master.RoomCell cell in roomViewData.Cells)
+                                    {
+                                        Data.Master.RoomCell roomCell = cell;
+                                        //EnvironmentSetting.Debug(roomCell.ToText());
+                                        var text = roomViewData.GetText(roomCell, item.RoomID);
+                                        //EnvironmentSetting.Debug(text);
+                                        <MudText Align="roomViewData.ToTextAlignCSS(roomCell)" Style="@roomViewData.GetRoomCellStyle(roomCell)">@text</MudText>
+                                    }
+                                </li>
+                            }
+                            else
+                            {
+                                <li class="table-cell" style="@(item.DisplayName.Length == 0 ? "visibility:hidden;" : string.Empty)position:relative;@roomViewData.GetCellColor(item)">
+                                    <MudText Align="Align.Center" Style="@($"font-family:{item.FontName};font-size:{item.FontSize}pt;color:{CConvert.ToHtmlColor(item.ForeColor)};")">@item.DisplayName</MudText>
+                                </li>
+                            }
+                        }
+                    </ul>
+                }
+            </div>
+        </div>
+    </div>
+    <MudPaper id="menuPop" Class="room-memu" Width="@roomViewData.Menu.WidthCss" Style="@roomViewData.Menu.DisplayCss">
+        <MudList Clickable="true" Dense=true @bind-SelectedItem="SelectedMenuItem" @bind-SelectedValue="SelectedMenuValue">
+            <MudListSubheader Class="pa-0 ma-0">
+                <MudStack Row="true">
+                    <MudIconButton Icon="@Icons.Filled.FastRewind" Color="MudBlazor.Color.Primary"></MudIconButton>
+                    <MudStack Style="width: 100%" Spacing="0">
+                        <MudPaper Elevation="0" Style="text-align:center;">中村 真一</MudPaper>
+                        <MudPaper Elevation="0" Style="text-align:center;">1/10</MudPaper>
+                    </MudStack>
+                    <MudIconButton Icon="@Icons.Filled.FastForward" Color="MudBlazor.Color.Primary"></MudIconButton>
+                </MudStack>
+            </MudListSubheader>
+            @foreach (RoomViewMenu.EType item in System.Enum.GetValues(typeof(RoomViewMenu.EType)))
+            {
+                if (roomViewData.Menu.Disable[(int)item]) { continue; }
+                if (item == RoomViewMenu.EType.Out || item == RoomViewMenu.EType.Maid || item == RoomViewMenu.EType.Customer)
+                {
+                    <MudDivider />
+                }
+
+                <MudListItem Text="@roomViewData.Menu.Text[(int)item]" Value="(int)item" Icon="@RoomViewMenu.IconData[(int)item]" OnClick="() => MenuClick(item)" />
+            }
+        </MudList>
+    </MudPaper>
+}
+else
+{
+    <p>読込中...</p>
+}
+
+
+<style>
+    #scrollTable {
+        background-color: #fff;
+        overflow: auto; /*必需*/
+    }
+
+    ul {
+        margin: 0;
+        padding: 0;
+        list-style: none;
+    }
+
+    .table {
+        display: table;
+        border: none;
+        border-spacing: 5px; 
+        width: max-content;
+    }
+
+    .table-caption {
+        display: table-caption;
+        margin: 0;
+        padding: 0;
+        font-size: 16px;
+    }
+
+    .table-column-group {
+        display: table-column-group;
+    }
+
+    .table-column {
+        display: table-column;
+    }
+
+    .table-row-group {
+        display: table-row-group;
+    }
+
+    .table-row {
+        display: table-row;
+        height: 200px;
+    }
+
+    .table-cell {
+        display: table-cell;
+        padding: 5px;
+        border-radius: 5px;
+        border: 1px solid #018EE8;
+        background-color: #fff;
+        cursor: pointer;
+        background-size: cover;
+        list-style-type: none;
+        box-shadow: 0 3px 4px rgba(0,0,0,0.4);
+        transition: 0.1s ease-out;
+    }
+
+    .table-cell:hover {            
+/*        border-radius: 5px;  */
+        border: 1px solid #ff0000;    
+/*        transition: filter .3s;
+        filter: brightness(1.3) contrast(110%);*/
+        transform: scale(1.05);
+    }
+
+    .table-header-group {
+        display: table-header-group;
+        background: #eee;
+        font-weight: bold;
+    }
+
+    .table-footer-group {
+        display: table-footer-group;
+    }
+
+    .room-memu {
+        position: absolute;        
+    }
+
+    /* 样式二 */
+    /*---滚动条默认显示样式--*/
+/*    ::-webkit-scrollbar-thumb {
+        background-color: #696969;
+        height: 50px;
+        outline-offset: -2px;
+        outline: 2px solid #fff;
+        border-radius: 4px;
+        border: 2px solid #fff;
+        cursor: default;
+    }*/
+        /*---鼠标点击滚动条显示样式--*/
+/*        ::-webkit-scrollbar-thumb:hover {
+            background-color: #3060FA;
+            height: 50px;
+            border-radius: 4px;
+            cursor: pointer;
+        }*/
+    /*---滚动条大小--*/
+/*    ::-webkit-scrollbar {
+        width: 15px;
+        height: 15px;
+    }*/
+    /*---滚动框背景样式--*/
+/*    ::-webkit-scrollbar-track-piece {
+        background-color: #fff;
+        border-radius: 0;
+    }*/
+
+/*    ::-webkit-scrollbar-thumb:active {
+        height: 50px;
+        background-color: #000;
+        border-radius: 4px;
+    }*/
+</style>
+
+@code {
+    DateTime? useDate;
+    private int spacing { get; set; } = 3;
+    private string buttonStyle = $"color:{Colors.Shades.White};background-color:{Colors.Green.Darken2};width: 150px; height: 40px;";
+    private RoomViewData roomViewData = new RoomViewData();
+    private bool visibled = false;
+    private ElementReference scrollDiv;
+    private ElementReference cellLi;
+    private int InnerHeight = 0;
+    private int InnerWidth = 0;
+
+    private MudListItem SelectedMenuItem { get; set; }
+    private object SelectedMenuValue { get; set; } = 0;
+
+    private DateTime GetUseDate() => useDate ?? DateTime.Today;
+    private bool renderUI = true;
+    private IJSObjectReference? module;
+
+    protected override async Task OnInitializedAsync()
+    {
+        await LoadingSpinner.ShowAsync();
+        // 下記一気で全部取得する
+        //useDate = await EnvironmentSetting.GetHotelDate();    // ⇒ShouldRender:1
+        //await roomViewData.InitTabs();                 // ⇒ShouldRender:2
+        //await roomViewData.GetRoomCell();              // ⇒ShouldRender:3 
+        //await roomViewData.GetData(GetUseDate());    // ⇒ShouldRender:4
+        await roomViewData.Init();            // ⇒ShouldRender:1
+        useDate = roomViewData.UseDate;       // ⇒ShouldRender:2
+
+        EnvironmentSetting.Debug($"【{DateTime.Now.ToString("HH:mm:ss fff")}】Resized開始");
+        BrowserResizeService.OnResize += BrowserHasResized;
+
+        //DotNet.invokeMethodAsync('{ASSEMBLY NAME}', '{.NET METHOD ID}', {ARGUMENTS});
+        //await JSRuntime.InvokeAsync<object>("browserResize.registerResizeCallback");
+
+
+        //InnerHeight = await BrowserResizeService.GetInnerHeight(JSRuntime);
+        //InnerWidth = await BrowserResizeService.GetInnerWidth(JSRuntime);
+        EnvironmentSetting.Debug($"【{DateTime.Now.ToString("HH:mm:ss fff")}】Resized終了");
+        visibled = true;
+        await LoadingSpinner.HideAsync();
+    }
+
+    protected override bool ShouldRender()
+    {
+        EnvironmentSetting.Debug($"【{DateTime.Now.ToString("HH:mm:ss fff")}】ShouldRender開始:{renderUI}");
+        if(renderUI)
+        {
+            renderUI = false;   //重複ShouldRenderを回避する
+            return true; 
+        }
+        else
+        {
+            return false;   
+        }
+    }
+
+    protected override async Task OnAfterRenderAsync(bool firstRender)
+    {
+        EnvironmentSetting.Debug($"【{DateTime.Now.ToString("HH:mm:ss fff")}】OnAfterRenderAsync開始:{firstRender}");
+        renderUI = true;
+        if(firstRender)
+        {
+            module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./js/browser-resize.js");
+            await module.InvokeAsync<object>("registerResizeCallback");
+
+            InnerHeight = await module.InvokeAsync<int>("getInnerHeight");
+            InnerWidth = await module.InvokeAsync<int>("getInnerWidth");
+        }
+        //return base.OnAfterRenderAsync(firstRender);
+    }
+
+    //public void Dispose()
+    //{
+    //    BrowserResizeService.OnResize -= BrowserHasResized;
+    //}
+
+    async ValueTask IAsyncDisposable.DisposeAsync()
+    {        
+        if (module is not null)
+        {            
+            BrowserResizeService.OnResize -= BrowserHasResized;
+            await module.InvokeAsync<object>("removeResizeCallback");
+            await module.DisposeAsync();
+        }
+    }
+
+    private async Task BrowserHasResized()
+    {
+        EnvironmentSetting.Debug($"【{DateTime.Now.ToString("HH:mm:ss fff")}】BrowserHasResized開始");
+        //InnerHeight = await BrowserResizeService.GetInnerHeight(JSRuntime);
+        //InnerWidth = await BrowserResizeService.GetInnerWidth(JSRuntime);
+        InnerHeight = await module.InvokeAsync<int>("getInnerHeight");
+        InnerWidth = await module.InvokeAsync<int>("getInnerWidth");
+        EnvironmentSetting.Debug($"【{DateTime.Now.ToString("HH:mm:ss fff")}】BrowserHasResized終了");
+
+        StateHasChanged();
+    }
+
+    private async Task CellMouseDown(ElementReference sender, int roomID, MouseEventArgs e)
+    {
+        if(e.Button != 0) { return; }   //0.左 1.中 2.右
+        EnvironmentSetting.Debug("CellMouseDown Start:" + DateTime.Now.ToString("HH:mm:ss fff"));
+        renderUI = false;   //↓画面再表示しないように
+        await roomViewData.Menu.Show(Channel, GetUseDate(), roomID);   //ここの画面再表示しないように
+
+        double x = e.ClientX, y = e.ClientY;
+        if (e.ClientX + roomViewData.Menu.Width > InnerWidth)
+        {
+            x = InnerWidth - roomViewData.Menu.Width;
+        }
+        if (e.ClientY + roomViewData.Menu.Height > InnerHeight)
+        {
+            y = InnerHeight - roomViewData.Menu.Height;
+        }
+        x += (e.PageX - e.ClientX);
+        y += (e.PageY - e.ClientY);   //scroll
+
+        var a = (await RoomStatusSetting.Instance()).Vacancy;
+
+#if false
+    //↓0.8秒かかる
+    //var browser = await JSRuntime.GetWindowSize();  //非表示の時にall 0
+    //EnvironmentSetting.Debug(DateTime.Now.ToString("HH:mm:ss fff"));
+
+    //double x = e.ClientX, y = e.ClientY;
+    //if (e.ClientX + menuWidth > browser.Width)
+    //{
+    //    x = browser.Width - menuWidth;
+    //}
+    //if (e.ClientY + menuHeight > browser.Height)
+    //{
+    //    y = browser.Height - menuHeight;
+    //}
+    //y += (e.PageY - e.ClientY);   //scroll
+#endif
+
+        renderUI = true;
+        roomViewData.Menu.DisplayCss = $"display:block; left: {x}px; top: {y}px";
+        EnvironmentSetting.Debug($"MouseEventArgs:OffsetX={e.OffsetX},OffsetY={e.OffsetY},ClientX={e.ClientX},ClientY={e.ClientY},PageX={e.PageX},PageY={e.PageY},ScreenX={e.ScreenX},ScreenY={e.ScreenY}");
+
+#if false
+    //EnvironmentSetting.Debug($"WindowWidth={browser.Width},WindowHeight={browser.Height}");
+    //EnvironmentSetting.Debug($"cellRect:AbsoluteLeft={cellRect.AbsoluteLeft},AbsoluteTop={cellRect.AbsoluteTop},WindowWidth={cellRect.WindowWidth},WindowHeight={cellRect.WindowHeight}");
+    //EnvironmentSetting.Debug($"ownerRect:AbsoluteLeft={ownerRect.AbsoluteLeft},AbsoluteTop={ownerRect.AbsoluteTop},ScrollX={ownerRect.ScrollX},ScrollY={ownerRect.ScrollY},WindowWidth={ownerRect.WindowWidth},WindowHeight={ownerRect.WindowHeight}");
+    //EnvironmentSetting.Debug($"menuRect:{menuRect.X},{menuRect.Y},{menuRect.Width},{menuRect.Height}");
+    //EnvironmentSetting.Debug(menudisplay);
+    //StateHasChanged();   //0.7秒かかる
+#endif
+
+        EnvironmentSetting.Debug("CellMouseDown End:" + DateTime.Now.ToString("HH: mm:ss fff"));
+    }
+
+    private async void MenuClick(RoomViewMenu.EType index)
+    {
+        EnvironmentSetting.Debug($"MenuClick:{index}");
+        roomViewData.Menu.DisplayCss = "display: none;";
+
+        if (index == RoomViewMenu.EType.Maid)
+        {
+            var ret = await roomViewData.Menu.SetRoomStatus(false);
+        }
+        else if (index == RoomViewMenu.EType.Finish)
+        {
+            var ret = await roomViewData.Menu.SetRoomStatus(true);
+        }
+        else if (index == RoomViewMenu.EType.Resv)
+        {
+            // new Guid キー
+            //Guid key = Guid.NewGuid();
+            //CacheStorage.Instance.Set(key.ToString(), "Dataだよ");  //簡単&乱暴
+            //if (module is not null)
+            //{
+            //    BrowserResizeService.OnResize -= BrowserHasResized;
+            //    await module.InvokeAsync<object>("removeResizeCallback");
+            //    await module.DisposeAsync();
+            //    module = null;
+            //}
+            NavigationManager.NavigateTo($"usedetail/input", new NavigationOptions
+                {
+                    ForceLoad = false,
+                    ReplaceHistoryEntry = false,
+                    HistoryEntryState = new Parameter.UseInputArgs { Guid = Guid.NewGuid().ToString(), CinDate = CConvert.ToDateString(useDate) }.ToJson(),
+                });
+            return;
+        }
+
+        await ShowTab();
+        StateHasChanged();
+    }
+
+    private void ColSetting()
+    {
+        roomViewData.Tabs.RemoveAt(0);
+        StateHasChanged();
+    }
+
+    private async Task ShowTab(int index = -1)
+    {
+        await LoadingSpinner.ShowAsync();
+        visibled = false;
+        if (index >= 0) { roomViewData.ActiveTabIndex = index; }
+        EnvironmentSetting.Debug($"ActiveTabIndex = {roomViewData.ActiveTabIndex}");
+        await roomViewData.GetData(GetUseDate(), index >= 0);
+        visibled = true;
+        await LoadingSpinner.HideAsync();
+    }
+
+    private async Task ReadHotelDate()
+    {
+        useDate = await EnvironmentSetting.GetHotelDate();
+        await ShowTab();
+    }
+
+    private async Task Read()
+    {
+            // GrpcChannelOptions options = new GrpcChannelOptions()
+            // {
+            //     MaxReceiveMessageSize = int.MaxValue,
+            //     HttpHandler = new GrpcWebHandler(new HttpClientHandler())
+            // };
+            // using (var Channel = GrpcChannel.ForAddress("https://ginbow.eu.org", options))
+            // {
+            //     HelloRequest request = new HelloRequest();
+            //     request.Name = "aaa";
+            //     var client = new Greeter.GreeterClient(Channel);
+            //     EnvironmentSetting.Debug($"開始");
+            //     HelloReply reply = await client.SayHelloAsync(request);
+            //     EnvironmentSetting.Debug($"Response: {reply.ToString()}");
+            //     //Console.WriteLine($"Response: {reply.ToString()}");
+            // }
+
+
+        await ShowTab();
+    }
+
+    private async Task TabChanged(int index)
+    {
+        await ShowTab(index);
+    }
+}

--
Gitblit v1.10.0