mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-01-18 13:26:47 +01:00
Editor: Use offcanvas for all breakpoints (#6441)
Avoids scrolling the editor out of the viewport. Closes #6436. Done for the POS/Crowdfund editor, as well as the Forms one.
This commit is contained in:
parent
341bea48f8
commit
a8d1f55544
@ -1240,15 +1240,17 @@ namespace BTCPayServer.Tests
|
||||
s.Driver.FindElement(By.Id("Title")).SendKeys("Tea shop");
|
||||
s.Driver.FindElement(By.CssSelector("label[for='DefaultView_Cart']")).Click();
|
||||
s.Driver.FindElement(By.CssSelector(".template-item:nth-of-type(1)")).Click();
|
||||
s.Driver.WaitUntilAvailable(By.Id("BuyButtonText"));
|
||||
s.Driver.FindElement(By.Id("BuyButtonText")).SendKeys("Take my money");
|
||||
s.Driver.FindElement(By.Id("EditorCategories-ts-control")).SendKeys("Drinks");
|
||||
s.Driver.FindElement(By.CssSelector(".offcanvas-header button")).Click();
|
||||
s.Driver.WaitUntilAvailable(By.Id("CodeTabButton"));
|
||||
s.Driver.ScrollTo(By.Id("CodeTabButton"));
|
||||
s.Driver.FindElement(By.Id("CodeTabButton")).Click();
|
||||
var template = s.Driver.FindElement(By.Id("TemplateConfig")).GetAttribute("value");
|
||||
Assert.Contains("\"buyButtonText\": \"Take my money\"", template);
|
||||
Assert.Matches("\"categories\": \\[\r?\n\\s*\"Drinks\"\\s*\\]", template);
|
||||
|
||||
|
||||
s.ClickPagePrimary();
|
||||
Assert.Contains("App updated", s.FindAlertMessage().Text);
|
||||
|
||||
@ -1453,12 +1455,15 @@ namespace BTCPayServer.Tests
|
||||
s.GoToUrl(editUrl);
|
||||
s.Driver.ScrollTo(By.Id("btAddItem"));
|
||||
s.Driver.FindElement(By.Id("btAddItem")).Click();
|
||||
s.Driver.WaitUntilAvailable(By.Id("EditorTitle"));
|
||||
s.Driver.FindElement(By.Id("EditorTitle")).SendKeys("Perk 1");
|
||||
s.Driver.FindElement(By.Id("EditorAmount")).SendKeys("20");
|
||||
// Test autogenerated ID
|
||||
Assert.Equal("perk-1", s.Driver.FindElement(By.Id("EditorId")).GetAttribute("value"));
|
||||
s.Driver.FindElement(By.Id("EditorId")).Clear();
|
||||
s.Driver.FindElement(By.Id("EditorId")).SendKeys("Perk-1");
|
||||
s.Driver.FindElement(By.CssSelector(".offcanvas-header button")).Click();
|
||||
s.Driver.WaitUntilAvailable(By.Id("CodeTabButton"));
|
||||
s.Driver.ScrollTo(By.Id("CodeTabButton"));
|
||||
s.Driver.FindElement(By.Id("CodeTabButton")).Click();
|
||||
var template = s.Driver.FindElement(By.Id("TemplateConfig")).GetAttribute("value");
|
||||
|
@ -54,70 +54,66 @@
|
||||
{
|
||||
<div asp-validation-summary="All" class="@(ViewContext.ModelState.ErrorCount.Equals(1) ? "no-marker" : "")"></div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-sm-10 col-md-9 col-xl-7 col-xxl-6">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label asp-for="AppName" class="form-label" data-required></label>
|
||||
<input asp-for="AppName" class="form-control" required />
|
||||
<span asp-validation-for="AppName" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label asp-for="Title" class="form-label" data-required></label>
|
||||
<input asp-for="Title" class="form-control" required />
|
||||
<span asp-validation-for="Title" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="max-width:540px;">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label asp-for="Tagline" class="form-label"></label>
|
||||
<input asp-for="Tagline" class="form-control" />
|
||||
<span asp-validation-for="Tagline" class="text-danger"></span>
|
||||
<label asp-for="AppName" class="form-label" data-required></label>
|
||||
<input asp-for="AppName" class="form-control" required />
|
||||
<span asp-validation-for="AppName" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<div class="d-flex align-items-center justify-content-between gap-2">
|
||||
<label asp-for="MainImageFile" class="form-label"></label>
|
||||
<label asp-for="Title" class="form-label" data-required></label>
|
||||
<input asp-for="Title" class="form-control" required />
|
||||
<span asp-validation-for="Title" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Tagline" class="form-label"></label>
|
||||
<input asp-for="Tagline" class="form-control" />
|
||||
<span asp-validation-for="Tagline" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="d-flex align-items-center justify-content-between gap-2">
|
||||
<label asp-for="MainImageFile" class="form-label"></label>
|
||||
@if (!string.IsNullOrEmpty(Model.MainImageUrl))
|
||||
{
|
||||
<button type="submit" class="btn btn-link p-0 text-danger" name="RemoveLogoFile" value="true">
|
||||
<vc:icon symbol="cross" /> <span text-translate="true">Remove</span>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
@if (canUpload)
|
||||
{
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<input asp-for="MainImageFile" type="file" class="form-control flex-grow">
|
||||
@if (!string.IsNullOrEmpty(Model.MainImageUrl))
|
||||
{
|
||||
<button type="submit" class="btn btn-link p-0 text-danger" name="RemoveLogoFile" value="true">
|
||||
<vc:icon symbol="cross" /> <span text-translate="true">Remove</span>
|
||||
</button>
|
||||
<img src="@Model.MainImageUrl" alt="Logo" style="height:2.1rem;max-width:10.5rem;" />
|
||||
}
|
||||
</div>
|
||||
@if (canUpload)
|
||||
{
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<input asp-for="MainImageFile" type="file" class="form-control flex-grow">
|
||||
@if (!string.IsNullOrEmpty(Model.MainImageUrl))
|
||||
{
|
||||
<img src="@Model.MainImageUrl" alt="Logo" style="height:2.1rem;max-width:10.5rem;" />
|
||||
}
|
||||
</div>
|
||||
<span asp-validation-for="MainImageFile" class="text-danger"></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<input asp-for="MainImageFile" type="file" class="form-control" disabled>
|
||||
<div class="form-text">@ViewLocalizer["In order to upload, a {0} must be configured.", Html.ActionLink(StringLocalizer["file storage"], "Files", "UIServer")]</div>
|
||||
}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="d-flex align-items-center">
|
||||
<input asp-for="Enabled" type="checkbox" class="btcpay-toggle me-3"/>
|
||||
<div>
|
||||
<label asp-for="Enabled" class="form-check-label"></label>
|
||||
<span asp-validation-for="Enabled" class="text-danger"></span>
|
||||
<div class="text-muted" text-translate="true">The crowdfund will be visible to anyone.</div>
|
||||
</div>
|
||||
<span asp-validation-for="MainImageFile" class="text-danger"></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<input asp-for="MainImageFile" type="file" class="form-control" disabled>
|
||||
<div class="form-text">@ViewLocalizer["In order to upload, a {0} must be configured.", Html.ActionLink(StringLocalizer["file storage"], "Files", "UIServer")]</div>
|
||||
}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="d-flex align-items-center">
|
||||
<input asp-for="Enabled" type="checkbox" class="btcpay-toggle me-3"/>
|
||||
<div>
|
||||
<label asp-for="Enabled" class="form-check-label"></label>
|
||||
<span asp-validation-for="Enabled" class="text-danger"></span>
|
||||
<div class="text-muted" text-translate="true">The crowdfund will be visible to anyone.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3">
|
||||
<div class="col-xl-10 col-xxl-constrain">
|
||||
<div class="col-xxl-constrain">
|
||||
<div class="form-group">
|
||||
<label asp-for="Description" class="form-label" data-required></label>
|
||||
<textarea asp-for="Description" rows="20" cols="40" class="form-control richtext"></textarea>
|
||||
|
@ -58,47 +58,43 @@
|
||||
{
|
||||
<div asp-validation-summary="All" class="@(ViewContext.ModelState.ErrorCount.Equals(1) ? "no-marker" : "")"></div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-sm-10 col-md-9 col-xl-7 col-xxl-6">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label asp-for="AppName" class="form-label" data-required></label>
|
||||
<input asp-for="AppName" class="form-control" required />
|
||||
<span asp-validation-for="AppName" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label asp-for="Title" class="form-label" data-required></label>
|
||||
<input asp-for="Title" class="form-control" required />
|
||||
<span asp-validation-for="Title" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="max-width:540px;">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label asp-for="DefaultView" class="form-label" data-required text-translate="true">Choose Point of Sale Style</label>
|
||||
<div class="btcpay-list-select">
|
||||
@foreach (var type in Enum.GetValues<PosViewType>())
|
||||
{
|
||||
<input type="radio" asp-for="DefaultView" value="@type" id="DefaultView_@type">
|
||||
<label for="DefaultView_@type" class="btcpay-list-select-item">
|
||||
<vc:icon symbol="pos-@type.ToString().ToLowerInvariant()" />
|
||||
@typeof(PosViewType).DisplayName(type.ToString())
|
||||
</label>
|
||||
}
|
||||
</div>
|
||||
<label asp-for="AppName" class="form-label" data-required></label>
|
||||
<input asp-for="AppName" class="form-control" required />
|
||||
<span asp-validation-for="AppName" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group mb-0">
|
||||
<label asp-for="Currency" class="form-label"></label>
|
||||
<input asp-for="Currency" class="form-control w-auto" currency-selection />
|
||||
<div class="form-text">@StringLocalizer["Uses the store's default currency ({0}) if empty.", Model.StoreDefaultCurrency]</div>
|
||||
<span asp-validation-for="Currency" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label asp-for="Title" class="form-label" data-required></label>
|
||||
<input asp-for="Title" class="form-control" required />
|
||||
<span asp-validation-for="Title" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="DefaultView" class="form-label" data-required text-translate="true">Choose Point of Sale Style</label>
|
||||
<div class="btcpay-list-select">
|
||||
@foreach (var type in Enum.GetValues<PosViewType>())
|
||||
{
|
||||
<input type="radio" asp-for="DefaultView" value="@type" id="DefaultView_@type">
|
||||
<label for="DefaultView_@type" class="btcpay-list-select-item">
|
||||
<vc:icon symbol="pos-@type.ToString().ToLowerInvariant()" />
|
||||
@typeof(PosViewType).DisplayName(type.ToString())
|
||||
</label>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mb-0">
|
||||
<label asp-for="Currency" class="form-label"></label>
|
||||
<input asp-for="Currency" class="form-control w-auto" currency-selection />
|
||||
<div class="form-text">@StringLocalizer["Uses the store's default currency ({0}) if empty.", Model.StoreDefaultCurrency]</div>
|
||||
<span asp-validation-for="Currency" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="description" class="row mt-4">
|
||||
<div class="col-xl-10 col-xxl-constrain">
|
||||
<div class="col-xxl-constrain">
|
||||
<div class="form-group mb-0">
|
||||
<label asp-for="Description" class="form-label"></label>
|
||||
<textarea asp-for="Description" rows="10" cols="40" class="form-control richtext"></textarea>
|
||||
|
@ -139,7 +139,7 @@
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="EditorTabPane" role="tabpanel" aria-labelledby="EditorTabButton" tabindex="0">
|
||||
<div class="row align-items-start">
|
||||
<div class="col-12 col-xl-7">
|
||||
<div class="col-12">
|
||||
<items-editor :items="items"
|
||||
:selected-item="selectedItem"
|
||||
v-on:add-item="addItem"
|
||||
@ -149,13 +149,13 @@
|
||||
:class="{ 'pt-2': (!items || items.length === 0) }"
|
||||
class="bg-tile pb-2 rounded" />
|
||||
</div>
|
||||
<div class="col-xl-5 offcanvas-xl offcanvas-end" tabindex="-1" ref="editorOffcanvas">
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" ref="editorOffcanvas">
|
||||
<div class="offcanvas-header justify-content-between p-3">
|
||||
<h5 class="offcanvas-title" text-translate="true">Edit Item</h5>
|
||||
<button type="button" class="btn btn-sm rounded-pill" :class="{ 'btn-primary': itemChanged, 'btn-outline-secondary': !itemChanged }" v-on:click="hideOffcanvas" v-text="itemChanged ? 'Apply' : 'Close'"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body p-3 p-xl-0">
|
||||
<item-editor ref="itemEditor" :item="selectedItem" class="bg-tile w-100 p-xl-4 rounded" />
|
||||
<div class="offcanvas-body p-3">
|
||||
<item-editor ref="itemEditor" :item="selectedItem" class="bg-tile w-100 rounded" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -236,7 +236,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="FormEditor" class="editor">
|
||||
<div id="FormEditor" class="editor col-xxl-constrain">
|
||||
<div class="d-flex flex-wrap align-items-end justify-content-between gap-3 mb-3">
|
||||
<ul class="nav nav-pills gap-4" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
@ -255,7 +255,7 @@
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="EditorTabPane" role="tabpanel" aria-labelledby="EditorTabButton" tabindex="0">
|
||||
<div class="row align-items-start">
|
||||
<div class="col-12 col-xl-7">
|
||||
<div class="col-12">
|
||||
<fields-editor :path="[]"
|
||||
:fields="fields"
|
||||
:selected-field="selectedField"
|
||||
@ -266,15 +266,15 @@
|
||||
:class="{ 'pt-2': (!fields || fields.length === 0) }"
|
||||
class="bg-tile pb-2 rounded" />
|
||||
</div>
|
||||
<div class="col-xl-5 offcanvas-xl offcanvas-end" tabindex="-1" ref="editorOffcanvas">
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" ref="editorOffcanvas">
|
||||
<div class="offcanvas-header justify-content-between p-3">
|
||||
<h5 class="offcanvas-title" text-translate="true">Edit Field</h5>
|
||||
<button type="button" class="btn-close" aria-label="@StringLocalizer["Close"]" v-on:click="hideOffcanvas">
|
||||
<vc:icon symbol="close" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="offcanvas-body p-3 p-xl-0">
|
||||
<field-editor :field="selectedField" class="bg-tile w-100 p-xl-4 rounded" />
|
||||
<div class="offcanvas-body p-3">
|
||||
<field-editor :field="selectedField" class="bg-tile w-100 rounded" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user