This commit is contained in:
MOHD ARIFF 2024-11-21 16:32:12 +08:00
parent 3f3ad980b9
commit 54b2affe28
14 changed files with 18562 additions and 108 deletions

View File

@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
using PSTW_CentralSystem.DBContext; using PSTW_CentralSystem.DBContext;
using PSTW_CentralSystem.Models; using PSTW_CentralSystem.Models;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection;
namespace PSTW_CentralSystem.Controllers.API namespace PSTW_CentralSystem.Controllers.API
{ {
@ -21,11 +22,32 @@ namespace PSTW_CentralSystem.Controllers.API
_authDbContext = authDbContext; _authDbContext = authDbContext;
} }
[HttpPost("GetModuleInformation")] [HttpPost("GetClassAndMethodInformation")]
public async Task<IActionResult> GetModuleInformation() public async Task<IActionResult> GetClassAndMethodInformation(string moduleName)
{ {
var qcList = await _authDbContext.ModuleSettings.ToListAsync(); var controllerAndMethodList = new object();
return Json(qcList);
// Get the assembly containing the controllers
var assembly = Assembly.GetExecutingAssembly();
// Get all types in the assembly (controllers will typically be in the "Controllers" namespace)
//var controllerTypes = await Task.Run(() => assembly.GetTypes().Where(type => typeof(ControllerBase).IsAssignableFrom(type) && type.IsClass && type.Name.Contains("Controller") && type.Name != "AdminController") .ToList());
var controllerTypes = await Task.Run(() => assembly.GetTypes().Where(type => typeof(ControllerBase).IsAssignableFrom(type) && type.IsClass && type.Name.Contains(moduleName)).FirstOrDefault());
// Iterate over the controller types and get their methods
var methods = controllerTypes?.GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(m => m.DeclaringType == controllerTypes) // Filter methods declared directly in the controller (ignoring inherited ones)
.Select(m => m.Name) // Get the method names
.ToList();
controllerAndMethodList = (new
{
Controller = controllerTypes?.Name,
Methods = methods
});
// Return the list as JSON
return Json(controllerAndMethodList);
} }
} }

View File

@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PSTW_CentralSystem.DBContext;
namespace PSTW_CentralSystem.Controllers.API
{
[ApiController]
[Route("[controller]")]
public class ModuleAPI : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly AuthDBContext _authDbContext;
public ModuleAPI(ILogger<HomeController> logger, AuthDBContext authDbContext)
{
_logger = logger;
_authDbContext = authDbContext;
}
[HttpPost("GetModuleInformation")]
public async Task<IActionResult> GetModuleInformation()
{
var qcList = await _authDbContext.ModuleSettings.ToListAsync();
return Json(qcList);
}
[HttpPost("GetXModuleInformation")]
public async Task<IActionResult> GetXModuleInformation(int? id)
{
var qcList = await _authDbContext.ModuleSettings.Where(x => x.SettingId == id).FirstOrDefaultAsync();
return Json(qcList);
}
}
}

View File

@ -0,0 +1,28 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PSTW_CentralSystem.DBContext;
namespace PSTW_CentralSystem.Controllers.API
{
[ApiController]
[Route("[controller]")]
public class RoleAPI : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly AuthDBContext _authDbContext;
public RoleAPI(ILogger<HomeController> logger, AuthDBContext authDbContext)
{
_logger = logger;
_authDbContext = authDbContext;
}
[HttpPost("GetRoleList")]
public async Task<IActionResult> GetRoleList()
{
var roleList = await _authDbContext.Roles.Where(r => r.Id != 1 && r.Id != 2).ToListAsync();
return Json(roleList);
}
}
}

View File

@ -42,6 +42,10 @@ namespace PSTW_CentralSystem.Controllers
return View(moduleSettings); return View(moduleSettings);
} }
public IActionResult ModuleCreate()
{
return View();
}
} }
} }

View File

@ -0,0 +1,83 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace PSTW_CentralSystem.Controllers.Inventory
{
public class InventoryController : Controller
{
// GET: Inventory
public ActionResult Index()
{
return View();
}
// GET: Inventory/Details/5
public ActionResult Details(int id)
{
return View();
}
// GET: Inventory/Create
public ActionResult Create()
{
return View();
}
// POST: Inventory/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(IFormCollection collection)
{
try
{
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
// GET: Inventory/Edit/5
public ActionResult Edit(int id)
{
return View();
}
// POST: Inventory/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, IFormCollection collection)
{
try
{
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
// GET: Inventory/Delete/5
public ActionResult Delete(int id)
{
return View();
}
// POST: Inventory/Delete/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id, IFormCollection collection)
{
try
{
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
}
}

View File

@ -37,6 +37,7 @@ namespace PSTW_CentralSystem.CustomPolicy
if (checkIfSuperAdmin()) if (checkIfSuperAdmin())
{ {
context.Succeed(requirement); context.Succeed(requirement);
return;
} }
else { else {
checkModuleExistOrNot(); checkModuleExistOrNot();
@ -66,6 +67,7 @@ namespace PSTW_CentralSystem.CustomPolicy
if (registeredModule == null) if (registeredModule == null)
{ {
context.Fail(); context.Fail();
return;
} }
else else
{ {
@ -78,6 +80,7 @@ namespace PSTW_CentralSystem.CustomPolicy
if (registeredModule.ModuleStatus == 0) if (registeredModule.ModuleStatus == 0)
{ {
context.Fail(); context.Fail();
return;
} }
} }
@ -87,6 +90,7 @@ namespace PSTW_CentralSystem.CustomPolicy
if (allowedUserTypes == "Public" || userRole.Any(role => allowedUserTypes.Contains(role))) if (allowedUserTypes == "Public" || userRole.Any(role => allowedUserTypes.Contains(role)))
{ {
context.Succeed(requirement); context.Succeed(requirement);
return;
} }
else if (currentUser != null && allowedUserTypes == "Registered User" ) else if (currentUser != null && allowedUserTypes == "Registered User" )
{ {
@ -95,6 +99,7 @@ namespace PSTW_CentralSystem.CustomPolicy
else else
{ {
context.Fail(); context.Fail();
return;
} }
} }
@ -116,15 +121,18 @@ namespace PSTW_CentralSystem.CustomPolicy
if (userRole.Any(role => allowedUserTypes.Contains(role)) || allowedUserTypes.Contains("All")) // Check if the user role is allowed, allowing only registered user to access. if (userRole.Any(role => allowedUserTypes.Contains(role)) || allowedUserTypes.Contains("All")) // Check if the user role is allowed, allowing only registered user to access.
{ {
context.Succeed(requirement); context.Succeed(requirement);
return;
} }
else else
{ {
context.Fail(); context.Fail();
return;
} }
} }
else // No method is registered to allow all method to be accessed else // No method is registered to allow all method to be accessed
{ {
context.Succeed(requirement); context.Succeed(requirement);
return;
} }
} }
} }

View File

@ -27,6 +27,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Controllers\JSA\API\" />
<Folder Include="Controllers\Inventory\API\" />
<Folder Include="Logs\" /> <Folder Include="Logs\" />
<Folder Include="Migrations\" /> <Folder Include="Migrations\" />
</ItemGroup> </ItemGroup>

View File

@ -123,7 +123,7 @@
}, },
methods: { methods: {
fetchModule() { fetchModule() {
fetch('/AdminAPI/GetModuleInformation', { fetch('/ModuleAPI/GetModuleInformation', {
method: 'POST' method: 'POST'
}) })
.then(response => response.json()) .then(response => response.json())
@ -151,7 +151,7 @@
$('#confirm-dialog').modal('show'); // Show the modal $('#confirm-dialog').modal('show'); // Show the modal
}, },
confirmDelete(module) { confirmDelete(module) {
fetch('/AdminAPI/DeleteModule/' + module.settingId, { fetch('/ModuleAPI/DeleteModule/' + module.settingId, {
method: 'POST' method: 'POST'
}) })
.then(response => { .then(response => {
@ -172,6 +172,9 @@
} }
} }
}) })
app.mount('#app');
$(function () {
app.mount('#app');
});
</script> </script>
} }

View File

@ -7,75 +7,91 @@
Layout = "~/Views/Shared/_Layout.cshtml"; Layout = "~/Views/Shared/_Layout.cshtml";
} }
<p>
<a asp-action="CreateModule">Create New</a>
</p>
<div class="row" id="app"> <div class="row" id="app">
<div class="col-md-12 col-lg-12"> <div class="col-md-12 col-lg-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h4 class="card-title">{{module.moduleName}}</h4>
<div class="col-md-12 col-lg-12"> <div class="col-md-12 col-lg-12">
<div v-if="moduleData"> <div v-if="moduleData">
<table class="table table-bordered border-primary"> <form v-on:submit.prevent="">
<thead> <div class="card">
<tr> <div class="card-body">
<th> <h5 class="card-title">Settings</h5>
ModuleName <div class="form-group row">
</th> <label class="col-md-3 mt-3">Module Name</label>
<th> <div class="col-md-6">
Access Type <input type="text" class="form-control" name="moduleName" :value="moduleData.moduleName" readonly />
</th> </div>
<th> </div>
Configured Page <div class="form-group row">
</th> <label class="col-md-3 mt-3">Module Access</label>
<th> <div class="col-md-6">
Description <select class="form-select shadow-none mt-3" name="allowedUserType" v-model="moduleData.allowedUserType" style="height: 36px; width: 100%">
</th> <optgroup label="General">
<th> <option value="Public">Public</option>
ModuleStatus <option value="Registered User">Registered User</option>
</th> </optgroup>
<th> <optgroup label="Role">
Action <option v-for="(roleType, index) in roleData" :key="index" :value="roleType.name">{{ roleType.name }}</option>
</th> </optgroup>
</tr> </select>
</thead> </div>
<tbody> </div>
<tr v-for="module in moduleData"> <div v-show="moduleData && moduleData.allowedUserType == 'Registered User'">
<td class="align-middle"> <div class="form-group row">
{{module.moduleName}} <label class="col-md-3 mt-3">Available Method</label>
</td> <div class="col-md-3">
<td class="align-middle"> <select class="form-select shadow-none mt-3" name="allowedUserType" v-model="selectedModule" style="height: 36px; width: 100%">
{{module.allowedUserType}} <option v-for="(methods, index) in availableMethod" :key="index" :value="methods">{{ methods }}</option>
</td> </select>
<td class="align-middle"> </div>
<ul> <button class="btn col-md-3 f-icon mt-3 d-flex align-items-center" style="height: 36px; width: auto">
<li v-for="(method, index) in module.methodAllowedUserType" :key="index"> <i class=" fas fa-plus-square fa-lg"></i>&nbsp;Add method
<strong>Method Name:</strong> {{ method.methodName }}<br> </button>
<strong>Allowed User Types:</strong> </div>
<span v-for="(userType, idx) in method.allowedUserTypesArray" :key="idx"> <div class="form-group row">
{{ userType }}<span v-if="idx < method.allowedUserTypesArray.length - 1">, </span> <label class="col-md-3 mt-3">Add Method Rules</label>
</span> <div class="col-md-9">
</li> <ul class="nav nav-tabs" role="tablist">
</ul> <li class="nav-item" role="presentation" v-for="(setMethod, index) in moduleData.methodAllowedUserType" :key="index">
</td> <a :class="['nav-link', activeTab === index ? 'active' : '']"
<td class="align-middle"> :id="'simple-tab-' + index"
{{module.description}} data-bs-toggle="tab"
</td> :href="'#simple-tabpanel-' + index"
<td class="align-middle"> role="tab"
<span> :aria-controls="'simple-tabpanel-' + index"
<i :class="{'far fa-lg fa-times-circle': module.moduleStatus === 0, 'far fa-lg fa-check-circle': module.moduleStatus === 1}" :aria-selected="activeTab === index ? 'true' : 'false'">
:style="{color: (module.moduleStatus === 0 ? 'red' : 'limegreen')}"> {{ setMethod.methodName }}
</i> </a>
</span> </li>
</td> </ul>
<td class="align-middle"> <div class="tab-content pt-5" id="tab-content">
<button class="btn btn-primary" v-on:click="editModule(module)">Edit</button> | <div :class="['tab-pane', activeTab === index ? 'active' : '']" :id="'simple-tabpanel-' + index" role="tabpanel" :aria-labelledby="'simple-tab-' + index" v-for="(setMethod, index) in moduleData.methodAllowedUserType" :key="index">
<button class="btn btn-danger delete-button" v-on:click="deleteModule(module)">Delete</button> <p>Tab {{ setMethod.methodName }} selected</p>
</td> <div class="form-group row">
</tr> <label class="col-md-1">Role:</label>
</tbody> <div class="col-md-6">
</table> <select class="select2 form-select shadow-none mt-3" multiple="multiple" style="height: 36px; width: 100%" v-model="moduleData.methodAllowedUserType[index].allowedUserTypesArray
">
<option v-for="(roleType, index) in roleData" :key="index" :value="roleType.name">{{ roleType.name }}</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="border-top">
<div class="card-body">
<button type="button" class="btn btn-primary">
Save
</button>
</div>
</div>
</div>
</form>
</div> </div>
<div v-else><p>... Loading</p></div> <div v-else><p>... Loading</p></div>
</div> </div>
@ -100,7 +116,7 @@
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<input type="hidden" id="delete-id"> <input type="hidden" id="delete-id">
<a id="confirmButton" href="#" class="btn btn-danger" @@click="confirmDelete(selectedModule)">Confirm</a> <a id="confirmButton" href="#" class="btn btn-danger" v-on:click="confirmDelete(selectedModule)">Confirm</a>
</div> </div>
</div> </div>
<div v-else><p>Loading...</p></div> <div v-else><p>Loading...</p></div>
@ -111,48 +127,93 @@
@{ @{
await Html.RenderPartialAsync("_ValidationScriptsPartial"); await Html.RenderPartialAsync("_ValidationScriptsPartial");
} }
<script>
</script>
<script> <script>
const app = Vue.createApp({ const app = Vue.createApp({
data() { data() {
return { return {
moduleData: null, moduleData: null,
roleData: null,
controllerMethodData: null,
activeTab: null,
availableMethod: [],
selectedModule: null selectedModule: null
}; };
}, },
mounted() { mounted() {
this.fetchModule(); this.fetchXModule();
this.fetchControllerMethodList();
},
watch: {
// Watching allowedUserType directly
// 'moduleData.allowedUserType'(newVal, oldVal) {
// console.log(`allowedUserType changed from ${oldVal} to ${newVal}`);
// }
'moduleData.allowedUserType'(newVal, oldVal) {
// console.log(`allowedUserType changed from ${oldVal} to ${newVal}`);
this.filterAvailableMethods();
}
}, },
methods: { methods: {
fetchModule() { fetchXModule() {
fetch('/AdminAPI/GetModuleInformation', { var id = @Model.SettingId
fetch('/ModuleAPI/GetXModuleInformation?id=' + id, {
method: 'POST' method: 'POST'
}) })
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
console.log(data); console.log(data);
if (data.length > 0) { if (data != null) {
this.moduleData = data.length ? data : []; this.moduleData = data;
this.fetchRoleList();
} }
}) })
.catch(error => { .catch(error => {
console.error('There was a problem with the fetch operation:', error); console.error('There was a problem with the fetch operation:', error);
}); });
}, },
editModule(module) { fetchRoleList() {
// Check if the user ID exists fetch('/RoleAPI/GetRoleList', {
if (module.settingId) { method: 'POST'
// Redirect the user to the edit user page })
window.location.href = 'EditModule/' + module.settingId; .then(response => response.json())
} else { .then(data => {
console.error('Module ID not found'); console.log(data);
} if (data != null) {
this.roleData = data;
this.$nextTick(() => {
$(".select2").select2(); // Initialize Select2 after DOM update
});
}
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
},
fetchControllerMethodList() {
var moduleName = '@Model.ModuleName'
fetch('/AdminAPI/GetClassAndMethodInformation?moduleName=' + moduleName, {
method: 'POST'
})
.then(response => response.json())
.then(data => {
console.log(data);
if (data != null) {
this.controllerMethodData = data;
}
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
}, },
deleteModule(module) { deleteModule(module) {
this.selectedModule = module; // Set selected user this.selectedModule = module; // Set selected user
$('#confirm-dialog').modal('show'); // Show the modal $('#confirm-dialog').modal('show'); // Show the modal
}, },
confirmDelete(module) { confirmDelete(module) {
fetch('/AdminAPI/DeleteModule/' + module.settingId, { fetch('/ModuleAPI/DeleteModule/' + module.settingId, {
method: 'POST' method: 'POST'
}) })
.then(response => { .then(response => {
@ -170,9 +231,15 @@
.catch(error => { .catch(error => {
console.error('Failed to delete module with status:', error); console.error('Failed to delete module with status:', error);
}); });
} },
filterAvailableMethods() {
const moduleMethods = this.moduleData.methodAllowedUserType.map(method => method.methodName);
this.availableMethod = this.controllerMethodData.methods.filter(method => !moduleMethods.includes(method)); // exclude methods that are already in moduleMethods
},
} }
}) })
app.mount('#app'); $(function () {
app.mount('#app');
});
</script> </script>
} }

View File

@ -0,0 +1,10 @@
@{
ViewData["Title"] = "PSTW Centralized System";
}
<div class="row">
<div class="text-center">
<h1 class="display-4">Welcome To Invetory Module</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
</div>

View File

@ -0,0 +1,83 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace PSTW_CentralSystem.Views.JSA
{
public class JSAController : Controller
{
// GET: JSAController
public ActionResult Index()
{
return View();
}
// GET: JSAController/Details/5
public ActionResult Details(int id)
{
return View();
}
// GET: JSAController/Create
public ActionResult Create()
{
return View();
}
// POST: JSAController/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(IFormCollection collection)
{
try
{
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
// GET: JSAController/Edit/5
public ActionResult Edit(int id)
{
return View();
}
// POST: JSAController/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, IFormCollection collection)
{
try
{
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
// GET: JSAController/Delete/5
public ActionResult Delete(int id)
{
return View();
}
// POST: JSAController/Delete/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id, IFormCollection collection)
{
try
{
return RedirectToAction(nameof(Index));
}
catch
{
return View();
}
}
}
}

View File

@ -24,14 +24,14 @@
sizes="16x16" sizes="16x16"
href="/assets/images/favicon.png" /> href="/assets/images/favicon.png" />
<!-- Custom CSS --> <!-- Custom CSS -->
<link href="/assets/libs/fullcalendar/dist/fullcalendar.min.css" <link rel="stylesheet" href="~/assets/libs/select2/dist/css/select2.min.css" />
rel="stylesheet" /> <link rel="stylesheet" href="~/assets/libs/jquery-minicolors/jquery.minicolors.css" />
<link href="/assets/extra-libs/calendar/calendar.css" rel="stylesheet" /> <link rel="stylesheet" href="~/assets/libs/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css" />
<link href="/dist/css/style.min.css" rel="stylesheet" /> <link rel="stylesheet" href="~/assets/libs/quill/dist/quill.snow.css" />
<link href="~/dist/css/style.min.css" rel="stylesheet" />
<!-- Vue Js CSS --> <!-- Vue Js CSS -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <script src="~/js/vue.global.js"></script>
@* <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script> *@ @* <script src="~/js/vue.global.prod.js"></script> *@
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
@ -650,24 +650,30 @@
<!-- ============================================================== --> <!-- ============================================================== -->
<!-- All Jquery --> <!-- All Jquery -->
<!-- ============================================================== --> <!-- ============================================================== -->
<script src="/assets/libs/jquery/dist/jquery.min.js"></script> <script src="~/assets/libs/jquery/dist/jquery.min.js"></script>
<script src="/dist/js/jquery.ui.touch-punch-improved.js"></script> <script src="~/dist/js/jquery.ui.touch-punch-improved.js"></script>
<script src="/dist/js/jquery-ui.min.js"></script> <script src="~/dist/js/jquery-ui.min.js"></script>
<!-- Bootstrap tether Core JavaScript --> <!-- Bootstrap tether Core JavaScript -->
<script src="/assets/libs/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/assets/libs/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<!-- slimscrollbar scrollbar JavaScript --> <!-- slimscrollbar scrollbar JavaScript -->
<script src="/assets/libs/perfect-scrollbar/dist/perfect-scrollbar.jquery.min.js"></script> <script src="~/assets/libs/perfect-scrollbar/dist/perfect-scrollbar.jquery.min.js"></script>
<script src="/assets/extra-libs/sparkline/sparkline.js"></script> <script src="~/assets/extra-libs/sparkline/sparkline.js"></script>
<!--Wave Effects --> <!--Wave Effects -->
<script src="/dist/js/waves.js"></script> <script src="~/dist/js/waves.js"></script>
<!--Menu sidebar --> <!--Menu sidebar -->
<script src="/dist/js/sidebarmenu.js"></script> <script src="~/dist/js/sidebarmenu.js"></script>
<!--Custom JavaScript --> <!--Custom JavaScript -->
<script src="/dist/js/custom.min.js"></script> <script src="~/dist/js/custom.min.js"></script>
<!-- this page js --> <!--Form JS-->
<script src="/assets/libs/moment/min/moment.min.js"></script> <script src="~/assets/libs/inputmask/dist/min/jquery.inputmask.bundle.min.js"></script>
<script src="/assets/libs/fullcalendar/dist/fullcalendar.min.js"></script> <script src="~/dist/js/pages/mask/mask.init.js"></script>
<script src="/dist/js/pages/calendar/cal-init.js"></script> <script src="~/assets/libs/select2/dist/js/select2.full.min.js"></script>
<script src="~/assets/libs/jquery-asColor/dist/jquery-asColor.min.js"></script>
<script src="~/assets/libs/jquery-asGradient/dist/jquery-asGradient.js"></script>
<script src="~/assets/libs/jquery-asColorPicker/dist/jquery-asColorPicker.min.js"></script>
<script src="~/assets/libs/jquery-minicolors/jquery.minicolors.min.js"></script>
<script src="~/assets/libs/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
<script src="~/assets/libs/quill/dist/quill.min.js"></script>
@await RenderSectionAsync("Scripts", required: false) @await RenderSectionAsync("Scripts", required: false)
</body> </body>

18096
wwwroot/js/vue.global.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long