mirror of
https://github.com/frappe/books.git
synced 2024-12-23 03:19:01 +00:00
fix: get sidebar to display
This commit is contained in:
parent
b383e426a0
commit
3f3da5001c
12
src/App.vue
12
src/App.vue
@ -4,18 +4,11 @@
|
||||
class="h-screen flex flex-col font-sans overflow-hidden antialiased"
|
||||
>
|
||||
<WindowsTitleBar v-if="platform === 'Windows'" />
|
||||
<!--
|
||||
<Desk
|
||||
class="flex-1"
|
||||
v-if="activeScreen === 'Desk'"
|
||||
@change-db-file="changeDbFile"
|
||||
/>-->
|
||||
<div
|
||||
v-if="activeScreen === 'Desk'"
|
||||
class="h-screen w-screen flex justify-center items-center bg-white"
|
||||
>
|
||||
<h1>Desk</h1>
|
||||
</div>
|
||||
/>
|
||||
|
||||
<DatabaseSelector
|
||||
v-if="activeScreen === 'DatabaseSelector'"
|
||||
@ -48,6 +41,7 @@ import TelemetryModal from './components/once/TelemetryModal.vue';
|
||||
import WindowsTitleBar from './components/WindowsTitleBar.vue';
|
||||
import { fyo, initializeInstance } from './initFyo';
|
||||
import DatabaseSelector from './pages/DatabaseSelector.vue';
|
||||
import Desk from './pages/Desk.vue';
|
||||
import SetupWizard from './pages/SetupWizard/SetupWizard.vue';
|
||||
import setupInstance from './setup/setupInstance';
|
||||
import './styles/index.css';
|
||||
@ -62,7 +56,7 @@ export default {
|
||||
};
|
||||
},
|
||||
components: {
|
||||
// Desk,
|
||||
Desk,
|
||||
SetupWizard,
|
||||
DatabaseSelector,
|
||||
WindowsTitleBar,
|
||||
|
@ -8,7 +8,6 @@ export default {
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
// default: 'middle-finger',
|
||||
required: true,
|
||||
validator: (value) => validIcons.includes(value),
|
||||
},
|
||||
|
@ -7,7 +7,8 @@
|
||||
>
|
||||
<div class="window-no-drag">
|
||||
<WindowControls v-if="platform === 'Mac'" class="px-3 mb-6" />
|
||||
<div class="px-3 flex flex-row items-center">
|
||||
<!-- Company name and DB Switcher -->
|
||||
<div class="px-3 flex flex-row items-center justify-between mb-6">
|
||||
<h6
|
||||
class="
|
||||
text-xl
|
||||
@ -15,6 +16,7 @@
|
||||
whitespace-nowrap
|
||||
overflow-scroll
|
||||
no-scrollbar
|
||||
w-32
|
||||
"
|
||||
>
|
||||
{{ companyName }}
|
||||
@ -33,57 +35,61 @@
|
||||
@click="$emit('change-db-file')"
|
||||
/>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<div class="mt-1 first:mt-0" v-for="group in groups" :key="group.title">
|
||||
|
||||
<!-- Sidebar Items -->
|
||||
<div class="mt-1 first:mt-0" v-for="group in groups" :key="group.label">
|
||||
<div
|
||||
class="
|
||||
px-3
|
||||
py-2
|
||||
flex
|
||||
items-center
|
||||
rounded-lg
|
||||
cursor-pointer
|
||||
hover:bg-white
|
||||
"
|
||||
:class="isActiveGroup(group) && !group.items ? 'bg-white' : ''"
|
||||
@click="onGroupClick(group)"
|
||||
>
|
||||
<Icon
|
||||
:name="group.icon"
|
||||
:size="group.iconSize || '18'"
|
||||
:height="group.iconHeight"
|
||||
:active="isActiveGroup(group)"
|
||||
/>
|
||||
<div
|
||||
class="ml-2 text-lg text-gray-900"
|
||||
:class="isActiveGroup(group) && !group.items && 'text-blue-500'"
|
||||
>
|
||||
{{ group.label }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Expanded Group -->
|
||||
<div v-if="group.items && isActiveGroup(group)">
|
||||
<div
|
||||
v-for="item in group.items"
|
||||
:key="item.label"
|
||||
class="
|
||||
px-3
|
||||
py-2
|
||||
flex
|
||||
items-center
|
||||
rounded-lg
|
||||
mt-1
|
||||
first:mt-0
|
||||
text-base text-gray-800
|
||||
py-1
|
||||
pl-10
|
||||
rounded
|
||||
cursor-pointer
|
||||
hover:bg-white
|
||||
"
|
||||
:class="isActiveGroup(group) && !group.items ? 'bg-white' : ''"
|
||||
@click="onGroupClick(group)"
|
||||
:class="itemActiveClass(item)"
|
||||
@click="onItemClick(item)"
|
||||
>
|
||||
<Icon
|
||||
:name="group.icon"
|
||||
:size="group.iconSize || '18'"
|
||||
:height="group.iconHeight"
|
||||
:active="isActiveGroup(group)"
|
||||
/>
|
||||
<div
|
||||
class="ml-2 text-lg text-gray-900"
|
||||
:class="isActiveGroup(group) && !group.items && 'text-blue-500'"
|
||||
>
|
||||
{{ group.title }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="group.items && isActiveGroup(group)">
|
||||
<div
|
||||
v-for="item in group.items"
|
||||
:key="item.label"
|
||||
class="
|
||||
mt-1
|
||||
first:mt-0
|
||||
text-base text-gray-800
|
||||
py-1
|
||||
pl-10
|
||||
rounded
|
||||
cursor-pointer
|
||||
hover:bg-white
|
||||
"
|
||||
:class="itemActiveClass(item)"
|
||||
@click="onItemClick(item)"
|
||||
>
|
||||
{{ item.label }}
|
||||
</div>
|
||||
{{ item.label }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Report Issue and App Version -->
|
||||
<div class="px-5 window-no-drag">
|
||||
<button
|
||||
class="pb-1 text-sm text-gray-600 hover:text-gray-800 w-full text-left"
|
||||
@ -97,14 +103,14 @@
|
||||
</template>
|
||||
<script>
|
||||
import path from 'path';
|
||||
import Button from 'src/components/Button';
|
||||
import Button from 'src/components/Button.vue';
|
||||
import { reportIssue } from 'src/errorHandling';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { routeTo } from 'src/utils';
|
||||
import { getSidebarConfig } from 'src/utils/sidebarConfig';
|
||||
import { routeTo } from 'src/utils/ui';
|
||||
import router from '../router';
|
||||
import sidebarConfig from '../sidebarConfig';
|
||||
import Icon from './Icon.vue';
|
||||
import WindowControls from './WindowControls';
|
||||
import WindowControls from './WindowControls.vue';
|
||||
|
||||
export default {
|
||||
components: [Button],
|
||||
@ -130,39 +136,9 @@ export default {
|
||||
Icon,
|
||||
},
|
||||
async mounted() {
|
||||
this.companyName = await sidebarConfig.getTitle();
|
||||
let groups = sidebarConfig.getGroups();
|
||||
groups = groups.filter((group) => {
|
||||
if (
|
||||
group.route === '/get-started' &&
|
||||
fyo.singles.SystemSettings.hideGetStarted
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// use the hidden property in the routes config to show/hide the elements
|
||||
// filter doens't work with async function so using reduce
|
||||
for (let group of groups) {
|
||||
if (group.items) {
|
||||
group.items = await group.items.reduce(async (acc, item) => {
|
||||
if (item.hidden) {
|
||||
// async methods can also be used in future
|
||||
const hidden = item.hidden();
|
||||
if (hidden) {
|
||||
return acc;
|
||||
} else {
|
||||
return (await acc).concat(item);
|
||||
}
|
||||
}
|
||||
|
||||
return (await acc).concat(item);
|
||||
}, []);
|
||||
}
|
||||
}
|
||||
|
||||
this.groups = groups;
|
||||
const { companyName } = await fyo.doc.getSingle('AccountingSettings');
|
||||
this.companyName = companyName;
|
||||
this.groups = getSidebarConfig();
|
||||
|
||||
this.setActiveGroup();
|
||||
router.afterEach(() => {
|
||||
@ -206,7 +182,7 @@ export default {
|
||||
return routeMatch || doctypeMatch ? 'bg-white text-blue-500' : '';
|
||||
},
|
||||
isActiveGroup(group) {
|
||||
return this.activeGroup && group.title === this.activeGroup.title;
|
||||
return this.activeGroup && group.label === this.activeGroup.label;
|
||||
},
|
||||
onGroupClick(group) {
|
||||
if (group.action) {
|
||||
|
@ -19,7 +19,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { runWindowAction } from 'src/utils';
|
||||
import { runWindowAction } from "src/utils/ipcCalls";
|
||||
|
||||
|
||||
export default {
|
||||
name: 'WindowControls',
|
||||
@ -32,10 +33,12 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async action(name) {
|
||||
if (this.buttons.includes(name)) {
|
||||
const actionRan = await runWindowAction(name);
|
||||
this.$emit(actionRan);
|
||||
if (!this.buttons.includes(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const actionRan = await runWindowAction(name);
|
||||
this.$emit(actionRan);
|
||||
},
|
||||
getColorClasses(name) {
|
||||
let classes = {
|
||||
|
@ -1,153 +1,199 @@
|
||||
import { t } from 'fyo';
|
||||
import { fyo } from './initFyo';
|
||||
import { fyo } from '../initFyo';
|
||||
import { SidebarConfig } from './types';
|
||||
|
||||
const config = {
|
||||
getTitle: async () => {
|
||||
const { companyName } = await fyo.doc.getSingle('AccountingSettings');
|
||||
return companyName;
|
||||
},
|
||||
getGroups: () => [
|
||||
export function getSidebarConfig(): SidebarConfig {
|
||||
const sideBar = getCompleteSidebar();
|
||||
return getFilteredSidebar(sideBar);
|
||||
}
|
||||
|
||||
export function getFilteredSidebar(sideBar: SidebarConfig): SidebarConfig {
|
||||
return sideBar.filter((root) => {
|
||||
root.items = root.items?.filter((item) => {
|
||||
if (item.hidden !== undefined) {
|
||||
return !item.hidden();
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (root.hidden !== undefined) {
|
||||
return !root.hidden();
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
function getCompleteSidebar(): SidebarConfig {
|
||||
return [
|
||||
{
|
||||
title: t`Get Started`,
|
||||
label: t`Get Started`,
|
||||
name: 'get-started',
|
||||
route: '/get-started',
|
||||
icon: 'general',
|
||||
iconSize: '24',
|
||||
iconHeight: '5',
|
||||
hidden: () => fyo.singles.SystemSettings!.hideGetStarted as boolean,
|
||||
},
|
||||
{
|
||||
title: t`Dashboard`,
|
||||
label: t`Dashboard`,
|
||||
name: 'dashboard',
|
||||
route: '/',
|
||||
icon: 'dashboard',
|
||||
},
|
||||
{
|
||||
title: t`Sales`,
|
||||
label: t`Sales`,
|
||||
name: 'sales',
|
||||
icon: 'sales',
|
||||
route: '/list/SalesInvoice',
|
||||
items: [
|
||||
{
|
||||
label: t`Invoices`,
|
||||
label: t`Sales Invoices`,
|
||||
name: 'sales-invoices',
|
||||
route: '/list/SalesInvoice',
|
||||
doctype: 'SalesInvoice',
|
||||
},
|
||||
{
|
||||
label: t`Payments`,
|
||||
name: 'payments',
|
||||
route: '/list/Payment/paymentType/Receive',
|
||||
doctype: 'Payment',
|
||||
},
|
||||
{
|
||||
label: t`Customers`,
|
||||
name: 'customers',
|
||||
route: '/list/Customer',
|
||||
doctype: 'Customer',
|
||||
},
|
||||
{
|
||||
label: t`Sales Items`,
|
||||
name: 'sales-items',
|
||||
route: '/list/Item/for/sales',
|
||||
doctype: 'Item',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: t`Purchases`,
|
||||
label: t`Purchases`,
|
||||
name: 'purchases',
|
||||
icon: 'purchase',
|
||||
route: '/list/PurchaseInvoice',
|
||||
items: [
|
||||
{
|
||||
label: t`Bills`,
|
||||
label: t`Purchase Invoices`,
|
||||
name: 'purchase-invoices',
|
||||
route: '/list/PurchaseInvoice',
|
||||
doctype: 'PurchaseInvoice',
|
||||
},
|
||||
{
|
||||
label: t`Payments`,
|
||||
name: 'payments',
|
||||
route: '/list/Payment/paymentType/Pay',
|
||||
doctype: 'Payment',
|
||||
},
|
||||
{
|
||||
label: t`Suppliers`,
|
||||
name: 'suppliers',
|
||||
route: '/list/Supplier',
|
||||
doctype: 'Supplier',
|
||||
},
|
||||
{
|
||||
label: t`Purchase Items`,
|
||||
name: 'purchase-items',
|
||||
route: '/list/Item/for/purchases',
|
||||
doctype: 'Item',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t`Common`,
|
||||
name: 'common-entries',
|
||||
icon: 'common-entries',
|
||||
title: t`Common`,
|
||||
route: '/list/JournalEntry',
|
||||
items: [
|
||||
{
|
||||
label: t`Journal Entry`,
|
||||
name: 'journal-entry',
|
||||
route: '/list/JournalEntry',
|
||||
doctype: 'JournalEntry',
|
||||
},
|
||||
{
|
||||
label: t`Common Items`,
|
||||
name: 'common-items',
|
||||
route: '/list/Item/for/both',
|
||||
doctype: 'Item',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: t`Reports`,
|
||||
label: t`Reports`,
|
||||
name: t`reports`,
|
||||
icon: 'reports',
|
||||
route: '/report/general-ledger',
|
||||
items: [
|
||||
{
|
||||
label: t`General Ledger`,
|
||||
name: 'general-ledger',
|
||||
route: '/report/general-ledger',
|
||||
},
|
||||
{
|
||||
label: t`Profit And Loss`,
|
||||
name: 'profit-and-loss',
|
||||
route: '/report/profit-and-loss',
|
||||
},
|
||||
{
|
||||
label: t`Balance Sheet`,
|
||||
name: 'balance-sheet',
|
||||
route: '/report/balance-sheet',
|
||||
},
|
||||
{
|
||||
label: t`Trial Balance`,
|
||||
name: 'trial-balance',
|
||||
route: '/report/trial-balance',
|
||||
},
|
||||
{
|
||||
label: t`GSTR1`,
|
||||
name: 'gstr1',
|
||||
route: '/report/gstr-1',
|
||||
hidden: () => fyo.singles.AccountingSettings!.country !== 'India',
|
||||
},
|
||||
{
|
||||
label: t`GSTR2`,
|
||||
name: 'gstr2',
|
||||
route: '/report/gstr-2',
|
||||
hidden: () => fyo.singles.AccountingSettings!.country !== 'India',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: t`Setup`,
|
||||
label: t`Setup`,
|
||||
name: t`setup`,
|
||||
icon: 'settings',
|
||||
route: '/chart-of-accounts',
|
||||
items: [
|
||||
{
|
||||
label: t`Chart of Accounts`,
|
||||
name: 'chart-of-accounts',
|
||||
route: '/chart-of-accounts',
|
||||
},
|
||||
{
|
||||
label: t`Taxes`,
|
||||
name: 'taxes',
|
||||
route: '/list/Tax',
|
||||
doctype: 'Tax',
|
||||
},
|
||||
{
|
||||
label: t`Data Import`,
|
||||
name: 'data-import',
|
||||
route: '/data_import',
|
||||
},
|
||||
{
|
||||
label: t`Settings`,
|
||||
name: 'settings',
|
||||
route: '/settings',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
||||
];
|
||||
}
|
@ -26,4 +26,24 @@ export interface QuickEditOptions {
|
||||
hideFields?: string[];
|
||||
showFields?: string[];
|
||||
defaults?: Record<string, unknown>;
|
||||
}
|
||||
}
|
||||
|
||||
export type SidebarConfig = SidebarRoot[];
|
||||
export interface SidebarRoot {
|
||||
label: string;
|
||||
name: string;
|
||||
route: string;
|
||||
icon: string;
|
||||
iconSize?: string;
|
||||
iconHeight?: string;
|
||||
hidden?: () => boolean;
|
||||
items?: SidebarItem[];
|
||||
}
|
||||
|
||||
export interface SidebarItem {
|
||||
label: string;
|
||||
name: string;
|
||||
route: string;
|
||||
doctype?: string;
|
||||
hidden?: () => boolean;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user