diff --git a/src/App.vue b/src/App.vue index 421b7359..f7541180 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,11 +3,12 @@ id="app" class="h-screen flex flex-col font-sans overflow-hidden antialiased" > - + - - diff --git a/src/background.js b/src/background.js index 2f554be8..ff498e01 100644 --- a/src/background.js +++ b/src/background.js @@ -1,23 +1,21 @@ 'use strict'; -import path from 'path'; import electron, { app, - dialog, - protocol, BrowserWindow, + dialog, ipcMain, Menu, + protocol, shell, } from 'electron'; -import { autoUpdater } from 'electron-updater'; -import Store from 'electron-store'; import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'; +import Store from 'electron-store'; +import { autoUpdater } from 'electron-updater'; +import path from 'path'; import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'; - +import { IPC_ACTIONS, IPC_MESSAGES } from './messages'; import saveHtmlAsPdf from './saveHtmlAsPdf'; -import { IPC_MESSAGES, IPC_ACTIONS } from './messages'; -import theme from '@/theme'; const isDevelopment = process.env.NODE_ENV !== 'production'; const isMac = process.platform === 'darwin'; @@ -97,28 +95,6 @@ function createWindow() { }); } -function createSettingsWindow(tab = 'General') { - let settingsWindow = new BrowserWindow({ - parent: mainWindow, - frame: isLinux, - width: 460, - height: 577, - icon, - title, - backgroundColor: theme.backgroundColor.gray['200'], - webPreferences: { - contextIsolation: false, // TODO: Switch this on - nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION, - }, - resizable: false, - }); - - settingsWindow.loadURL(`${winURL}#/settings/${tab}`); - settingsWindow.on('close', () => { - mainWindow.reload(); - }); -} - /* --------------------------------- * Register ipcMain message handlers * ---------------------------------*/ @@ -130,10 +106,6 @@ ipcMain.on(IPC_MESSAGES.CHECK_FOR_UPDATES, () => { } }); -ipcMain.on(IPC_MESSAGES.OPEN_SETTINGS, (event, tab) => { - createSettingsWindow(tab); -}); - ipcMain.on(IPC_MESSAGES.OPEN_MENU, (event) => { const window = event.sender.getOwnerBrowserWindow(); const menu = Menu.getApplicationMenu(); diff --git a/src/components/Icons/18/settings.vue b/src/components/Icons/18/settings.vue index a503a4e7..48621c0a 100644 --- a/src/components/Icons/18/settings.vue +++ b/src/components/Icons/18/settings.vue @@ -1,4 +1,4 @@ - diff --git a/src/pages/Settings/TabInvoice.vue b/src/pages/Settings/TabInvoice.vue index d21434ac..4b230ebe 100644 --- a/src/pages/Settings/TabInvoice.vue +++ b/src/pages/Settings/TabInvoice.vue @@ -38,7 +38,7 @@ diff --git a/src/pages/SetupWizard/SetupWizard.vue b/src/pages/SetupWizard/SetupWizard.vue index a4b83d32..7b0dd637 100644 --- a/src/pages/SetupWizard/SetupWizard.vue +++ b/src/pages/SetupWizard/SetupWizard.vue @@ -74,6 +74,7 @@ import { getErrorMessage, handleErrorWithDialog, showMessageDialog, + purgeCache, } from '@/utils'; export default { @@ -145,13 +146,7 @@ export default { const filePath = config.get('lastSelectedFilePath'); renameDbFile(filePath); - // Clear cache to prevent doc changed error. - Object.keys(frappe.docs) - .filter((d) => frappe.docs[d][d] instanceof frappe.BaseMeta) - .forEach((d) => { - frappe.removeFromCache(d, d); - delete frappe[d]; - }); + purgeCache(); const connectionSuccess = await connectToLocalDatabase(filePath); if (connectionSuccess) { diff --git a/src/router.js b/src/router.js index 50c83d40..65a0e2b7 100644 --- a/src/router.js +++ b/src/router.js @@ -1,103 +1,110 @@ -import Vue from 'vue'; -import Router from 'vue-router'; - +import ChartOfAccounts from '@/pages/ChartOfAccounts'; // standard views import Dashboard from '@/pages/Dashboard/Dashboard'; +// custom views +import GetStarted from '@/pages/GetStarted'; +import InvoiceForm from '@/pages/InvoiceForm'; +import JournalEntryForm from '@/pages/JournalEntryForm'; import ListView from '@/pages/ListView/ListView'; import PrintView from '@/pages/PrintView/PrintView'; import QuickEditForm from '@/pages/QuickEditForm'; import Report from '@/pages/Report'; +import Settings from '@/pages/Settings/Settings'; +import Vue from 'vue'; +import Router from 'vue-router'; + -// custom views -import GetStarted from '@/pages/GetStarted'; -import ChartOfAccounts from '@/pages/ChartOfAccounts'; -import InvoiceForm from '@/pages/InvoiceForm'; -import JournalEntryForm from '@/pages/JournalEntryForm'; Vue.use(Router); const routes = [ { path: '/', - component: Dashboard + component: Dashboard, }, { path: '/get-started', - component: GetStarted + component: GetStarted, }, { path: '/edit/JournalEntry/:name', name: 'JournalEntryForm', components: { default: JournalEntryForm, - edit: QuickEditForm + edit: QuickEditForm, }, props: { - default: route => { + default: (route) => { // for sidebar item active state route.params.doctype = 'JournalEntry'; return { doctype: 'JournalEntry', - name: route.params.name + name: route.params.name, }; }, - edit: route => route.query - } + edit: (route) => route.query, + }, }, { path: '/edit/:doctype/:name', name: 'InvoiceForm', components: { default: InvoiceForm, - edit: QuickEditForm + edit: QuickEditForm, }, props: { default: true, - edit: route => route.query - } + edit: (route) => route.query, + }, }, { path: '/list/:doctype', name: 'ListView', components: { default: ListView, - edit: QuickEditForm + edit: QuickEditForm, }, props: { - default: route => { + default: (route) => { const { doctype, filters } = route.params; return { doctype, - filters + filters, }; }, - edit: route => route.query - } + edit: (route) => route.query, + }, }, { path: '/print/:doctype/:name', name: 'PrintView', component: PrintView, - props: true + props: true, }, { path: '/report/:reportName', name: 'Report', component: Report, - props: true + props: true, }, { path: '/chart-of-accounts', name: 'Chart Of Accounts', components: { default: ChartOfAccounts, - edit: QuickEditForm + edit: QuickEditForm, }, props: { default: true, - edit: route => route.query - } - } + edit: (route) => route.query, + }, + }, + { + path: '/settings', + name: 'Settings', + component: Settings, + props: true, + }, ]; let router = new Router({ routes }); diff --git a/src/sidebarConfig.js b/src/sidebarConfig.js index fee53ab9..ae61e4e3 100644 --- a/src/sidebarConfig.js +++ b/src/sidebarConfig.js @@ -1,5 +1,4 @@ import frappe from 'frappejs'; -import { openSettings } from '@/utils'; import { _ } from 'frappejs/utils'; import Icon from './components/Icon'; @@ -12,12 +11,12 @@ const config = { { title: _('Get Started'), route: '/get-started', - icon: getIcon('general', '24', '5') + icon: getIcon('general', '24', '5'), }, { title: _('Dashboard'), route: '/', - icon: getIcon('dashboard') + icon: getIcon('dashboard'), }, { title: _('Sales'), @@ -27,29 +26,29 @@ const config = { { label: _('Invoices'), route: '/list/SalesInvoice', - doctype: 'SalesInvoice' + doctype: 'SalesInvoice', }, { label: _('Customers'), route: '/list/Customer', - doctype: 'Customer' + doctype: 'Customer', }, { label: _('Items'), route: '/list/Item', - doctype: 'Item' + doctype: 'Item', }, { label: _('Payments'), route: '/list/Payment', - doctype: 'Payment' + doctype: 'Payment', }, { label: _('Journal Entry'), route: '/list/JournalEntry', - doctype: 'JournalEntry' - } - ] + doctype: 'JournalEntry', + }, + ], }, { title: _('Purchases'), @@ -59,29 +58,29 @@ const config = { { label: _('Bills'), route: '/list/PurchaseInvoice', - doctype: 'PurchaseInvoice' + doctype: 'PurchaseInvoice', }, { label: _('Suppliers'), route: '/list/Supplier', - doctype: 'Supplier' + doctype: 'Supplier', }, { label: _('Items'), route: '/list/Item', - doctype: 'Item' + doctype: 'Item', }, { label: _('Payments'), route: '/list/Payment', - doctype: 'Payment' + doctype: 'Payment', }, { label: _('Journal Entry'), route: '/list/JournalEntry', - doctype: 'JournalEntry' - } - ] + doctype: 'JournalEntry', + }, + ], }, { title: _('Reports'), @@ -90,21 +89,21 @@ const config = { items: [ { label: _('General Ledger'), - route: '/report/general-ledger' + route: '/report/general-ledger', }, { label: _('Profit And Loss'), - route: '/report/profit-and-loss' + route: '/report/profit-and-loss', }, { label: _('Balance Sheet'), - route: '/report/balance-sheet' + route: '/report/balance-sheet', }, { label: _('Trial Balance'), - route: '/report/trial-balance' - } - ] + route: '/report/trial-balance', + }, + ], }, { title: _('Setup'), @@ -113,22 +112,20 @@ const config = { items: [ { label: _('Chart of Accounts'), - route: '/chart-of-accounts' + route: '/chart-of-accounts', }, { label: _('Taxes'), route: '/list/Tax', - doctype: 'Tax' + doctype: 'Tax', }, { label: _('Settings'), - action() { - openSettings(); - } - } - ] - } - ] + route: '/settings', + }, + ], + }, + ], }; function getIcon(name, size = '18', height = null) { @@ -140,12 +137,12 @@ function getIcon(name, size = '18', height = null) { { name, size, - height + height, }, this.$attrs - ) + ), }); - } + }, }; } diff --git a/src/utils.js b/src/utils.js index 00f91804..01fbcf11 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,14 +1,14 @@ -import frappe from 'frappejs'; -import fs from 'fs'; -import { _ } from 'frappejs/utils'; -import migrate from './migrate'; -import { ipcRenderer } from 'electron'; -import { IPC_MESSAGES, IPC_ACTIONS } from './messages'; -import SQLite from 'frappejs/backends/sqlite'; -import postStart from '../server/postStart'; -import router from '@/router'; import Avatar from '@/components/Avatar'; import config from '@/config'; +import router from '@/router'; +import { ipcRenderer } from 'electron'; +import frappe from 'frappejs'; +import SQLite from 'frappejs/backends/sqlite'; +import { _ } from 'frappejs/utils'; +import fs from 'fs'; +import postStart from '../server/postStart'; +import { IPC_ACTIONS, IPC_MESSAGES } from './messages'; +import migrate from './migrate'; export async function createNewDatabase() { const options = { @@ -212,7 +212,7 @@ export function openQuickEdit({ doctype, name, hideFields, defaults = {} }) { // editing another document of the same doctype method = 'replace'; } - if (query.name === name) return + if (query.name === name) return; router[method]({ query: { edit: 1, @@ -257,7 +257,8 @@ export function getActionsForDocument(doc) { component: { template: `{{ _('Delete') }}`, }, - condition: (doc) => !doc.isNew() && !doc.submitted && !doc.meta.isSingle && !doc.cancelled, + condition: (doc) => + !doc.isNew() && !doc.submitted && !doc.meta.isSingle && !doc.cancelled, action: () => deleteDocWithPrompt(doc).then((res) => { if (res) { @@ -293,10 +294,6 @@ export function getActionsForDocument(doc) { return actions; } -export function openSettings(tab = 'General') { - ipcRenderer.send(IPC_MESSAGES.OPEN_SETTINGS, tab); -} - export async function runWindowAction(name) { switch (name) { case 'close': @@ -341,3 +338,16 @@ export function routeTo(route) { router.push(route); } } + +export function purgeCache(purgeAll = false) { + const filterFunction = purgeAll + ? (d) => true + : (d) => frappe.docs[d][d] instanceof frappe.BaseMeta; + + Object.keys(frappe.docs) + .filter(filterFunction) + .forEach((d) => { + frappe.removeFromCache(d, d); + delete frappe[d]; + }); +}