@using BTCPayServer.Views.Stores @using BTCPayServer.Abstractions.Extensions @using BTCPayServer.Abstractions.Models @using BTCPayServer.Client @using BTCPayServer.Client.Models @using ExchangeSharp @model BTCPayServer.Models.WalletViewModels.PullPaymentsModel @{ var storeId = Context.GetStoreData().Id; ViewData.SetActivePage(StoreNavPages.PullPayments, "Pull Payments", storeId); var nextStartDateSortOrder = (string)ViewData["NextStartSortOrder"]; string startDateSortOrder = null; switch (nextStartDateSortOrder) { case "asc": startDateSortOrder = "desc"; break; case "desc": startDateSortOrder = "asc"; break; } var sortIconClass = "fa-sort"; if (startDateSortOrder != null) { sortIconClass = $"fa-sort-alpha-{startDateSortOrder}"; } var sortByDesc = "Sort by descending..."; var sortByAsc = "Sort by ascending..."; } @section PageHeadContent { <style> .tooltip-inner { text-align: left; } </style> } <div class="sticky-header d-flex align-items-center justify-content-between"> <h2 class="mb-0"> @ViewData["Title"] <a href="#descriptor" data-bs-toggle="collapse"> <vc:icon symbol="info" /> </a> </h2> <a permission="@Policies.CanCreateNonApprovedPullPayments" asp-action="NewPullPayment" asp-route-storeId="@storeId" class="btn btn-primary" role="button" id="NewPullPayment"> Create Pull Payment </a> </div> <div id="descriptor" class="collapse"> <div class="d-flex px-4 py-4 mb-4 bg-tile rounded"> <div class="flex-fill"> <p class="mb-3">Pull Payments allow receivers to claim specified funds from your wallet at their convenience. Once submitted and approved, the funds will be released.</p> <a href="https://docs.btcpayserver.org/PullPayments/" target="_blank" rel="noreferrer noopener">Learn More</a> </div> <button type="button" class="btn-close ms-auto" data-bs-toggle="collapse" data-bs-target="#descriptor" aria-expanded="false" aria-label="Close"> <vc:icon symbol="close" /> </button> </div> </div> <partial name="_StatusMessage" /> <nav id="SectionNav" class="mb-3"> <div class="nav"> @foreach (var state in Enum.GetValues(typeof(PullPaymentState)).Cast<PullPaymentState>()) { <a id="@state-view" asp-action="PullPayments" asp-route-storeId="@storeId" asp-route-pullPaymentState="@state" class="nav-link @(state == Model.ActiveState ? "active" : "")" role="tab">@state</a> } </div> </nav> @if (Model.PullPayments.Any()) { @foreach (var pp in Model.PullPayments) { <script id="tooptip_template_@pp.Id" type="text/template"> <span>Awaiting: <span class="float-end">@pp.Progress.AwaitingFormatted</span></span> <br /> <span>Completed: <span class="float-end">@pp.Progress.CompletedFormatted</span></span> <br /> <span>Limit: <span class="float-end">@pp.Progress.LimitFormatted</span></span> @if (pp.Progress.ResetIn != null) { <br /> <span>Resets in: <span class="float-end">@pp.Progress.ResetIn</span></span> } @if (pp.Progress.EndIn != null) { <br /> <span>Expires in: <span class="float-end">@pp.Progress.EndIn</span></span> } </script> } <div class="table-responsive"> <table class="table table-hover"> <thead> <tr> <th scope="col" class="date-col"> <div class="d-flex align-items-center gap-2"> <a asp-action="PullPayments" asp-route-sortOrder="@(nextStartDateSortOrder ?? "asc")" asp-route-pullPaymentState="@Model.ActiveState" class="text-nowrap" title="@(nextStartDateSortOrder == "desc" ? sortByAsc : sortByDesc)"> Start <span class="fa @(sortIconClass)"></span> </a> <button type="button" class="btn btn-link p-0 fa fa-clock-o switch-time-format only-for-js" title="Switch date format"></button> </div> </th> <th scope="col">Name</th> <th scope="col">Automatically Approved</th> <th scope="col">Refunded</th> <th scope="col" class="actions-col"></th> </tr> </thead> <tbody> @foreach (var pp in Model.PullPayments) { <tr class="mass-action-row"> <td class="date-col">@pp.StartDate.ToBrowserDate()</td> <td> <a permission="@Policies.CanManagePullPayments" asp-action="EditPullPayment" asp-controller="UIPullPayment" asp-route-storeId="@storeId" asp-route-pullPaymentId="@pp.Id"> @pp.Name </a> <span not-permission="@Policies.CanManagePullPayments">@pp.Name</span> </td> <td>@pp.AutoApproveClaims</td> <td class="align-middle"> <div class="progress ppProgress" data-pp="@pp.Id" data-bs-toggle="tooltip" data-bs-html="true"> <div class="progress-bar" role="progressbar" aria-valuenow="@pp.Progress.CompletedPercent" aria-valuemin="0" aria-valuemax="100" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width:@(pp.Progress.CompletedPercent)%;"> </div> <div class="progress-bar" role="progressbar" aria-valuenow="@pp.Progress.AwaitingPercent" aria-valuemin="0" aria-valuemax="100" style="background-color:orange; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width:@(pp.Progress.AwaitingPercent)%;"> </div> </div> </td> <td class="actions-col"> <div class="d-inline-flex align-items-center gap-3"> <a asp-action="ViewPullPayment" permission="@Policies.CanViewPullPayments" asp-controller="UIPullPayment" asp-route-pullPaymentId="@pp.Id" target="_blank"> View </a> <a class="pp-payout" permission="@Policies.CanViewPayouts" asp-action="Payouts" asp-route-storeId="@storeId" asp-route-pullPaymentId="@pp.Id"> Payouts </a> @if (!pp.Archived) { <a asp-action="ArchivePullPayment" permission="@Policies.CanArchivePullPayments" asp-route-storeId="@storeId" asp-route-pullPaymentId="@pp.Id" data-bs-toggle="modal" data-bs-target="#ConfirmModal" data-description="Do you really want to archive the pull payment <strong>@Html.Encode(pp.Name)</strong>?"> Archive </a> } </div> </td> </tr> } </tbody> </table> </div> <vc:pager view-model="Model" /> <partial name="_Confirm" model="@(new ConfirmModel("Archive pull payment", "Do you really want to archive the pull payment?", "Archive"))" /> @section PageFootContent { <script> const ppProgresses = document.getElementsByClassName("ppProgress"); for (var i = 0; i < ppProgresses.length; i++) { var pp = ppProgresses[i]; var ppId = pp.getAttribute("data-pp"); var template = document.getElementById("tooptip_template_" + ppId); pp.setAttribute("title", template.innerHTML); } </script> } } else { <p class="text-secondary mt-4"> There are no @Model.ActiveState.ToStringLowerInvariant() pull payments yet. </p> }