Activities of "henrry.arujo"

I was able to add a new microservice into ABP Studio:

how can I find details about developing the UI? If there is any sample code I can use, I will greatly appreciate it.

I appreciate your intention to help, but it is clear we are not in the same page of the book - this feels like going in circle. I will appreciate if you can either take a deeper look to what it is that I am asking, or if you could escalate it to someone else who may be more familiar with the issue at hand.

The question is about using **the latest Microservices solution ABP Commercial (v8.2.1). **

To be more specific: these steps https://abp.io/docs/latest/solution-templates/microservice/adding-new-microservices outline how to add a new microserive to an existing ABP Studio solution. But the new service created with these steps has no layers.

I tried following the same steps using the option to add a DDD Microservice. When the DDD microservice is created, it comes with layers, but the new DDD Service added does not have the required Module References, project references, etc. Basically, the template provided through the option of creating a DDD microservice is missing the baseline implementation.

What I have been asking all this time is this: once I have my microservices solution created using ABP Studio up and running, where can I find documentation how to add a new DDD microservice, configure it to work within the scope of the ABP Studio, and then add the business logic in the different layers: Application, Application.Contracts, Domain, Domain.Shared, EF Repositories etc.

I hope it makes this clear what is the type of question I'm asking for. If you need more clarification, please let me know, but I think it is clear by the context of what I am asking what the issue at hand is.

The question since the beginning about using microservices using the new ABP Commercial version 8.2.1. Let me be more specific - how to add business logic across the various layers, such as Application, Application.Contracts, Domain, Domain.Shared, and EF Repositories in the new ABP Commercial Microservices solution version 8.2? Is there any documentation how to add business logic, and custom repositories for the version 8.2?

Please note, i have reviewed the documentation for the new version. It only addresses how to create the solution and how to run it, but so far I could not find any details about how to add you own business logic, nor how the layers are represented. Can anyone point me in the right direction? Again, please note this is for the Commercial Microservices Template DDD version 8.2 and up.

Thank you for your response! I appreciate your help so far, and I’m looking for a bit more guidance to fully understand the solution.

Could you or anyone else please provide more details on how to appropriately add business logic across the various layers, such as Application, Application.Contracts, Domain, Domain.Shared, and EF Repositories?

Looking forward to your insights!

Thanks for the recommendation, we will try. If you have any code sample that you can share using vue calling the backend APIs and interacting with the middleware that will be helpful. Having a sample of the functionalities working will help us in the long run (rising less questions as we try to solve our business need).

Some of the cases we want to know how to cover with vue are:

  • add dynamic behaviour in the modal popup: completing a form as a wizzad passing to the next page when the current page is complete and validated
  • a shopping cart / invoice page where I can add a new row of an item, and recalculate realtime values such as quantity and amount, etc.
  • interaction with App Services either calling the Rest API or calling the method using dependency injection in the on post method of the index form.

again, if you have any code sample available that may how us how to cover some of these, it will be greatly appreciated

this is the logic for each file: CreateModal.cshtml

@page
@using Microsoft.Extensions.Localization
@using KnoroomsPayments.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@inject IStringLocalizer<KnoroomsPaymentsResource> L
@model KnoroomsPayments.Web.Pages.Products.CreateModalModel
@{
    Layout = null;
}
@section scripts {

    <abp-script src="/libs/vue/vue.min.js" />
    <abp-script src="/Pages/Products/createModal.js" />
}

@section styles {
    <abp-style src="/Pages/Products/CreateModal.css" />
}

<script>
    var app = new Vue({
        el: '#createProductApp',
        data: {
            currentStep: 1,
            activeTab: 'tab2',
            pricingModelsList:[
                {
                    "value": "",
                    "text": "--- select ---"
                },
                {
                    "value": "",
                    "text": "Flat rate"
                },
                {
                    "value": "",
                    "text": "Package pricing"
                },
                {
                    "value": "",
                    "text": "Customer chooses price"
                }
            ],
            currencyCodesList: [
                {
                    "value": "",
                    "text": "--- select ---"
                },
                {
                    "value": "dop",
                    "text": "DOP"
                },
                {
                    "value": "cad",
                    "text": "CAD"
                },
                {
                    "value": "usd",
                    "text": "USD"
                }
            ],
            billingPeriodList: [
                {
                    "value": "",
                    "text": "--- select ---"
                },
                {
                    "value": "day",
                    "text": "Daily"
                },
                {
                    "value": "week",
                    "text": "Weekly"
                },
                {
                    "value": "month",
                    "text": "Monthly"
                },
                {
                    "value": "year",
                    "text": "Yearly"
                }
            ],
            product: {
                name: '',
                description: '',
                unitAmount:'',
                currency:'',
                billingScheme: ''
            }
        },
        methods: {
            createProduct() {
                fetch('/products/CreateModal', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'RequestVerificationToken': document.getElementsByName("__RequestVerificationToken")[0].value
                    },
                    body: JSON.stringify(this.product)
                })
                    .then(response => {
                        if (response.ok) {
                            abp.notify.success('Data saved successfully');                            
                            $('#productModal').modal('hide');   
                        }
                        else {
                            abp.notify.error('Data not saved');
                        }
                    })
                    .catch(error => {
                        abp.notify.error('network error');
                    });
            },
            nextStep() {
                this.currentStep = 2;
            },
            previousStep() {
                this.currentStep = 1;
            }
        }
    });

</script>

<form data-ajaxForm="true" asp-page="/Products/CreateModal" autocomplete="off">
    <abp-modal id="productModal">
        <abp-modal-header title="@L["NewProduct"].Value"></abp-modal-header>

        <abp-modal-body id="createProductApp">
            <div v-if="currentStep === 1">
                <div>
                    <label class="form-label">Name(required)</label>
                    <input type="text" v-model="product.name" class="form-control" />
                </div>

                <div>
                    <label class="form-label">Description</label>
                    <input type="text" v-model="product.description" class="form-control" />
                </div>

                <div class="buttonDiv">
                    <input type="button" class="btn btn-primary" v-on:click="nextStep" value="Next">
                </div>
            </div>

            <div v-if="currentStep === 2">
                <div class="tabDiv">
                    <button class="button" type="button" :class="{ active: activeTab === 'tab1'}" v-on:click="activeTab = 'tab1'">
                        <span class="first-line">Recurring</span>
                        <br/>
                        <span class="second-line">Charge on ongoing fee</span>
                    </button>
                    <button class="button" type="button" :class="{ active: activeTab === 'tab2'}" v-on:click="activeTab = 'tab2'">
                        <span class="first-line">One-off</span>
                        <br />
                        <span class="second-line">Charge a one time fee</span>
                    </button>
                </div>
                <div>
                    <label class="form-label">Choose your pricing model:</label>
                    <div>
                        <select class="form-select form-control" v-model="product.billingScheme">
                            <option v-for="item in pricingModelsList" :value="item.value">{{item.text}}</option>
                        </select>
                    </div>
                </div>


                <div v-if="activeTab === 'tab1'">
                    <label class="form-label">Billing Scheme</label>
                    <input type="text" v-model="product.billingScheme" class="form-control" />
                </div>


                <div v-if="activeTab === 'tab2'">
                     <div>
                         <h4>Price</h4>
                     </div>
                     <div>
                        <label class="form-label">Amount (required)</label>
                        <div class="currencyDiv">
                            <input type="text" class="form-control currencyInput" v-model="product.unitAmount" />
                            <select class="form-select form-control currencySelect" v-model="product.currency">
                                <option v-for="item in currencyCodesList" :value="item.value">{{item.text}}</option>
                            </select>
                        </div>
                    </div>
                </div>

                <div class="modal-footer">
                    <input type="button" class="btn btn-secondary" v-on:click="previousStep" value="Back">
                    <input type="button" class="btn btn-primary" data-busy-text="Saving..." v-on:click="createProduct" value="Create Product">
                </div>
            </div>
        </abp-modal-body>
    </abp-modal>
</form>

CreateModal.cshtml.cs

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using KnoroomsPayments.Products;
using Stripe;
using System.Data;
using KnoroomsPayments.Migrations;
using System;
using KnoroomsPayments.Price;

namespace KnoroomsPayments.Web.Pages.Products
{
    public class CreateModalModel : KnoroomsPaymentsPageModel
    {
        [BindProperty]
        public Stripe.Price Price { get; set; } = new Stripe.Price();

        [HiddenInput]
        [BindProperty(SupportsGet = true)]
        public List<SelectListItem> ListPriceTypes { get; set; }

        [HiddenInput]
        [BindProperty(SupportsGet = true)]
        public List<SelectListItem> ListPricingModels { get; set; }

        [HiddenInput]
        [BindProperty(SupportsGet = true)]
        public List<SelectListItem> ListCurrencyCodes { get; set; }

        [HiddenInput]
        [BindProperty(SupportsGet = true)]
        public List<SelectListItem> ListRecurringInterval { get; set; }

        private readonly ProductsAppService _productsAppService;
        private readonly StripeProductAppService _stripeProductAppService;
        private readonly PriceAppService _stripePriceAppService;
        
        public SelectList ProductGroupSelectList;

        public CreateModalModel(
            ProductsAppService productsAppService,
            StripeProductAppService stripeProductAppService,
            PriceAppService stripePriceAppService)
        {
            _productsAppService = productsAppService;
            _stripeProductAppService = stripeProductAppService;
            _stripePriceAppService = stripePriceAppService;
        }

        public async Task OnGetAsync()
        {
            ListPriceTypes = new List<SelectListItem> {
                new SelectListItem {
                    Value = "",
                    Text = "--- select ---"
                },
                new SelectListItem {
                    Value = "recurring",
                    Text = "Recurring"
                },
                new SelectListItem {
                    Value = "one_time",
                    Text = "One-off"
                }
            }.ToList();

            ListPricingModels = new List<SelectListItem> {
                new SelectListItem {
                    Value = "",
                    Text = "--- select ---"
                },
                new SelectListItem {
                    Value = "per_unit",
                    Text = "Flat Rate"
                },
                new SelectListItem {
                    Value = "tiered",
                    Text = "Tiered"
                }
            }.ToList();

            ListCurrencyCodes = new List<SelectListItem> {
                new SelectListItem {
                    Value = "",
                    Text = "--- select ---"
                },
                new SelectListItem {
                    Value = "CAD",
                    Text = "Canadian dollar"
                },
                new SelectListItem {
                    Value = "USD",
                    Text = "United States dollar"
                }
            }.ToList();

            ListRecurringInterval = new List<SelectListItem> {
                new SelectListItem {
                    Value = "",
                    Text = "--- select ---"
                },
                new SelectListItem {
                    Value = "day",
                    Text = "Daily"
                },
                new SelectListItem {
                    Value = "month",
                    Text = "Monthly"
                },
                new SelectListItem {
                    Value = "week",
                    Text = "Weekly"
                },
                new SelectListItem {
                    Value = "year",
                    Text = "Yearly"
                }
            }.ToList();
        }

        public async Task<IActionResult> OnPostAsync([FromBody] StripeProduct uXProduct)
        {
            Product productToCreate = new Product();
            Stripe.Price priceToCreate = new Stripe.Price();

            productToCreate.Name = uXProduct.Name;
            productToCreate.Description = uXProduct.Description;

            productToCreate = await _productsAppService.CreateProductAsync(productToCreate);

            if (productToCreate != null)
            {
                priceToCreate.BillingScheme = "per_unit";
                priceToCreate.UnitAmount = uXProduct.UnitAmount;
                priceToCreate.UnitAmountDecimal = uXProduct.UnitAmount;
                priceToCreate.Currency = uXProduct.Currency;
                priceToCreate.Product = new Product();
                priceToCreate.Product.Id = productToCreate.Id;
                priceToCreate = await _stripePriceAppService.CreatePriceAsync(priceToCreate);
            }

            if (priceToCreate != null &&
                productToCreate != null)
            {
                CreateUpdateStripeProductDto stripeProduct = new CreateUpdateStripeProductDto();
                stripeProduct.Name = productToCreate.Name;
                stripeProduct.Description = productToCreate.Description;
                stripeProduct.StripeProductId = productToCreate.Id;
                stripeProduct.DefaultPriceId = priceToCreate.Id.ToString();
                stripeProduct.Object = "product";

                stripeProduct.StripePriceId = priceToCreate.Id;
                stripeProduct.BillingScheme = "per_unit";
                stripeProduct.UnitAmount = priceToCreate.UnitAmount;
                stripeProduct.UnitAmountDecimal = priceToCreate.UnitAmount;
                stripeProduct.Currency = priceToCreate.Currency;
                _stripeProductAppService.CreateAsync(stripeProduct);
            }

            return NoContent();
        }
    }
  }

CreateModal.css

.buttonDiv {
    padding: 5px;
    display: flex;
    flex-shrink: 0;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
}
.tabDiv {
    display: flex;
}
.button {
    margin: 5px;
    flex: 1;
    display: inline-block;
    font-weight: 400;
    text-align: left;
    border: 1px solid transparent;
    padding: .375rem .75rem;
    font-size: 12px;
    line-height: 1.5;
    border-radius: 8px;
    color: black;
    background: #fcfffe;
    border-color: #eeeeee;
}
.active {
    border-color: #3DB9F5;
    box-shadow: 0 -1px 5px 0 #3DB9F5, 0 2px 10px 0 #3DB9F5;
    border-width: 2px;
    background: #f5f6fd;
    color: #3DB9F5;
}
.first-line {
    font-weight: bold;
}
.second-line {
    color:black;
}
.currencyDiv {
    display: flex;
}
.currencySelect {
    flex: 25%;
}
.currencyInput {
    flex: 75%;
}```

this is the logic for each file: CreateModal.cshtml

@page
@using Microsoft.Extensions.Localization
@using KnoroomsPayments.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
@inject IStringLocalizer<KnoroomsPaymentsResource> L
@model KnoroomsPayments.Web.Pages.Products.CreateModalModel
@{
    Layout = null;
}
@section scripts {

    <abp-script src="/libs/vue/vue.min.js" />
    <abp-script src="/Pages/Products/createModal.js" />
}

@section styles {
    <abp-style src="/Pages/Products/CreateModal.css" />
}

<script>
    var app = new Vue({
        el: '#createProductApp',
        data: {
            currentStep: 1,
            activeTab: 'tab2',
            pricingModelsList:[
                {
                    "value": "",
                    "text": "--- select ---"
                },
                {
                    "value": "",
                    "text": "Flat rate"
                },
                {
                    "value": "",
                    "text": "Package pricing"
                },
                {
                    "value": "",
                    "text": "Customer chooses price"
                }
            ],
            currencyCodesList: [
                {
                    "value": "",
                    "text": "--- select ---"
                },
                {
                    "value": "dop",
                    "text": "DOP"
                },
                {
                    "value": "cad",
                    "text": "CAD"
                },
                {
                    "value": "usd",
                    "text": "USD"
                }
            ],
            billingPeriodList: [
                {
                    "value": "",
                    "text": "--- select ---"
                },
                {
                    "value": "day",
                    "text": "Daily"
                },
                {
                    "value": "week",
                    "text": "Weekly"
                },
                {
                    "value": "month",
                    "text": "Monthly"
                },
                {
                    "value": "year",
                    "text": "Yearly"
                }
            ],
            product: {
                name: '',
                description: '',
                unitAmount:'',
                currency:'',
                billingScheme: ''
            }
        },
        methods: {
            createProduct() {
                fetch('/products/CreateModal', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'RequestVerificationToken': document.getElementsByName("__RequestVerificationToken")[0].value
                    },
                    body: JSON.stringify(this.product)
                })
                    .then(response => {
                        if (response.ok) {
                            abp.notify.success('Data saved successfully');                            
                            $('#productModal').modal('hide');   
                        }
                        else {
                            abp.notify.error('Data not saved');
                        }
                    })
                    .catch(error => {
                        abp.notify.error('network error');
                    });
            },
            nextStep() {
                this.currentStep = 2;
            },
            previousStep() {
                this.currentStep = 1;
            }
        }
    });

</script>

<form data-ajaxForm="true" asp-page="/Products/CreateModal" autocomplete="off">
    <abp-modal id="productModal">
        <abp-modal-header title="@L["NewProduct"].Value"></abp-modal-header>

        <abp-modal-body id="createProductApp">
            <div v-if="currentStep === 1">
                <div>
                    <label class="form-label">Name(required)</label>
                    <input type="text" v-model="product.name" class="form-control" />
                </div>

                <div>
                    <label class="form-label">Description</label>
                    <input type="text" v-model="product.description" class="form-control" />
                </div>

                <div class="buttonDiv">
                    <input type="button" class="btn btn-primary" v-on:click="nextStep" value="Next">
                </div>
            </div>

            <div v-if="currentStep === 2">
                <div class="tabDiv">
                    <button class="button" type="button" :class="{ active: activeTab === 'tab1'}" v-on:click="activeTab = 'tab1'">
                        <span class="first-line">Recurring</span>
                        <br/>
                        <span class="second-line">Charge on ongoing fee</span>
                    </button>
                    <button class="button" type="button" :class="{ active: activeTab === 'tab2'}" v-on:click="activeTab = 'tab2'">
                        <span class="first-line">One-off</span>
                        <br />
                        <span class="second-line">Charge a one time fee</span>
                    </button>
                </div>
                <div>
                    <label class="form-label">Choose your pricing model:</label>
                    <div>
                        <select class="form-select form-control" v-model="product.billingScheme">
                            <option v-for="item in pricingModelsList" :value="item.value">{{item.text}}</option>
                        </select>
                    </div>
                </div>


                <div v-if="activeTab === 'tab1'">
                    <label class="form-label">Billing Scheme</label>
                    <input type="text" v-model="product.billingScheme" class="form-control" />
                </div>


                <div v-if="activeTab === 'tab2'">
                     <div>
                         <h4>Price</h4>
                     </div>
                     <div>
                        <label class="form-label">Amount (required)</label>
                        <div class="currencyDiv">
                            <input type="text" class="form-control currencyInput" v-model="product.unitAmount" />
                            <select class="form-select form-control currencySelect" v-model="product.currency">
                                <option v-for="item in currencyCodesList" :value="item.value">{{item.text}}</option>
                            </select>
                        </div>
                    </div>
                </div>

                <div class="modal-footer">
                    <input type="button" class="btn btn-secondary" v-on:click="previousStep" value="Back">
                    <input type="button" class="btn btn-primary" data-busy-text="Saving..." v-on:click="createProduct" value="Create Product">
                </div>
            </div>
        </abp-modal-body>
    </abp-modal>
</form>

CreateModal.cshtml.cs

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using KnoroomsPayments.Products;
using Stripe;
using System.Data;
using KnoroomsPayments.Migrations;
using System;
using KnoroomsPayments.Price;

namespace KnoroomsPayments.Web.Pages.Products
{
    public class CreateModalModel : KnoroomsPaymentsPageModel
    {
        [BindProperty]
        public Stripe.Price Price { get; set; } = new Stripe.Price();

        [HiddenInput]
        [BindProperty(SupportsGet = true)]
        public List<SelectListItem> ListPriceTypes { get; set; }

        [HiddenInput]
        [BindProperty(SupportsGet = true)]
        public List<SelectListItem> ListPricingModels { get; set; }

        [HiddenInput]
        [BindProperty(SupportsGet = true)]
        public List<SelectListItem> ListCurrencyCodes { get; set; }

        [HiddenInput]
        [BindProperty(SupportsGet = true)]
        public List<SelectListItem> ListRecurringInterval { get; set; }

        private readonly ProductsAppService _productsAppService;
        private readonly StripeProductAppService _stripeProductAppService;
        private readonly PriceAppService _stripePriceAppService;
        
        public SelectList ProductGroupSelectList;

        public CreateModalModel(
            ProductsAppService productsAppService,
            StripeProductAppService stripeProductAppService,
            PriceAppService stripePriceAppService)
        {
            _productsAppService = productsAppService;
            _stripeProductAppService = stripeProductAppService;
            _stripePriceAppService = stripePriceAppService;
        }

        public async Task OnGetAsync()
        {
            ListPriceTypes = new List<SelectListItem> {
                new SelectListItem {
                    Value = "",
                    Text = "--- select ---"
                },
                new SelectListItem {
                    Value = "recurring",
                    Text = "Recurring"
                },
                new SelectListItem {
                    Value = "one_time",
                    Text = "One-off"
                }
            }.ToList();

            ListPricingModels = new List<SelectListItem> {
                new SelectListItem {
                    Value = "",
                    Text = "--- select ---"
                },
                new SelectListItem {
                    Value = "per_unit",
                    Text = "Flat Rate"
                },
                new SelectListItem {
                    Value = "tiered",
                    Text = "Tiered"
                }
            }.ToList();

            ListCurrencyCodes = new List<SelectListItem> {
                new SelectListItem {
                    Value = "",
                    Text = "--- select ---"
                },
                new SelectListItem {
                    Value = "CAD",
                    Text = "Canadian dollar"
                },
                new SelectListItem {
                    Value = "USD",
                    Text = "United States dollar"
                }
            }.ToList();

            ListRecurringInterval = new List<SelectListItem> {
                new SelectListItem {
                    Value = "",
                    Text = "--- select ---"
                },
                new SelectListItem {
                    Value = "day",
                    Text = "Daily"
                },
                new SelectListItem {
                    Value = "month",
                    Text = "Monthly"
                },
                new SelectListItem {
                    Value = "week",
                    Text = "Weekly"
                },
                new SelectListItem {
                    Value = "year",
                    Text = "Yearly"
                }
            }.ToList();
        }

        public async Task<IActionResult> OnPostAsync([FromBody] StripeProduct uXProduct)
        {
            Product productToCreate = new Product();
            Stripe.Price priceToCreate = new Stripe.Price();

            productToCreate.Name = uXProduct.Name;
            productToCreate.Description = uXProduct.Description;

            productToCreate = await _productsAppService.CreateProductAsync(productToCreate);

            if (productToCreate != null)
            {
                priceToCreate.BillingScheme = "per_unit";
                priceToCreate.UnitAmount = uXProduct.UnitAmount;
                priceToCreate.UnitAmountDecimal = uXProduct.UnitAmount;
                priceToCreate.Currency = uXProduct.Currency;
                priceToCreate.Product = new Product();
                priceToCreate.Product.Id = productToCreate.Id;
                priceToCreate = await _stripePriceAppService.CreatePriceAsync(priceToCreate);
            }

            if (priceToCreate != null &&
                productToCreate != null)
            {
                CreateUpdateStripeProductDto stripeProduct = new CreateUpdateStripeProductDto();
                stripeProduct.Name = productToCreate.Name;
                stripeProduct.Description = productToCreate.Description;
                stripeProduct.StripeProductId = productToCreate.Id;
                stripeProduct.DefaultPriceId = priceToCreate.Id.ToString();
                stripeProduct.Object = "product";

                stripeProduct.StripePriceId = priceToCreate.Id;
                stripeProduct.BillingScheme = "per_unit";
                stripeProduct.UnitAmount = priceToCreate.UnitAmount;
                stripeProduct.UnitAmountDecimal = priceToCreate.UnitAmount;
                stripeProduct.Currency = priceToCreate.Currency;
                _stripeProductAppService.CreateAsync(stripeProduct);
            }

            return NoContent();
        }
    }
  }

CreateModal.css

.buttonDiv {
    padding: 5px;
    display: flex;
    flex-shrink: 0;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
}
.tabDiv {
    display: flex;
}
.button {
    margin: 5px;
    flex: 1;
    display: inline-block;
    font-weight: 400;
    text-align: left;
    border: 1px solid transparent;
    padding: .375rem .75rem;
    font-size: 12px;
    line-height: 1.5;
    border-radius: 8px;
    color: black;
    background: #fcfffe;
    border-color: #eeeeee;
}
.active {
    border-color: #3DB9F5;
    box-shadow: 0 -1px 5px 0 #3DB9F5, 0 2px 10px 0 #3DB9F5;
    border-width: 2px;
    background: #f5f6fd;
    color: #3DB9F5;
}
.first-line {
    font-weight: bold;
}
.second-line {
    color:black;
}
.currencyDiv {
    display: flex;
}
.currencySelect {
    flex: 25%;
}
.currencyInput {
    flex: 75%;
}

Thanks very much, the issue has been identified and closed. Much appreciated.

Showing 1 to 8 of 8 entries
Made with ❤️ on ABP v9.0.0-preview Updated on September 20, 2024, 05:21