Merge pull request #1303 from btcpayserver/feat/viewnewwindow

Providing open in new window split buttons
This commit is contained in:
rockstardev 2020-01-24 15:34:25 -06:00 committed by GitHub
commit 666682677c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 109 additions and 86 deletions

View file

@ -22,8 +22,8 @@ namespace BTCPayServer.Controllers
return String.Empty;
}
}
[HttpGet]
[Route("{appId}/settings/crowdfund")]
public async Task<IActionResult> UpdateCrowdfund(string appId)
@ -61,8 +61,8 @@ namespace BTCPayServer.Controllers
SearchTerm = app.TagAllInvoices ? $"storeid:{app.StoreDataId}" : $"orderid:{AppService.GetCrowdfundOrderId(appId)}",
DisplayPerksRanking = settings.DisplayPerksRanking,
SortPerksByPopularity = settings.SortPerksByPopularity,
Sounds = string.Join(Environment.NewLine, settings.Sounds),
AnimationColors = string.Join(Environment.NewLine, settings.AnimationColors)
Sounds = string.Join(Environment.NewLine, settings.Sounds),
AnimationColors = string.Join(Environment.NewLine, settings.AnimationColors)
};
return View(vm);
}
@ -70,9 +70,9 @@ namespace BTCPayServer.Controllers
[Route("{appId}/settings/crowdfund")]
public async Task<IActionResult> UpdateCrowdfund(string appId, UpdateCrowdfundViewModel vm, string command)
{
if (!string.IsNullOrEmpty( vm.TargetCurrency) && _currencies.GetCurrencyData(vm.TargetCurrency, false) == null)
if (!string.IsNullOrEmpty(vm.TargetCurrency) && _currencies.GetCurrencyData(vm.TargetCurrency, false) == null)
ModelState.AddModelError(nameof(vm.TargetCurrency), "Invalid currency");
try
{
_AppService.Parse(vm.PerksTemplate, vm.TargetCurrency).ToString();
@ -98,14 +98,14 @@ namespace BTCPayServer.Controllers
}
var parsedSounds = vm.Sounds.Split(
new[] {"\r\n", "\r", "\n"},
new[] { "\r\n", "\r", "\n" },
StringSplitOptions.None
).Select(s => s.Trim()).ToArray();
if (vm.SoundsEnabled && !parsedSounds.Any())
{
ModelState.AddModelError(nameof(vm.Sounds), "You must have at least one sound if you enable sounds");
}
var parsedAnimationColors = vm.AnimationColors.Split(
new[] { "\r\n", "\r", "\n" },
StringSplitOptions.None
@ -114,13 +114,13 @@ namespace BTCPayServer.Controllers
{
ModelState.AddModelError(nameof(vm.AnimationColors), "You must have at least one animation color if you enable animations");
}
if (!ModelState.IsValid)
{
return View(vm);
}
var app = await GetOwnedApp(appId, AppType.Crowdfund);
if (app == null)
return NotFound();
@ -157,24 +157,16 @@ namespace BTCPayServer.Controllers
app.TagAllInvoices = vm.UseAllStoreInvoices;
app.SetSettings(newSettings);
if (command == "save")
{
await _AppService.UpdateOrCreateApp(app);
await _AppService.UpdateOrCreateApp(app);
_EventAggregator.Publish(new AppUpdated()
{
AppId = appId,
StoreId = app.StoreDataId,
Settings = newSettings
});
TempData[WellKnownTempData.SuccessMessage] = "App updated";
return RedirectToAction(nameof(UpdateCrowdfund), new { appId });
}
else if (command == "viewapp")
_EventAggregator.Publish(new AppUpdated()
{
return RedirectToAction(nameof(AppsPublicController.ViewCrowdfund), "AppsPublic", new { appId });
}
return NotFound();
AppId = appId,
StoreId = app.StoreDataId,
Settings = newSettings
});
TempData[WellKnownTempData.SuccessMessage] = "App updated";
return RedirectToAction(nameof(UpdateCrowdfund), new { appId });
}
}
}

View file

@ -79,9 +79,9 @@ namespace BTCPayServer.Controllers
public string CustomCSSLink { get; set; }
public string EmbeddedCSS { get; set; }
public string Description { get; set; }
public string NotificationEmail { get; set; }
public string NotificationUrl { get; set; }
@ -96,7 +96,7 @@ namespace BTCPayServer.Controllers
if (app == null)
return NotFound();
var settings = app.GetSettings<PointOfSaleSettings>();
var vm = new UpdatePointOfSaleViewModel()
{
NotificationEmailWarning = !await IsEmailConfigured(app.StoreDataId),
@ -119,7 +119,7 @@ namespace BTCPayServer.Controllers
NotificationEmail = settings.NotificationEmail,
NotificationUrl = settings.NotificationUrl,
SearchTerm = $"storeid:{app.StoreDataId}",
RedirectAutomatically = settings.RedirectAutomatically.HasValue? settings.RedirectAutomatically.Value? "true": "false" : ""
RedirectAutomatically = settings.RedirectAutomatically.HasValue ? settings.RedirectAutomatically.Value ? "true" : "false" : ""
};
if (HttpContext?.Request != null)
{
@ -197,8 +197,8 @@ namespace BTCPayServer.Controllers
NotificationEmail = vm.NotificationEmail,
Description = vm.Description,
EmbeddedCSS = vm.EmbeddedCSS,
RedirectAutomatically = string.IsNullOrEmpty(vm.RedirectAutomatically)? (bool?) null: bool.Parse(vm.RedirectAutomatically)
RedirectAutomatically = string.IsNullOrEmpty(vm.RedirectAutomatically) ? (bool?)null : bool.Parse(vm.RedirectAutomatically)
});
await _AppService.UpdateOrCreateApp(app);
TempData[WellKnownTempData.SuccessMessage] = "App updated";
@ -211,8 +211,8 @@ namespace BTCPayServer.Controllers
if (string.IsNullOrEmpty(list))
{
return Array.Empty<int>();
}
else
}
else
{
// Remove all characters except numeric and comma
Regex charsToDestroy = new Regex(@"[^\d|\" + separator + "]");

View file

@ -10,16 +10,20 @@ namespace BTCPayServer.Models.AppViewModels
public class UpdateCrowdfundViewModel
{
public string StoreId { get; set; }
[Required] [MaxLength(30)] public string Title { get; set; }
[Required]
[MaxLength(30)]
public string Title { get; set; }
[MaxLength(50)] public string Tagline { get; set; }
[MaxLength(50)]
public string Tagline { get; set; }
[Required]
public string Description { get; set; }
[Required] public string Description { get; set; }
[Display(Name = "Featured Image")]
public string MainImageUrl { get; set; }
[Display(Name = "Callback Notification Url")]
[Display(Name = "Callback Notification Url")]
[Uri]
public string NotificationUrl { get; set; }
[Display(Name = "Invoice IPN Notification")]
@ -59,7 +63,8 @@ namespace BTCPayServer.Models.AppViewModels
public IEnumerable<string> ResetEveryValues = Enum.GetNames(typeof(CrowdfundResetEvery));
[Display(Name = "Reset goal every")] public string ResetEvery { get; set; } = nameof(CrowdfundResetEvery.Never);
[Display(Name = "Reset goal every")]
public string ResetEvery { get; set; } = nameof(CrowdfundResetEvery.Never);
public int ResetEveryAmount { get; set; } = 1;
@ -78,7 +83,7 @@ namespace BTCPayServer.Models.AppViewModels
public string EmbeddedCSS { get; set; }
[Display(Name = "Count all invoices created on the store as part of the crowdfunding goal")]
public bool UseAllStoreInvoices { get; set; }
public bool UseAllStoreInvoices { get; set; }
public string AppId { get; set; }
public string SearchTerm { get; set; }
@ -90,10 +95,18 @@ namespace BTCPayServer.Models.AppViewModels
[Display(Name = "Sounds to play when a payment is made. One sound per line")]
public string Sounds{ get; set; }
public string Sounds { get; set; }
[Display(Name = "Colors to rotate between with animation when a payment is made. First color is the default background. One color per line. Can be any valid css color value.")]
public string AnimationColors{ get; set; }
public string AnimationColors { get; set; }
public bool NotificationEmailWarning { get; set; }
// NOTE: Improve validation if needed
public bool ModelWithMinimumData
{
get { return Description != null && Title != null && TargetCurrency != null; }
}
}
}

View file

@ -56,9 +56,13 @@
<td style="text-align:right">
@if (app.IsOwner)
{
<a asp-action="@app.UpdateAction" asp-controller="Apps" asp-route-appId="@app.Id">Settings</a><span> - </span>
<a asp-action="@app.UpdateAction" asp-controller="Apps" asp-route-appId="@app.Id">Settings</a>
<span> - </span>
}
<a asp-action="@app.ViewAction" asp-controller="AppsPublic" asp-route-appId="@app.Id">View</a><span> - </span>
<a asp-action="@app.ViewAction" asp-controller="AppsPublic" asp-route-appId="@app.Id">View</a>
<a asp-action="@app.ViewAction" asp-controller="AppsPublic" asp-route-appId="@app.Id" target="_blank"
title="View in New Window"><span class="fa fa-external-link"></span></a>
<span> - </span>
<a asp-action="DeleteApp" asp-route-appId="@app.Id">Remove</a>
</td>
</tr>

View file

@ -215,13 +215,21 @@
</div>
<input type="hidden" asp-for="NotificationEmailWarning" />
<div class="form-group">
<button name="command" type="submit" class="btn btn-primary" value="save" id="SaveSettings">Save settings</button>
<a class="btn btn-secondary" target="_blank" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@Model.SearchTerm">Invoices</a>
@if ((Model.Description != null) && (Model.Title != null) && (Model.TargetCurrency != null))
<button type="submit" class="btn btn-primary" id="SaveSettings">Save Settings</button>
<div class="btn-group">
<a class="btn btn-outline-primary" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@Model.SearchTerm">Invoices</a>
<a class="btn btn-outline-primary" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@Model.SearchTerm"
target="viewinvoices_@Model.AppId"><span class="fa fa-external-link"></span></a>
</div>
@if (Model.ModelWithMinimumData)
{
<button name="command" type="submit" value="viewapp" class="btn btn-secondary" id="ViewApp">View App</button>
<div class="btn-group">
<a class="btn btn-outline-primary" asp-action="ViewCrowdfund" asp-controller="AppsPublic" asp-route-appId="@Model.AppId" id="ViewApp">View App</a>
<a class="btn btn-outline-primary" asp-action="ViewCrowdfund" asp-controller="AppsPublic" asp-route-appId="@Model.AppId"
target="viewapp_@Model.AppId"><span class="fa fa-external-link"></span></a>
</div>
}
<a class="btn btn-secondary" target="_blank" asp-action="ListApps">Back to the app list</a>
<a class="btn btn-outline-primary" target="_blank" asp-action="ListApps">Back to the app list</a>
</div>
</form>
</div>
@ -255,13 +263,12 @@
</div>
<div class="col-sm-3">
<label>Price</label>*
<input
class="js-product-price form-control mb-2"
inputmode="numeric"
pattern="\d*"
step="any"
type="number"
value="{price}" />
<input class="js-product-price form-control mb-2"
inputmode="numeric"
pattern="\d*"
step="any"
type="number"
value="{price}" />
</div>
<div class="col-sm-3">
<label>Custom price</label>
@ -285,7 +292,7 @@
<div class="form-row">
<div class="col">
<label>Inventory (leave blank to not use inventory feature)</label>
<input type="number" step="1" class="js-product-inventory form-control mb-2" value="{inventory}"/>
<input type="number" step="1" class="js-product-inventory form-control mb-2" value="{inventory}" />
</div>
</div>
</div>

View file

@ -145,10 +145,18 @@
</div>
<input type="hidden" asp-for="NotificationEmailWarning" />
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Save Settings" id="SaveSettings" />
<a class="btn btn-secondary" target="_blank" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@Model.SearchTerm">Invoices</a>
<a class="btn btn-secondary" target="_blank" asp-action="ViewPointOfSale" asp-controller="AppsPublic" asp-route-appId="@Model.Id" id="ViewApp">View App</a>
<a class="btn btn-secondary" target="_blank" asp-action="ListApps">Back to the app list</a>
<button type="submit" class="btn btn-primary" id="SaveSettings">Save Settings</button>
<div class="btn-group">
<a class="btn btn-outline-primary" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@Model.SearchTerm">Invoices</a>
<a class="btn btn-outline-primary" asp-action="ListInvoices" asp-controller="Invoice" asp-route-searchterm="@Model.SearchTerm"
target="viewinvoices_@Model.Id"><span class="fa fa-external-link"></span></a>
</div>
<div class="btn-group">
<a class="btn btn-outline-primary" asp-action="ViewPointOfSale" asp-controller="AppsPublic" asp-route-appId="@Model.Id" id="ViewApp">View App</a>
<a class="btn btn-outline-primary" asp-action="ViewPointOfSale" asp-controller="AppsPublic" asp-route-appId="@Model.Id"
target="viewapp_@Model.Id"><span class="fa fa-external-link"></span></a>
</div>
<a class="btn btn-outline-primary" target="_blank" asp-action="ListApps">Back to the app list</a>
</div>
<div class="form-group">
<div class="accordion" id="accordian-dev-info">
@ -253,12 +261,11 @@
</div>
<div class="col-sm-3">
<label>Price</label>*
<input
class="js-product-price form-control mb-2"
inputmode="numeric"
pattern="\d*"
type="number"
value="{price}" />
<input class="js-product-price form-control mb-2"
inputmode="numeric"
pattern="\d*"
type="number"
value="{price}" />
</div>
<div class="col-sm-3">
<label>Custom price</label>
@ -282,7 +289,7 @@
<div class="form-row">
<div class="col">
<label>Inventory (leave blank to not use inventory feature)</label>
<input type="number" step="1" class="js-product-inventory form-control mb-2" value="{inventory}"/>
<input type="number" step="1" class="js-product-inventory form-control mb-2" value="{inventory}" />
</div>
</div>
</div>

View file

@ -33,27 +33,27 @@
<bundle name="wwwroot/bundles/crowdfund-bundle.min.css"></bundle>
@if (!string.IsNullOrEmpty(Model.EmbeddedCSS))
{
@Safe.Raw($"<style>{Model.EmbeddedCSS}</style>");
@Safe.Raw($"<style>{Model.EmbeddedCSS}</style>");
}
</head>
<body>
@if (Context.Request.Query.ContainsKey("simple"))
{
@await Html.PartialAsync("/Views/AppsPublic/Crowdfund/MinimalCrowdfund.cshtml", Model)
}
else
{
<noscript>
@await Html.PartialAsync("/Views/AppsPublic/Crowdfund/MinimalCrowdfund.cshtml", Model)
</noscript>
if (Model.AnimationsEnabled)
@if (Context.Request.Query.ContainsKey("simple"))
{
<canvas id="fireworks"></canvas>
@await Html.PartialAsync("/Views/AppsPublic/Crowdfund/MinimalCrowdfund.cshtml", Model)
}
else
{
<noscript>
@await Html.PartialAsync("/Views/AppsPublic/Crowdfund/MinimalCrowdfund.cshtml", Model)
</noscript>
if (Model.AnimationsEnabled)
{
<canvas id="fireworks"></canvas>
}
@await Html.PartialAsync("/Views/AppsPublic/Crowdfund/VueCrowdfund.cshtml", Model)
}
@await Html.PartialAsync("/Views/AppsPublic/Crowdfund/VueCrowdfund.cshtml", Model)
}
</body>
</html>