This commit is contained in:
d11n 2023-08-09 15:47:28 +03:00 committed by GitHub
parent d67ebd957e
commit ed43fb2071
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 18 deletions

View file

@ -22,6 +22,7 @@ namespace BTCPayServer.Abstractions.Services
{
return _htmlHelper.Raw(_htmlSanitizer.Sanitize(value));
}
public IHtmlContent RawEncode(string value)
{
return _htmlHelper.Raw(HttpUtility.HtmlEncode(_htmlSanitizer.Sanitize(value)));

View file

@ -988,14 +988,14 @@ namespace BTCPayServer.Tests
Assert.True(s.Driver.PageSource.Contains("Tea shop"), "Unable to create PoS");
Assert.True(s.Driver.PageSource.Contains("Cart"), "PoS not showing correct default view");
Assert.True(s.Driver.PageSource.Contains("Take my money"), "PoS not showing correct default view");
Assert.Equal(6, s.Driver.FindElements(By.CssSelector(".posItem:not(.d-none)")).Count);
Assert.Equal(6, s.Driver.FindElements(By.CssSelector(".posItem.posItem--displayed")).Count);
var drinks = s.Driver.FindElement(By.CssSelector("label[for='Category-Drinks']"));
Assert.Equal("Drinks", drinks.Text);
drinks.Click();
Assert.Single(s.Driver.FindElements(By.CssSelector(".posItem:not(.d-none)")));
Assert.Single(s.Driver.FindElements(By.CssSelector(".posItem.posItem--displayed")));
s.Driver.FindElement(By.CssSelector("label[for='Category-*']")).Click();
Assert.Equal(6, s.Driver.FindElements(By.CssSelector(".posItem:not(.d-none)")).Count);
Assert.Equal(6, s.Driver.FindElements(By.CssSelector(".posItem.posItem--displayed")).Count);
s.Driver.Url = posBaseUrl + "/static";
Assert.False(s.Driver.PageSource.Contains("Cart"), "Static PoS not showing correct view");

View file

@ -64,14 +64,14 @@
: item.BuyButtonText;
buttonText = buttonText.Replace("{0}", formatted).Replace("{Price}", formatted);
var categories = new JArray(item.Categories ?? new object[] { });
<div class="col posItem" :class="{ 'posItem--inStock': inStock(@index) }" data-index="@index" data-search="@Safe.RawEncode(item.Title + " " + item.Description)" data-categories='@Safe.Json(categories)'>
<div class="col posItem posItem--displayed" :class="{ 'posItem--inStock': inStock(@index) }" data-index="@index" data-search="@Safe.RawEncode(item.Title + " " + item.Description)" data-categories='@Safe.Json(categories)'>
<div class="card h-100 px-0" v-on:click="addToCart(@index)">
@if (!string.IsNullOrWhiteSpace(item.Image))
{
<img class="card-img-top" src="@item.Image" alt="@item.Title" asp-append-version="true">
}
<div class="card-body p-3 d-flex flex-column gap-2">
<h5 class="card-title m-0">@Safe.RawEncode(item.Title)</h5>
<h5 class="card-title m-0">@Safe.Raw(item.Title)</h5>
<div class="d-flex gap-2 align-items-center">
@if (item.PriceType == ViewPointOfSaleViewModel.ItemPriceType.Topup || item.Price == 0)
{
@ -90,7 +90,7 @@
</div>
@if (!string.IsNullOrWhiteSpace(item.Description))
{
<p class="card-text">@Safe.RawEncode(item.Description)</p>
<p class="card-text">@Safe.Raw(item.Description)</p>
}
</div>
@if (inStock)
@ -104,7 +104,7 @@
</div>
}
<button type="button" class="btn btn-primary w-100" :disabled="!inStock(@index)">
@Safe.RawEncode(buttonText)
@Safe.Raw(buttonText)
</button>
</form>
<div class="posItem-added"><vc:icon symbol="checkmark" /></div>

View file

@ -87,6 +87,7 @@ header .cart-toggle-btn {
}
.posItem {
display: none;
position: relative;
}
.posItem.posItem--inStock {
@ -117,6 +118,15 @@ header .cart-toggle-btn {
.posItem--added .posItem-added {
opacity: .8;
}
.posItem--displayed {
display: flex;
}
.posItem--first {
margin-left: auto;
}
.posItem--last {
margin-right: auto;
}
@media (max-width: 991px) {
#cart {

View file

@ -68,19 +68,10 @@ document.addEventListener("DOMContentLoaded",function () {
},
watch: {
searchTerm(term) {
const t = term.toLowerCase();
this.forEachItem(item => {
const terms = decodeURIComponent(item.dataset.search.toLowerCase());
const included = terms.indexOf(t) !== -1
item.classList[included ? 'remove' : 'add']("d-none")
})
this.updateDisplay()
},
displayCategory(category) {
this.forEachItem(item => {
const categories = JSON.parse(item.dataset.categories)
const included = category === "*" || categories.includes(category)
item.classList[included ? 'remove' : 'add']("d-none")
})
this.updateDisplay()
},
cart: {
handler(newCart) {
@ -166,6 +157,27 @@ document.addEventListener("DOMContentLoaded",function () {
},
clearCart() {
this.cart = [];
},
displayItem(item) {
const inSearch = !this.searchTerm ||
decodeURIComponent(item.dataset.search ? item.dataset.search.toLowerCase() : '')
.indexOf(this.searchTerm.toLowerCase()) !== -1
const inCategories = this.displayCategory === "*" ||
(item.dataset.categories ? JSON.parse(item.dataset.categories) : [])
.includes(this.displayCategory)
return inSearch && inCategories
},
updateDisplay() {
this.forEachItem(item => {
item.classList[this.displayItem(item) ? 'add' : 'remove']('posItem--displayed')
item.classList.remove('posItem--first')
item.classList.remove('posItem--last')
})
const $displayed = this.$refs.posItems.querySelectorAll('.posItem.posItem--displayed')
if ($displayed.length > 0) {
$displayed[0].classList.add('posItem--first')
$displayed[$displayed.length - 1].classList.add('posItem--last')
}
}
},
mounted() {
@ -184,6 +196,7 @@ document.addEventListener("DOMContentLoaded",function () {
}
});
})
this.updateDisplay()
},
});
});