const App = { setup() { const state = Vue.reactive({ mainData: [], deleteMode: false, vendorListLookupData: [], taxListLookupData: [], purchaseOrderStatusListLookupData: [], secondaryData: [], productListLookupData: [], mainTitle: null, id: '', number: '', orderDate: '', description: '', vendorId: null, taxId: null, orderStatus: null, errors: { orderDate: '', vendorId: '', taxId: '', orderStatus: '', description: '' }, showComplexDiv: false, isSubmitting: false, subTotalAmount: '0.00', taxAmount: '0.00', totalAmount: '0.00' }); const mainGridRef = Vue.ref(null); const mainModalRef = Vue.ref(null); const orderDateRef = Vue.ref(null); const numberRef = Vue.ref(null); const vendorIdRef = Vue.ref(null); const taxIdRef = Vue.ref(null); const orderStatusRef = Vue.ref(null); const secondaryGridRef = Vue.ref(null); const validateForm = function () { state.errors.orderDate = ''; state.errors.vendorId = ''; state.errors.taxId = ''; state.errors.orderStatus = ''; let isValid = true; if (!state.orderDate) { state.errors.orderDate = 'Order date is required.'; isValid = false; } if (!state.vendorId) { state.errors.vendorId = 'Vendor is required.'; isValid = false; } if (!state.taxId) { state.errors.taxId = 'Tax is required.'; isValid = false; } if (!state.orderStatus) { state.errors.orderStatus = 'Order status is required.'; isValid = false; } return isValid; }; const resetFormState = () => { state.id = ''; state.number = ''; state.orderDate = ''; state.description = ''; state.vendorId = null; state.taxId = null; state.orderStatus = null; state.errors = { orderDate: '', vendorId: '', taxId: '', orderStatus: '', description: '' }; state.secondaryData = []; state.subTotalAmount = '0.00'; state.taxAmount = '0.00'; state.totalAmount = '0.00'; state.showComplexDiv = false; }; const services = { getMainData: async () => { try { const response = await AxiosManager.get('/PurchaseOrder/GetPurchaseOrderList', {}); return response; } catch (error) { throw error; } }, createMainData: async (orderDate, description, orderStatus, taxId, vendorId, createdById) => { try { const response = await AxiosManager.post('/PurchaseOrder/CreatePurchaseOrder', { orderDate, description, orderStatus, taxId, vendorId, createdById }); return response; } catch (error) { throw error; } }, updateMainData: async (id, orderDate, description, orderStatus, taxId, vendorId, updatedById) => { try { const response = await AxiosManager.post('/PurchaseOrder/UpdatePurchaseOrder', { id, orderDate, description, orderStatus, taxId, vendorId, updatedById }); return response; } catch (error) { throw error; } }, deleteMainData: async (id, deletedById) => { try { const response = await AxiosManager.post('/PurchaseOrder/DeletePurchaseOrder', { id, deletedById }); return response; } catch (error) { throw error; } }, getVendorListLookupData: async () => { try { const response = await AxiosManager.get('/Vendor/GetVendorList', {}); return response; } catch (error) { throw error; } }, getTaxListLookupData: async () => { try { const response = await AxiosManager.get('/Tax/GetTaxList', {}); return response; } catch (error) { throw error; } }, getPurchaseOrderStatusListLookupData: async () => { try { const response = await AxiosManager.get('/PurchaseOrder/GetPurchaseOrderStatusList', {}); return response; } catch (error) { throw error; } }, getSecondaryData: async (purchaseOrderId) => { try { const response = await AxiosManager.get('/PurchaseOrderItem/GetPurchaseOrderItemByPurchaseOrderIdList?purchaseOrderId=' + purchaseOrderId, {}); return response; } catch (error) { throw error; } }, createSecondaryData: async (unitPrice, quantity, summary, productId, purchaseOrderId, createdById) => { try { const response = await AxiosManager.post('/PurchaseOrderItem/CreatePurchaseOrderItem', { unitPrice, quantity, summary, productId, purchaseOrderId, createdById }); return response; } catch (error) { throw error; } }, updateSecondaryData: async (id, unitPrice, quantity, summary, productId, purchaseOrderId, updatedById) => { try { const response = await AxiosManager.post('/PurchaseOrderItem/UpdatePurchaseOrderItem', { id, unitPrice, quantity, summary, productId, purchaseOrderId, updatedById }); return response; } catch (error) { throw error; } }, deleteSecondaryData: async (id, deletedById) => { try { const response = await AxiosManager.post('/PurchaseOrderItem/DeletePurchaseOrderItem', { id, deletedById }); return response; } catch (error) { throw error; } }, getProductListLookupData: async () => { try { const response = await AxiosManager.get('/Product/GetProductList', {}); return response; } catch (error) { throw error; } } }; const methods = { populateVendorListLookupData: async () => { const response = await services.getVendorListLookupData(); state.vendorListLookupData = response?.data?.content?.data; }, populateTaxListLookupData: async () => { const response = await services.getTaxListLookupData(); state.taxListLookupData = response?.data?.content?.data; }, populatePurchaseOrderStatusListLookupData: async () => { const response = await services.getPurchaseOrderStatusListLookupData(); state.purchaseOrderStatusListLookupData = response?.data?.content?.data; }, populateMainData: async () => { const response = await services.getMainData(); state.mainData = response?.data?.content?.data.map(item => ({ ...item, orderDate: new Date(item.orderDate), createdAtUtc: new Date(item.createdAtUtc) })); }, populateSecondaryData: async (purchaseOrderId) => { try { const response = await services.getSecondaryData(purchaseOrderId); state.secondaryData = response?.data?.content?.data.map(item => ({ ...item, createdAtUtc: new Date(item.createdAtUtc) })); methods.refreshPaymentSummary(purchaseOrderId); } catch (error) { state.secondaryData = []; } }, populateProductListLookupData: async () => { const response = await services.getProductListLookupData(); state.productListLookupData = response?.data?.content?.data; }, refreshPaymentSummary: async (id) => { const record = state.mainData.find(item => item.id === id); if (record) { state.subTotalAmount = NumberFormatManager.formatToLocale(record.beforeTaxAmount ?? 0); state.taxAmount = NumberFormatManager.formatToLocale(record.taxAmount ?? 0); state.totalAmount = NumberFormatManager.formatToLocale(record.afterTaxAmount ?? 0); } }, handleFormSubmit: async () => { state.isSubmitting = true; await new Promise(resolve => setTimeout(resolve, 200)); if (!validateForm()) { state.isSubmitting = false; return; } try { const response = state.id === '' ? await services.createMainData(state.orderDate, state.description, state.orderStatus, state.taxId, state.vendorId, StorageManager.getUserId()) : state.deleteMode ? await services.deleteMainData(state.id, StorageManager.getUserId()) : await services.updateMainData(state.id, state.orderDate, state.description, state.orderStatus, state.taxId, state.vendorId, StorageManager.getUserId()); if (response.data.code === 200) { await methods.populateMainData(); mainGrid.refresh(); if (!state.deleteMode) { state.mainTitle = 'Edit Purchase Order'; state.id = response?.data?.content?.data.id ?? ''; state.number = response?.data?.content?.data.number ?? ''; state.orderDate = response?.data?.content?.data.orderDate ? new Date(response.data.content.data.orderDate) : null; state.description = response?.data?.content?.data.description ?? ''; state.vendorId = response?.data?.content?.data.vendorId ?? ''; state.taxId = response?.data?.content?.data.taxId ?? ''; taxListLookup.trackingChange = true; state.orderStatus = String(response?.data?.content?.data.orderStatus ?? ''); state.showComplexDiv = true; await methods.refreshPaymentSummary(state.id); Swal.fire({ icon: 'success', title: 'Save Successful', timer: 1000, showConfirmButton: false }); } else { Swal.fire({ icon: 'success', title: 'Delete Successful', text: 'Form will be closed...', timer: 2000, showConfirmButton: false }); setTimeout(() => { mainModal.obj.hide(); resetFormState(); }, 2000); } } else { Swal.fire({ icon: 'error', title: state.deleteMode ? 'Delete Failed' : 'Save Failed', text: response.data.message ?? 'Please check your data.', confirmButtonText: 'Try Again' }); } } catch (error) { Swal.fire({ icon: 'error', title: 'An Error Occurred', text: error.response?.data?.message ?? 'Please try again.', confirmButtonText: 'OK' }); } finally { state.isSubmitting = false; } }, onMainModalHidden: () => { state.errors.orderDate = ''; state.errors.vendorId = ''; state.errors.taxId = ''; state.errors.orderStatus = ''; taxListLookup.trackingChange = false; } }; const vendorListLookup = { obj: null, create: () => { if (state.vendorListLookupData && Array.isArray(state.vendorListLookupData)) { vendorListLookup.obj = new ej.dropdowns.DropDownList({ dataSource: state.vendorListLookupData, fields: { value: 'id', text: 'name' }, placeholder: 'Select a Vendor', filterBarPlaceholder: 'Search', sortOrder: 'Ascending', allowFiltering: true, filtering: (e) => { e.preventDefaultAction = true; let query = new ej.data.Query(); if (e.text !== '') { query = query.where('name', 'startsWith', e.text, true); } e.updateData(state.vendorListLookupData, query); }, change: (e) => { state.vendorId = e.value; } }); vendorListLookup.obj.appendTo(vendorIdRef.value); } }, refresh: () => { if (vendorListLookup.obj) { vendorListLookup.obj.value = state.vendorId; } } }; const taxListLookup = { obj: null, trackingChange: false, create: () => { if (state.taxListLookupData && Array.isArray(state.taxListLookupData)) { taxListLookup.obj = new ej.dropdowns.DropDownList({ dataSource: state.taxListLookupData, fields: { value: 'id', text: 'name' }, placeholder: 'Select a Tax', change: async (e) => { state.taxId = e.value; if (e.isInteracted && taxListLookup.trackingChange) { await methods.handleFormSubmit(); } } }); taxListLookup.obj.appendTo(taxIdRef.value); } }, refresh: () => { if (taxListLookup.obj) { taxListLookup.obj.value = state.taxId; } } }; const purchaseOrderStatusListLookup = { obj: null, create: () => { if (state.purchaseOrderStatusListLookupData && Array.isArray(state.purchaseOrderStatusListLookupData)) { purchaseOrderStatusListLookup.obj = new ej.dropdowns.DropDownList({ dataSource: state.purchaseOrderStatusListLookupData, fields: { value: 'id', text: 'name' }, placeholder: 'Select an Order Status', change: (e) => { state.orderStatus = e.value; } }); purchaseOrderStatusListLookup.obj.appendTo(orderStatusRef.value); } }, refresh: () => { if (purchaseOrderStatusListLookup.obj) { purchaseOrderStatusListLookup.obj.value = state.orderStatus; } } }; const orderDatePicker = { obj: null, create: () => { orderDatePicker.obj = new ej.calendars.DatePicker({ format: 'yyyy-MM-dd', value: state.orderDate ? new Date(state.orderDate) : null, change: (e) => { state.orderDate = DateFormatManager.preserveClientDate(e.value); } }); orderDatePicker.obj.appendTo(orderDateRef.value); }, refresh: () => { if (orderDatePicker.obj) { orderDatePicker.obj.value = state.orderDate ? new Date(state.orderDate) : null; } } }; const numberText = { obj: null, create: () => { numberText.obj = new ej.inputs.TextBox({ placeholder: '[auto]', readonly: true }); numberText.obj.appendTo(numberRef.value); } }; Vue.watch( () => state.orderDate, (newVal, oldVal) => { orderDatePicker.refresh(); state.errors.orderDate = ''; } ); Vue.watch( () => state.vendorId, (newVal, oldVal) => { vendorListLookup.refresh(); state.errors.vendorId = ''; } ); Vue.watch( () => state.taxId, (newVal, oldVal) => { taxListLookup.refresh(); state.errors.taxId = ''; } ); Vue.watch( () => state.orderStatus, (newVal, oldVal) => { purchaseOrderStatusListLookup.refresh(); state.errors.orderStatus = ''; } ); const mainGrid = { obj: null, create: async (dataSource) => { mainGrid.obj = new ej.grids.Grid({ height: '240px', dataSource: dataSource, allowFiltering: true, allowSorting: true, allowSelection: true, allowGrouping: true, groupSettings: { columns: ['vendorName'] }, allowTextWrap: true, allowResizing: true, allowPaging: true, allowExcelExport: true, filterSettings: { type: 'CheckBox' }, sortSettings: { columns: [{ field: 'createdAtUtc', direction: 'Descending' }] }, pageSettings: { currentPage: 1, pageSize: 50, pageSizes: ["10", "20", "50", "100", "200", "All"] }, selectionSettings: { persistSelection: true, type: 'Single' }, autoFit: true, showColumnMenu: true, gridLines: 'Horizontal', columns: [ { type: 'checkbox', width: 60 }, { field: 'id', isPrimaryKey: true, headerText: 'Id', visible: false }, { field: 'number', headerText: 'Number', width: 150, minWidth: 150 }, { field: 'orderDate', headerText: 'PO Date', width: 150, format: 'yyyy-MM-dd' }, { field: 'vendorName', headerText: 'Vendor', width: 200, minWidth: 200 }, { field: 'orderStatusName', headerText: 'Status', width: 150, minWidth: 150 }, { field: 'taxName', headerText: 'Tax', width: 150, minWidth: 150 }, { field: 'afterTaxAmount', headerText: 'Total Amount', width: 150, minWidth: 150, format: 'N2' }, { field: 'createdAtUtc', headerText: 'Created At UTC', width: 150, format: 'yyyy-MM-dd HH:mm' } ], toolbar: [ 'ExcelExport', 'Search', { type: 'Separator' }, { text: 'Add', tooltipText: 'Add', prefixIcon: 'e-add', id: 'AddCustom' }, { text: 'Edit', tooltipText: 'Edit', prefixIcon: 'e-edit', id: 'EditCustom' }, { text: 'Delete', tooltipText: 'Delete', prefixIcon: 'e-delete', id: 'DeleteCustom' }, { type: 'Separator' }, { text: 'Print PDF', tooltipText: 'Print PDF', id: 'PrintPDFCustom' }, ], beforeDataBound: () => { }, dataBound: function () { mainGrid.obj.toolbarModule.enableItems(['EditCustom', 'DeleteCustom', 'PrintPDFCustom'], false); mainGrid.obj.autoFitColumns(['number', 'orderDate', 'vendorName', 'orderStatusName', 'taxName', 'afterTaxAmount', 'createdAtUtc']); }, excelExportComplete: () => { }, rowSelected: () => { if (mainGrid.obj.getSelectedRecords().length == 1) { mainGrid.obj.toolbarModule.enableItems(['EditCustom', 'DeleteCustom', 'PrintPDFCustom'], true); } else { mainGrid.obj.toolbarModule.enableItems(['EditCustom', 'DeleteCustom', 'PrintPDFCustom'], false); } }, rowDeselected: () => { if (mainGrid.obj.getSelectedRecords().length == 1) { mainGrid.obj.toolbarModule.enableItems(['EditCustom', 'DeleteCustom', 'PrintPDFCustom'], true); } else { mainGrid.obj.toolbarModule.enableItems(['EditCustom', 'DeleteCustom', 'PrintPDFCustom'], false); } }, rowSelecting: () => { if (mainGrid.obj.getSelectedRecords().length) { mainGrid.obj.clearSelection(); } }, toolbarClick: async (args) => { if (args.item.id === 'MainGrid_excelexport') { mainGrid.obj.excelExport(); } if (args.item.id === 'AddCustom') { state.deleteMode = false; state.mainTitle = 'Add Purchase Order'; resetFormState(); state.secondaryData = []; secondaryGrid.refresh(); state.showComplexDiv = false; mainModal.obj.show(); } if (args.item.id === 'EditCustom') { state.deleteMode = false; if (mainGrid.obj.getSelectedRecords().length) { const selectedRecord = mainGrid.obj.getSelectedRecords()[0]; state.mainTitle = 'Edit Purchase Order'; state.id = selectedRecord.id ?? ''; state.number = selectedRecord.number ?? ''; state.orderDate = selectedRecord.orderDate ? new Date(selectedRecord.orderDate) : null; state.description = selectedRecord.description ?? ''; state.vendorId = selectedRecord.vendorId ?? ''; state.taxId = selectedRecord.taxId ?? ''; taxListLookup.trackingChange = true; state.orderStatus = String(selectedRecord.orderStatus ?? ''); state.showComplexDiv = true; await methods.populateSecondaryData(selectedRecord.id); secondaryGrid.refresh(); mainModal.obj.show(); } } if (args.item.id === 'DeleteCustom') { state.deleteMode = true; if (mainGrid.obj.getSelectedRecords().length) { const selectedRecord = mainGrid.obj.getSelectedRecords()[0]; state.mainTitle = 'Delete Purchase Order?'; state.id = selectedRecord.id ?? ''; state.number = selectedRecord.number ?? ''; state.orderDate = selectedRecord.orderDate ? new Date(selectedRecord.orderDate) : null; state.description = selectedRecord.description ?? ''; state.vendorId = selectedRecord.vendorId ?? ''; state.taxId = selectedRecord.taxId ?? ''; state.orderStatus = String(selectedRecord.orderStatus ?? ''); state.showComplexDiv = false; await methods.populateSecondaryData(selectedRecord.id); secondaryGrid.refresh(); mainModal.obj.show(); } } if (args.item.id === 'PrintPDFCustom') { if (mainGrid.obj.getSelectedRecords().length) { const selectedRecord = mainGrid.obj.getSelectedRecords()[0]; window.open('/PurchaseOrders/PurchaseOrderPdf?id=' + (selectedRecord.id ?? ''), '_blank'); } } } }); mainGrid.obj.appendTo(mainGridRef.value); }, refresh: () => { mainGrid.obj.setProperties({ dataSource: state.mainData }); } }; const secondaryGrid = { obj: null, create: async (dataSource) => { secondaryGrid.obj = new ej.grids.Grid({ height: 400, dataSource: dataSource, editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, showDeleteConfirmDialog: true, mode: 'Normal', allowEditOnDblClick: true }, allowFiltering: false, allowSorting: true, allowSelection: true, allowGrouping: false, allowTextWrap: true, allowResizing: true, allowPaging: false, allowExcelExport: true, filterSettings: { type: 'CheckBox' }, sortSettings: { columns: [{ field: 'productName', direction: 'Descending' }] }, pageSettings: { currentPage: 1, pageSize: 50, pageSizes: ["10", "20", "50", "100", "200", "All"] }, selectionSettings: { persistSelection: true, type: 'Single' }, autoFit: false, showColumnMenu: false, gridLines: 'Horizontal', columns: [ { type: 'checkbox', width: 60 }, { field: 'id', isPrimaryKey: true, headerText: 'Id', visible: false }, { field: 'productId', headerText: 'Product', width: 250, validationRules: { required: true }, disableHtmlEncode: false, valueAccessor: (field, data, column) => { const product = state.productListLookupData.find(item => item.id === data[field]); return product ? `${product.name}` : ''; }, editType: 'dropdownedit', edit: { create: () => { let productElem = document.createElement('input'); return productElem; }, read: () => { return productObj.value; }, destroy: () => { productObj.destroy(); }, write: (args) => { productObj = new ej.dropdowns.DropDownList({ dataSource: state.productListLookupData, fields: { value: 'id', text: 'name' }, value: args.rowData.productId, change: (e) => { const selectedProduct = state.productListLookupData.find(item => item.id === e.value); if (selectedProduct) { args.rowData.productId = selectedProduct.id; if (numberObj) { numberObj.value = selectedProduct.number; } if (priceObj) { priceObj.value = selectedProduct.unitPrice; } if (summaryObj) { summaryObj.value = selectedProduct.description; } if (quantityObj) { quantityObj.value = 1; const total = selectedProduct.unitPrice * quantityObj.value; if (totalObj) { totalObj.value = total; } } } }, placeholder: 'Select a Product', floatLabelType: 'Never' }); productObj.appendTo(args.element); } } }, { field: 'unitPrice', headerText: 'Unit Price', width: 200, validationRules: { required: true }, type: 'number', format: 'N2', textAlign: 'Right', edit: { create: () => { let priceElem = document.createElement('input'); return priceElem; }, read: () => { return priceObj.value; }, destroy: () => { priceObj.destroy(); }, write: (args) => { priceObj = new ej.inputs.NumericTextBox({ value: args.rowData.unitPrice ?? 0, change: (e) => { if (quantityObj && totalObj) { const total = e.value * quantityObj.value; totalObj.value = total; } } }); priceObj.appendTo(args.element); } } }, { field: 'quantity', headerText: 'Quantity', width: 200, validationRules: { required: true, custom: [(args) => { return args['value'] > 0; }, 'Must be a positive number and not zero'] }, type: 'number', format: 'N2', textAlign: 'Right', edit: { create: () => { let quantityElem = document.createElement('input'); return quantityElem; }, read: () => { return quantityObj.value; }, destroy: () => { quantityObj.destroy(); }, write: (args) => { quantityObj = new ej.inputs.NumericTextBox({ value: args.rowData.quantity ?? 0, change: (e) => { if (priceObj && totalObj) { const total = e.value * priceObj.value; totalObj.value = total; } } }); quantityObj.appendTo(args.element); } } }, { field: 'total', headerText: 'Total', width: 200, validationRules: { required: false }, type: 'number', format: 'N2', textAlign: 'Right', edit: { create: () => { let totalElem = document.createElement('input'); return totalElem; }, read: () => { return totalObj.value; }, destroy: () => { totalObj.destroy(); }, write: (args) => { totalObj = new ej.inputs.NumericTextBox({ value: args.rowData.total ?? 0, readonly: true }); totalObj.appendTo(args.element); } } }, { field: 'productNumber', headerText: 'Product Number', allowEditing: false, width: 180, edit: { create: () => { let numberElem = document.createElement('input'); return numberElem; }, read: () => { return numberObj.value; }, destroy: () => { numberObj.destroy(); }, write: (args) => { numberObj = new ej.inputs.TextBox(); numberObj.value = args.rowData.productNumber; numberObj.readonly = true; numberObj.appendTo(args.element); } } }, { field: 'summary', headerText: 'Summary', width: 200, edit: { create: () => { let summaryElem = document.createElement('input'); return summaryElem; }, read: () => { return summaryObj.value; }, destroy: () => { summaryObj.destroy(); }, write: (args) => { summaryObj = new ej.inputs.TextBox(); summaryObj.value = args.rowData.summary; summaryObj.appendTo(args.element); } } }, ], toolbar: [ 'ExcelExport', { type: 'Separator' }, 'Add', 'Edit', 'Delete', 'Update', 'Cancel', ], beforeDataBound: () => { }, dataBound: function () { }, excelExportComplete: () => { }, rowSelected: () => { if (secondaryGrid.obj.getSelectedRecords().length == 1) { secondaryGrid.obj.toolbarModule.enableItems(['Edit'], true); } else { secondaryGrid.obj.toolbarModule.enableItems(['Edit'], false); } }, rowDeselected: () => { if (secondaryGrid.obj.getSelectedRecords().length == 1) { secondaryGrid.obj.toolbarModule.enableItems(['Edit'], true); } else { secondaryGrid.obj.toolbarModule.enableItems(['Edit'], false); } }, rowSelecting: () => { if (secondaryGrid.obj.getSelectedRecords().length) { secondaryGrid.obj.clearSelection(); } }, toolbarClick: (args) => { if (args.item.id === 'SecondaryGrid_excelexport') { secondaryGrid.obj.excelExport(); } }, actionComplete: async (args) => { if (args.requestType === 'save' && args.action === 'add') { const purchaseOrderId = state.id; const userId = StorageManager.getUserId(); const data = args.data; await services.createSecondaryData(data?.unitPrice, data?.quantity, data?.summary, data?.productId, purchaseOrderId, userId); await methods.populateSecondaryData(purchaseOrderId); secondaryGrid.refresh(); Swal.fire({ icon: 'success', title: 'Save Successful', timer: 2000, showConfirmButton: false }); } if (args.requestType === 'save' && args.action === 'edit') { const purchaseOrderId = state.id; const userId = StorageManager.getUserId(); const data = args.data; await services.updateSecondaryData(data?.id, data?.unitPrice, data?.quantity, data?.summary, data?.productId, purchaseOrderId, userId); await methods.populateSecondaryData(purchaseOrderId); secondaryGrid.refresh(); Swal.fire({ icon: 'success', title: 'Save Successful', timer: 2000, showConfirmButton: false }); } if (args.requestType === 'delete') { const purchaseOrderId = state.id; const userId = StorageManager.getUserId(); const data = args.data[0]; await services.deleteSecondaryData(data?.id, userId); await methods.populateSecondaryData(purchaseOrderId); secondaryGrid.refresh(); Swal.fire({ icon: 'success', title: 'Delete Successful', timer: 2000, showConfirmButton: false }); } await methods.populateMainData(); mainGrid.refresh(); await methods.refreshPaymentSummary(state.id); } }); secondaryGrid.obj.appendTo(secondaryGridRef.value); }, refresh: () => { secondaryGrid.obj.setProperties({ dataSource: state.secondaryData }); } }; const mainModal = { obj: null, create: () => { mainModal.obj = new bootstrap.Modal(mainModalRef.value, { backdrop: 'static', keyboard: false }); } }; Vue.onMounted(async () => { try { await SecurityManager.authorizePage(['PurchaseOrders']); await SecurityManager.validateToken(); await methods.populateMainData(); await mainGrid.create(state.mainData); mainModal.create(); mainModalRef.value?.addEventListener('hidden.bs.modal', methods.onMainModalHidden); await methods.populateVendorListLookupData(); vendorListLookup.create(); await methods.populateTaxListLookupData(); taxListLookup.create(); await methods.populatePurchaseOrderStatusListLookupData(); purchaseOrderStatusListLookup.create(); orderDatePicker.create(); numberText.create(); await methods.populateProductListLookupData(); await secondaryGrid.create(state.secondaryData); } catch (e) { console.error('page init error:', e); } finally { } }); Vue.onUnmounted(() => { mainModalRef.value?.removeEventListener('hidden.bs.modal', methods.onMainModalHidden); }); return { mainGridRef, mainModalRef, orderDateRef, numberRef, vendorIdRef, taxIdRef, orderStatusRef, secondaryGridRef, state, methods, handler: { handleSubmit: methods.handleFormSubmit } }; } }; Vue.createApp(App).mount('#app');