This commit is contained in:
MOHD ARIFF 2026-03-06 14:39:09 +08:00
parent 815769fab7
commit 136b9cadb1
7 changed files with 389 additions and 84 deletions

View File

@ -2,7 +2,7 @@
ViewData["Title"] = "Dashboard";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container" id="invAdmin">
<div class="container" id="invAdmin">
<div class="row">
<div class="text-center">
<p><h1 class="display-4">Reporting Dashboard</h1></p>
@ -64,70 +64,69 @@
</div>
<div class="row card">
<div class="card-header">
<h3 class="card-title">User Report</h3>
<h3 class="card-title">Report Inquiry</h3>
</div>
<div class="card-body">
<div v-if="reportData">
<div class="row justify-content-center">
<div class="col-3">
<div class="row col-10">
<h4>Department</h4>
<multiselect v-model="selectedSingleDepartment" :options="compDeptList" :multiple="false" group-values="departments" group-label="companyName"
:group-select="false" placeholder="Search Department" track-by="departmentId" label="departmentName">
</multiselect>
<div class=""><button class="btn btn-danger" v-on:click="selectedSingleDepartment = []">Clear</button></div>
</div>
</div>
<div class="card-body">
<div v-if="reportData">
<div class="row justify-content-center">
<div class="col-3">
<div class="row col-10">
<h4>Department</h4>
<multiselect v-model="selectedSingleDepartment" :options="compDeptList" :multiple="false" group-values="departments" group-label="companyName"
:group-select="false" placeholder="Search Department" track-by="departmentId" label="departmentName">
</multiselect>
<div class=""><button class="btn btn-danger" v-on:click="selectedSingleDepartment = []">Clear</button></div>
</div>
<div class="col-3">
<div class="row col-10">
<h4>Date filter</h4>
<vue-date-picker v-model="selectedMonth" month-picker auto-apply></vue-date-picker>
<div class=""><button class="btn btn-danger" v-on:click="selectedMonth = null">Clear</button></div>
</div>
</div>
<div class="col-3">
<div class="row col-10">
<h4>Date filter</h4>
<vue-date-picker v-model="selectedMonth" month-picker auto-apply></vue-date-picker>
<div class=""><button class="btn btn-danger" v-on:click="selectedMonth = null">Clear</button></div>
</div>
<div class="col-3">
<div class="row col-10">
<h4>Position Filter</h4>
<multiselect v-model="selectedPosition" :options="positionList" :multiple="false" placeholder="Search Position" track-by="positionId" label="positionName"></multiselect>
<div class=""><button class="btn btn-danger" v-on:click="selectedPosition = []">Clear</button></div>
</div>
</div>
<div class="col-12">
<button class="btn btn-primary" v-on:click="generateReport">Generate Report</button>
</div>
<div class="col-3">
<div class="row col-10">
<h4>Position Filter</h4>
<multiselect v-model="selectedPosition" :options="positionList" :multiple="false" placeholder="Search Position" track-by="positionId" label="positionName"></multiselect>
<div class=""><button class="btn btn-danger" v-on:click="selectedPosition = []">Clear</button></div>
</div>
</div>
<div class="col-12">
<button class="btn btn-primary" v-on:click="generateReport">Generate Report</button>
</div>
</div>
</div>
<hr />
<div class="card-body">
<div v-if="reportData">
<div class="row">
<div v-if="formResponse">
<div class="col-3">
<h4>User List</h4>
<multiselect v-model="selectedUser" :options="formResponse.userItemBalance" :multiple="false" placeholder="Select User" track-by="userId" label="userFullName"></multiselect>
<div class=""><button class="btn btn-danger" v-on:click="console.log(selectedUser);selectedUser = {}; console.log(selectedUser)">Clear</button></div>
</div>
<div class="col-9" v-if="selectedUser">
<table id="userItemsTable" v-if="selectedUser.userFullName" class="display">
<thead>
<tr>
<th>Item Name</th>
<th>Item Price</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in selectedUser.items" :key="index">
<td>{{item.itemName}}</td>
<td>{{item.itemPrice}}</td>
</tr>
<tr>
<td>Total</td>
<td>{{selectedUser.totalItemPrice}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<hr />
<ul class="nav nav-tabs nav-tabs-outline" id="reportTabs" role="tablist">
<li class="nav-item">
<button :class="['nav-link', {active: activeTab === 'userTab'}]" v-on:click="activeTab = 'userTab'">User</button>
</li>
<li class="nav-item">
<button :class="['nav-link', {active: activeTab === 'storeTab'}]" v-on:click="activeTab = 'storeTab'">Store</button>
</li>
</ul>
<hr />
<div class="card-body">
<div v-if="reportData">
<div class="row">
<div v-if="formResponse" v-show="activeTab === 'userTab'">
<div class="col-3">
<h4>User List</h4>
<multiselect v-model="selectedUser" :options="formResponse.userItemBalance" :multiple="false" placeholder="Select User" track-by="userId" label="userFullName"></multiselect>
</div>
<div class="col-9">
<table id="userItemsTable" class="display table table-bordered"></table>
</div>
</div>
<div v-if="formResponse" v-show="activeTab === 'storeTab'">
<div class="col-3">
<h4>Store</h4>
</div>
<div class="col-9">
<table id="itemsTable" class="display table table-bordered"></table>
</div>
</div>
</div>
@ -171,15 +170,17 @@
filteredProduct: [],
selectedMonth: null,
selectedDepartment: [],
selectedSingleDepartment: null,
selectedSingleDepartment: [],
selectedItem: [],
selectedCategory: [],
selectedPosition: [],
usersInfo: [],
submitBody: null,
formResponse: null,
selectedUser: {},
userItemsTable:null,
selectedUser: [],
userItemsTable: null,
itemsTable: null,
activeTab: "userTab"
}
},
mounted() {
@ -188,32 +189,54 @@
this.fetchDepartmentsCompaniesList();
},
watch: {
//watch selectedDepartment. when selectedDepartment is changed, if selectedCategory is null filter productList based on selectedDepartment only. otherwise filter the productList based on selectedDepartment and selectedCategory
selectedDepartment() {
this.filterProducts();
},
selectedCategory() {
this.filterProducts();
},
},
computed: {
userItemsTableCompt() {
if (!this.selectedUser || !this.$refs.userItemsTable) {
return null;
}
return $(this.$refs.userItemsTable).DataTable();
}
selectedUser(newVal) {
if (this.userItemsTable) {
this.userItemsTable.clear().destroy();
this.userItemsTable = null;
}
// if (newVal && newVal.items) {
const tableData = newVal?.items ? newVal.items : [];
this.$nextTick(() => {
this.userItemsTable = $('#userItemsTable').DataTable({
data: tableData ,
columns: [
{ data: 'uniqueID', title: 'Unique ID' },
{ data: 'itemName', title: 'Item Name' },
{ data: 'itemPrice', title: 'Item Price' },
],
destroy: true,
drawCallback: function () {
if(!newVal) {return};
const total = newVal.totalItemPrice;
$(this.api().table().node()).find('tbody tr.total-row').remove();
$(this.api().table().node()).find('tbody').append(
`<tr class="total-row">
<td colspan="2"><strong>Total</strong></td>
<td class="text-end"><strong>${total}</strong></td>
</tr>`
);
},
});
});
}
},
methods: {
async generateReport(){
if(this.selectedMonth == null || this.selectedSingleDepartment.length == 0 || this.selectedPosition.length == 0)
if(this.selectedMonth == null || this.selectedSingleDepartment.length == 0 || this.selectedPosition.length == 0)
{
var msg = [];
if(this.selectedMonth == null)
{
msg.push("Date");
}
if(this.selectedSingleDepartment.length == 0)
if(this.selectedSingleDepartment.length == 0)
{
msg.push("Department");
}
@ -223,7 +246,7 @@
}
alert(msg.length > 1 ? msg.join(" & ") + " cannot be empty" : msg[0] + " cannot be empty");
}
else{
else{
this.submitBody = {
formDate: new Date(this.selectedMonth.year, this.selectedMonth.month + 1, 0, 23, 59, 59).toISOString().slice(0, 19),
// selectedCategory: this.selectedCategory,
@ -247,7 +270,17 @@
if (response.ok) {
const data = await response.json();
this.formResponse = data
console.log(this.formResponse);
this.initTable();
if (this.userItemsTable) {
this.userItemsTable.clear().destroy();
this.userItemsTable = null;
this.selectedUser = null;
}
if (this.itemsTable) {
this.itemsTable.clear().destroy();
this.itemsTable = null;
}
console.log(data);
}
else {
console.error(`Failed to fetch user: ${response.statusText}`);
@ -363,12 +396,19 @@
);
}
},
initUserItemsTable() {
initTable() {
this.userItemsTable = $('#userItemsTable').DataTable();
this.$nextTick(() => {
if (this.$refs.userItemsTable) {
$(this.$refs.userItemsTable).DataTable().clear().destroy();
}
this.userItemsTable = $('#userItemsTable').DataTable();
this.itemsTable = $('#itemsTable').DataTable({
data: this.formResponse.allProductInStore ,
columns: [
{ data: 'productName', title: 'Item Name' },
{ data: 'quantity', title: 'Quantity' },
{ data: 'totalPrice', title: 'Total Item Price' },
],
destroy: true,
});
});
},
// selectedUserFunc() {

View File

@ -31,6 +31,7 @@ namespace PSTW_CentralSystem.Controllers.API
{
public string? ProductName { get; set; } = default!;
public int Quantity { get; set; }
public float TotalPrice { get; set; }
}
public class ReportQuery
@ -146,13 +147,14 @@ namespace PSTW_CentralSystem.Controllers.API
int ToStore = reportQuery.ToStore;
var currentProductBalance = new List<ProductReport>();
var result = await _centralDbContext.Products
.Select(p => new { p.ProductName, p.QuantityJSON })
.Include(p => p.Items)
.Select(p => new { p.ProductName, p.QuantityJSON, p.Items})
.Where(p => p.QuantityJSON != null)
.ToListAsync();
var quantityJsonDict = new Dictionary<string, Dictionary<string,int>>();
foreach (var item in result)
{
quantityJsonDict[item.ProductName] = JsonConvert.DeserializeObject<Dictionary<string, int>>(item.QuantityJSON)!;
quantityJsonDict[item.ProductName] = JsonConvert.DeserializeObject<Dictionary<string, int>>(item.QuantityJSON!)!;
if (!quantityJsonDict.TryGetValue(item.ProductName, out var deptDict))
{
continue;
@ -163,7 +165,8 @@ namespace PSTW_CentralSystem.Controllers.API
currentProductBalance.Add(new ProductReport
{
ProductName = item.ProductName,
Quantity = quantity
Quantity = quantity,
TotalPrice = item.Items!.Sum(i => i.ConvertPrice * i.Quantity)
});
}
}
@ -177,7 +180,8 @@ namespace PSTW_CentralSystem.Controllers.API
.Select(m => new
{
ProductName = m.Item!.Product!.ProductName,
QuantityOut = m.Quantity??0,
QuantityIn = m.Quantity??0,
PriceIn = m.Quantity * m.Item!.ConvertPrice
})
.ToListAsync();
@ -190,6 +194,7 @@ namespace PSTW_CentralSystem.Controllers.API
{
ProductName = m.Item!.Product!.ProductName,
QuantityOut = m.Quantity??0,
PriceOut = m.Quantity * m.Item!.ConvertPrice
})
.ToListAsync();
@ -199,12 +204,14 @@ namespace PSTW_CentralSystem.Controllers.API
var movementIn = thisMonthMovementIn.FirstOrDefault(m => m.ProductName == item.ProductName);
if (movementIn != null && item.Quantity > 0)
{
item.Quantity += movementIn.QuantityOut;
item.Quantity += movementIn.QuantityIn;
item.TotalPrice += (float)movementIn.PriceIn!;
}
var movementOut = thisMonthMovementOut.FirstOrDefault(m => m.ProductName == item.ProductName);
if (movementOut != null && item.Quantity > 0)
{
item.Quantity -= movementOut.QuantityOut;
item.TotalPrice -= (float)movementOut.PriceOut!;
}
}
@ -239,6 +246,10 @@ namespace PSTW_CentralSystem.Controllers.API
ItemName = m.Item!.Product!.ProductName,
Quantity = m.Quantity,
ItemPrice = m.Item!.ConvertPrice,
PO = m.Item!.PONo,
DO = m.Item!.DONo,
SerialNumber = m.Item.SerialNumber,
UniqueID = m.Item.UniqueID,
})
.ToList(),
TotalItemPrice = latestItemMovements.Where(m => m.ToUser == u.Id).Sum(m => m!.Item!.ConvertPrice * m.Quantity),

View File

@ -922,6 +922,9 @@
<!-- VUE Date Picker-->
<link href="~/lib/vue-datepicker/mainvuedate.css" rel="stylesheet" />
<script src="~/lib/vue-datepicker/vue-datepicker.iife.js"></script>
<!-- VUE DataTables -->
@* <script src="~/lib/vue-datatables/datatables.net-vue3.js"></script>
<script src="~/lib/vue-datatables/datatables.net-vue3.umd.js"></script> *@
<!-- Bootstrap tether Core JavaScript -->
<script src="~/assets/libs/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<!-- slimscrollbar scrollbar JavaScript -->

View File

@ -0,0 +1,83 @@
import { AllowedComponentProps } from 'vue';
import type { Api } from 'datatables.net';
import { ComponentCustomProps } from 'vue';
import { ComponentOptionsMixin } from 'vue';
import type { Config } from 'datatables.net';
import type { ConfigColumns } from 'datatables.net';
import { DefineComponent } from 'vue';
import { ExtractPropTypes } from 'vue';
import { Plugin as Plugin_2 } from 'vue';
import { PropType } from 'vue';
import { Ref } from 'vue';
import { VNodeProps } from 'vue';
declare type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
declare type __VLS_TypePropsToRuntimeProps<T> = {
[K in keyof T]-?: {} extends Pick<T, K> ? {
type: PropType<__VLS_NonUndefinedable<T[K]>>;
} : {
type: PropType<T[K]>;
required: true;
};
};
declare type __VLS_WithTemplateSlots<T, S> = T & {
new (): {
$slots: S;
};
};
export declare const DataTable: __VLS_WithTemplateSlots<DefineComponent<__VLS_TypePropsToRuntimeProps<{
/**
* Load data for the table's content from an Ajax source
*/
ajax?: Config['ajax'];
/**
* Set column specific initialisation properties.
*/
columns?: ConfigColumns[] | undefined;
/**
* Data to use as the display data for the table.
*/
data?: any;
/**
* DataTables options
*/
options?: Config | undefined;
}>, {
/**
* DataTable instance
*/
dt: Ref<Api<any> | undefined>;
}, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, string[], string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
/**
* Load data for the table's content from an Ajax source
*/
ajax?: Config['ajax'];
/**
* Set column specific initialisation properties.
*/
columns?: ConfigColumns[] | undefined;
/**
* Data to use as the display data for the table.
*/
data?: any;
/**
* DataTables options
*/
options?: Config | undefined;
}>>> & {
[x: `on${Capitalize<string>}`]: ((...args: any[]) => any) | undefined;
}, {}>, {
default: (_: {}) => any;
}>;
declare const _default: InstallableComponent;
export default _default;
export declare type InstallableComponent = typeof DataTable & {
install: Exclude<Plugin_2['install'], undefined>;
};
export { }

View File

@ -0,0 +1 @@
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const n=require("vue"),g=["childRow","column-sizing","column-visibility","destroy","draw","error","init","length","order","page","preDraw","preInit","preXhr","processing","requestChild","search","stateLoadParams","stateLoaded","stateSaveParams","xhr","autoFill","preAutoFill","buttons-action","buttons-processing","column-reorder","key","key-blur","key-focus","key-refocus","key-return-submit","responsive-display","responsive-resize","rowgroup-datasrc","pre-row-reorder","row-reorder","row-reordered","dtsb-inserted","deselect","select","select-blur","selectItems","selectStyle","user-select","stateRestore-change"];let m;const D={name:"Datatables.netVue",inheritAttrs:!1,use(u){m=u}},h=n.defineComponent({...D,props:{ajax:null,columns:null,data:null,options:null},emits:g,setup(u,{expose:f}){const i=u,v=n.ref(null),c={},s=n.ref(),w=n.ref([]);n.watch(()=>i.data,t=>{let e=s.value;e&&(p(e),e.clear(),e.rows.add(t).draw(!1))},{deep:!0}),n.onMounted(()=>{var a;const t=n.getCurrentInstance();let e=Object.assign({},i.options)||{};if(i.data&&(e.data=i.data,k(e.data)),i.columns&&(e.columns=i.columns),e.columns&&y(e.columns,t),i.ajax&&(e.ajax=i.ajax),e.columnDefs||(e.columnDefs=[]),t){let l=Object.keys(t.slots);for(let r=0;r<l.length;r++){let o=l[r];if(o.match(/^column\-/)){let d=o.replace("column-","");e.columnDefs.push({target:d.match(/^\d+$/)?parseInt(d):d+":name",render:"#"+o})}}y(e.columnDefs,t)}if(!m)throw new Error("DataTables library not set. See https://datatables.net/tn/19 for details.");s.value=new m(n.unref(v),e),(a=s.value)==null||a.on("preXhr",function(){p(s.value)});for(let l of g)s.value&&t&&s.value.on(l,function(){var r=Array.from(arguments),o=r.shift();r.unshift({event:o,dt:s}),r.unshift(l),t.emit.apply(t,r)})}),n.onBeforeUnmount(()=>{var t;p(s.value),(t=s.value)==null||t.destroy(!0)});function k(t){w.value=t.value?t.value.slice():t.slice()}function b(t){return function(e,a,l,r){let o=r.settings.sTableId+","+r.row+","+r.col;if(!c[o]){let d=n.h("div",t({cellData:e,colIndex:r.col,rowData:l,rowIndex:r.row,type:a}));c[o]=document.createElement("div"),n.render(d,c[o])}return c[o]}}function y(t,e){if(e)for(let l=0;l<t.length;l++){let r=t[l];if(typeof r.render=="string"&&r.render.charAt(0)==="#"){var a=r.render.replace("#","");e.slots[a]&&(r.render=b(e.slots[a]))}else if(typeof r.render=="object"&&typeof r.render.display=="string"&&r.render.display.charAt(0)==="#"){var a=r.render.display.replace("#","");e.slots[a]&&(r.render.display=b(e.slots[a]))}}}function p(t){let e=Object.keys(c),a=t.table().node().id;for(var l=0;l<e.length;l++)e[l].indexOf(a+",")===0&&delete c[e[l]]}return f({dt:s}),(t,e)=>e[0]||(n.setBlockTracking(-1),e[0]=n.createElementVNode("div",{class:"datatable"},[n.createElementVNode("table",n.mergeProps({ref_key:"table",ref:v},t.$attrs,{style:{width:"100%"}}),[n.renderSlot(t.$slots,"default")],16)]),n.setBlockTracking(1),e[0])}}),j=(()=>{const u=h;return u.install=f=>{f.component("Datatables.netVue",u)},u})();exports.DataTable=h;exports.default=j;

View File

@ -0,0 +1,166 @@
import { defineComponent as x, ref as p, watch as j, onMounted as I, getCurrentInstance as A, unref as E, onBeforeUnmount as O, setBlockTracking as h, createElementVNode as g, mergeProps as T, renderSlot as R, h as S, render as _ } from "vue";
const w = [
"childRow",
"column-sizing",
"column-visibility",
"destroy",
"draw",
"error",
"init",
"length",
"order",
"page",
"preDraw",
"preInit",
"preXhr",
"processing",
"requestChild",
"search",
"stateLoadParams",
"stateLoaded",
"stateSaveParams",
"xhr",
"autoFill",
"preAutoFill",
"buttons-action",
"buttons-processing",
"column-reorder",
"key",
"key-blur",
"key-focus",
"key-refocus",
"key-return-submit",
"responsive-display",
"responsive-resize",
"rowgroup-datasrc",
"pre-row-reorder",
"row-reorder",
"row-reordered",
"dtsb-inserted",
"deselect",
"select",
"select-blur",
"selectItems",
"selectStyle",
"user-select",
"stateRestore-change"
];
let m;
const C = {
name: "Datatables.netVue",
inheritAttrs: !1,
use(i) {
m = i;
}
}, L = /* @__PURE__ */ x({
...C,
props: {
ajax: null,
columns: null,
data: null,
options: null
},
emits: w,
setup(i, { expose: c }) {
const o = i, y = p(null), u = {}, l = p(), D = p([]);
j(
() => o.data,
(t) => {
let e = l.value;
e && (f(e), e.clear(), e.rows.add(t).draw(!1));
},
{
deep: !0
}
), I(() => {
var a;
const t = A();
let e = Object.assign({}, o.options) || {};
if (o.data && (e.data = o.data, k(e.data)), o.columns && (e.columns = o.columns), e.columns && v(e.columns, t), o.ajax && (e.ajax = o.ajax), e.columnDefs || (e.columnDefs = []), t) {
let n = Object.keys(t.slots);
for (let r = 0; r < n.length; r++) {
let s = n[r];
if (s.match(/^column\-/)) {
let d = s.replace("column-", "");
e.columnDefs.push({
target: d.match(/^\d+$/) ? parseInt(d) : d + ":name",
render: "#" + s
});
}
}
v(e.columnDefs, t);
}
if (!m)
throw new Error(
"DataTables library not set. See https://datatables.net/tn/19 for details."
);
l.value = new m(E(y), e), (a = l.value) == null || a.on("preXhr", function() {
f(l.value);
});
for (let n of w)
l.value && t && l.value.on(n, function() {
var r = Array.from(arguments), s = r.shift();
r.unshift({ event: s, dt: l }), r.unshift(n), t.emit.apply(t, r);
});
}), O(() => {
var t;
f(l.value), (t = l.value) == null || t.destroy(!0);
});
function k(t) {
D.value = t.value ? t.value.slice() : t.slice();
}
function b(t) {
return function(e, a, n, r) {
let s = r.settings.sTableId + "," + r.row + "," + r.col;
if (!u[s]) {
let d = S("div", t({
cellData: e,
colIndex: r.col,
rowData: n,
rowIndex: r.row,
type: a
}));
u[s] = document.createElement("div"), _(d, u[s]);
}
return u[s];
};
}
function v(t, e) {
if (e)
for (let n = 0; n < t.length; n++) {
let r = t[n];
if (typeof r.render == "string" && r.render.charAt(0) === "#") {
var a = r.render.replace("#", "");
e.slots[a] && (r.render = b(e.slots[a]));
} else if (typeof r.render == "object" && typeof r.render.display == "string" && r.render.display.charAt(0) === "#") {
var a = r.render.display.replace("#", "");
e.slots[a] && (r.render.display = b(e.slots[a]));
}
}
}
function f(t) {
let e = Object.keys(u), a = t.table().node().id;
for (var n = 0; n < e.length; n++)
e[n].indexOf(a + ",") === 0 && delete u[e[n]];
}
return c({
dt: l
}), (t, e) => e[0] || (h(-1), e[0] = g("div", { class: "datatable" }, [
g("table", T({
ref_key: "table",
ref: y
}, t.$attrs, { style: { width: "100%" } }), [
R(t.$slots, "default")
], 16)
]), h(1), e[0]);
}
}), V = /* @__PURE__ */ (() => {
const i = L;
return i.install = (c) => {
c.component("Datatables.netVue", i);
}, i;
})();
export {
L as DataTable,
V as default
};

View File

@ -0,0 +1 @@
(function(l,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],n):(l=typeof globalThis<"u"?globalThis:l||self,n((l.datatables=l.datatables||{},l.datatables["net-vue3"]={}),l.Vue))})(this,function(l,n){"use strict";const b=["childRow","column-sizing","column-visibility","destroy","draw","error","init","length","order","page","preDraw","preInit","preXhr","processing","requestChild","search","stateLoadParams","stateLoaded","stateSaveParams","xhr","autoFill","preAutoFill","buttons-action","buttons-processing","column-reorder","key","key-blur","key-focus","key-refocus","key-return-submit","responsive-display","responsive-resize","rowgroup-datasrc","pre-row-reorder","row-reorder","row-reordered","dtsb-inserted","deselect","select","select-blur","selectItems","selectStyle","user-select","stateRestore-change"];let p;const k={name:"Datatables.netVue",inheritAttrs:!1,use(c){p=c}},h=n.defineComponent({...k,props:{ajax:null,columns:null,data:null,options:null},emits:b,setup(c,{expose:m}){const d=c,g=n.ref(null),u={},o=n.ref(),j=n.ref([]);n.watch(()=>d.data,t=>{let e=o.value;e&&(y(e),e.clear(),e.rows.add(t).draw(!1))},{deep:!0}),n.onMounted(()=>{var a;const t=n.getCurrentInstance();let e=Object.assign({},d.options)||{};if(d.data&&(e.data=d.data,x(e.data)),d.columns&&(e.columns=d.columns),e.columns&&v(e.columns,t),d.ajax&&(e.ajax=d.ajax),e.columnDefs||(e.columnDefs=[]),t){let s=Object.keys(t.slots);for(let r=0;r<s.length;r++){let i=s[r];if(i.match(/^column\-/)){let f=i.replace("column-","");e.columnDefs.push({target:f.match(/^\d+$/)?parseInt(f):f+":name",render:"#"+i})}}v(e.columnDefs,t)}if(!p)throw new Error("DataTables library not set. See https://datatables.net/tn/19 for details.");o.value=new p(n.unref(g),e),(a=o.value)==null||a.on("preXhr",function(){y(o.value)});for(let s of b)o.value&&t&&o.value.on(s,function(){var r=Array.from(arguments),i=r.shift();r.unshift({event:i,dt:o}),r.unshift(s),t.emit.apply(t,r)})}),n.onBeforeUnmount(()=>{var t;y(o.value),(t=o.value)==null||t.destroy(!0)});function x(t){j.value=t.value?t.value.slice():t.slice()}function w(t){return function(e,a,s,r){let i=r.settings.sTableId+","+r.row+","+r.col;if(!u[i]){let f=n.h("div",t({cellData:e,colIndex:r.col,rowData:s,rowIndex:r.row,type:a}));u[i]=document.createElement("div"),n.render(f,u[i])}return u[i]}}function v(t,e){if(e)for(let s=0;s<t.length;s++){let r=t[s];if(typeof r.render=="string"&&r.render.charAt(0)==="#"){var a=r.render.replace("#","");e.slots[a]&&(r.render=w(e.slots[a]))}else if(typeof r.render=="object"&&typeof r.render.display=="string"&&r.render.display.charAt(0)==="#"){var a=r.render.display.replace("#","");e.slots[a]&&(r.render.display=w(e.slots[a]))}}}function y(t){let e=Object.keys(u),a=t.table().node().id;for(var s=0;s<e.length;s++)e[s].indexOf(a+",")===0&&delete u[e[s]]}return m({dt:o}),(t,e)=>e[0]||(n.setBlockTracking(-1),e[0]=n.createElementVNode("div",{class:"datatable"},[n.createElementVNode("table",n.mergeProps({ref_key:"table",ref:g},t.$attrs,{style:{width:"100%"}}),[n.renderSlot(t.$slots,"default")],16)]),n.setBlockTracking(1),e[0])}}),D=(()=>{const c=h;return c.install=m=>{m.component("Datatables.netVue",c)},c})();l.DataTable=h,l.default=D,Object.defineProperties(l,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});