mirror of
https://github.com/frappe/books.git
synced 2024-11-09 23:30:56 +00:00
feat: Add GetStarted page
- GetStarted model to track progress
This commit is contained in:
parent
c9d0219320
commit
86d841da7a
@ -1,4 +1,6 @@
|
||||
const countryList = Object.keys(require('../../../fixtures/countryInfo.json')).sort();
|
||||
const countryList = Object.keys(
|
||||
require('../../../fixtures/countryInfo.json')
|
||||
).sort();
|
||||
|
||||
module.exports = {
|
||||
name: 'AccountingSettings',
|
||||
@ -27,7 +29,7 @@ module.exports = {
|
||||
return {
|
||||
isGroup: 0,
|
||||
rootType: 'Expense'
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
@ -41,7 +43,7 @@ module.exports = {
|
||||
return {
|
||||
isGroup: 0,
|
||||
rootType: 'Expense'
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
@ -55,7 +57,7 @@ module.exports = {
|
||||
|
||||
{
|
||||
fieldname: 'currency',
|
||||
label: 'Country Currency',
|
||||
label: 'Currency',
|
||||
fieldtype: 'Data',
|
||||
required: 0
|
||||
},
|
||||
@ -102,6 +104,6 @@ module.exports = {
|
||||
'country',
|
||||
'currency',
|
||||
'fiscalYearStart',
|
||||
'fiscalYearEnd',
|
||||
'fiscalYearEnd'
|
||||
]
|
||||
};
|
||||
|
17
models/doctype/GetStarted/GetStarted.js
Normal file
17
models/doctype/GetStarted/GetStarted.js
Normal file
@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
name: 'GetStarted',
|
||||
isSingle: 1,
|
||||
fields: [
|
||||
{
|
||||
fieldname: 'needOnboarding',
|
||||
label: 'Need Onboarding',
|
||||
fieldtype: 'Check',
|
||||
default: 1
|
||||
},
|
||||
{
|
||||
fieldname: 'salesItemCreated',
|
||||
label: 'Sales Item Created',
|
||||
fieldtype: 'Check'
|
||||
}
|
||||
]
|
||||
};
|
@ -13,8 +13,6 @@ module.exports = async function postStart() {
|
||||
|
||||
frappe.metaCache = {};
|
||||
|
||||
frappe.syncDoc(require('../fixtures/invoicePrint'));
|
||||
|
||||
// init naming series if missing
|
||||
await naming.createNumberSeries('SINV-', 'SalesInvoiceSettings');
|
||||
await naming.createNumberSeries('PINV-', 'PurchaseInvoiceSettings');
|
||||
@ -27,10 +25,10 @@ module.exports = async function postStart() {
|
||||
await naming.createNumberSeries('PREC-', 'PurchaseReceiptSettings');
|
||||
|
||||
// fetch singles
|
||||
// these will be available as
|
||||
// frappe.SystemSettings and frappe.AccountingSettings
|
||||
// so that they are available synchronously
|
||||
await frappe.getSingle('SystemSettings');
|
||||
await frappe.getSingle('AccountingSettings');
|
||||
await frappe.getSingle('GetStarted');
|
||||
|
||||
// cache currency symbols for frappe.format
|
||||
frappe.currencySymbols = await getCurrencySymbols();
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<button
|
||||
class="focus:outline-none rounded-md shadow-button"
|
||||
class="focus:outline-none rounded-md shadow-button flex-center"
|
||||
:style="style"
|
||||
:class="_class"
|
||||
v-bind="$attrs"
|
||||
|
@ -16,7 +16,7 @@ requireComponent.keys().forEach(fileName => {
|
||||
const componentConfig = requireComponent(fileName);
|
||||
|
||||
let match = fileName.match(/\.\/(\d+)\/((\w|-)+).vue/);
|
||||
let [_, size, name] = match || [];
|
||||
let [, size, name] = match || [];
|
||||
|
||||
if (name) {
|
||||
components[size] = components[size] || {};
|
||||
@ -26,7 +26,7 @@ requireComponent.keys().forEach(fileName => {
|
||||
|
||||
export default {
|
||||
name: 'Icon',
|
||||
props: ['size', 'name', 'active'],
|
||||
props: ['name', 'active', 'size', 'height'],
|
||||
computed: {
|
||||
iconComponent() {
|
||||
try {
|
||||
@ -44,6 +44,10 @@ export default {
|
||||
'24': 'w-6 h-6'
|
||||
}[this.size];
|
||||
|
||||
if (this.height) {
|
||||
sizeClass = `w-${this.height} h-${this.height}`;
|
||||
}
|
||||
|
||||
return [sizeClass, 'fill-current'];
|
||||
}
|
||||
}
|
||||
|
@ -6,11 +6,11 @@
|
||||
<div class="window-no-drag">
|
||||
<WindowControls v-if="platform === 'Mac'" class="px-3 mb-6" />
|
||||
<div class="px-3">
|
||||
<h6 class="text-base font-semibold" @click="$router.push('/')">
|
||||
<h6 class="text-lg font-semibold" @click="$router.push('/')">
|
||||
{{ companyName }}
|
||||
</h6>
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
<div class="mt-3">
|
||||
<div class="mt-1 first:mt-0" v-for="group in groups" :key="group.title">
|
||||
<div
|
||||
class="px-3 py-2 flex items-center rounded-lg cursor-pointer hover:bg-white"
|
||||
|
196
src/pages/GetStarted.vue
Normal file
196
src/pages/GetStarted.vue
Normal file
@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<div>
|
||||
<PageHeader>
|
||||
<h1 slot="title" class="text-2xl font-bold">
|
||||
{{ _('Setup your workspace') }}
|
||||
</h1>
|
||||
</PageHeader>
|
||||
<div class="px-8 mt-4">
|
||||
<div class="border-t"></div>
|
||||
<div class="mt-6" v-for="section in sections" :key="section.label">
|
||||
<h2 class="font-medium">{{ section.label }}</h2>
|
||||
<div class="mt-4 flex -mx-2">
|
||||
<div
|
||||
class="w-1/3 px-2"
|
||||
v-for="item in section.items"
|
||||
:key="item.label"
|
||||
>
|
||||
<div
|
||||
class="flex flex-col justify-between border rounded-lg p-6 h-full hover:shadow-md cursor-pointer"
|
||||
@mouseenter="() => (item.showActions = true)"
|
||||
@mouseleave="() => (item.showActions = false)"
|
||||
>
|
||||
<div>
|
||||
<component
|
||||
v-show="!item.showActions"
|
||||
:is="getIconComponent(item.icon)"
|
||||
class="mb-4"
|
||||
/>
|
||||
<h3 class="font-medium">{{ item.label }}</h3>
|
||||
<p class="mt-2 text-sm text-gray-800">
|
||||
{{ item.description }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-2 flex" v-show="item.showActions">
|
||||
<Button class="leading-tight" type="primary">
|
||||
<span class="text-white text-base">
|
||||
{{ _('Setup') }}
|
||||
</span>
|
||||
</Button>
|
||||
<Button class="ml-4 leading-tight">
|
||||
<span class="text-base">
|
||||
{{ _('Documentation') }}
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PageHeader from '@/components/PageHeader';
|
||||
import Icon from '@/components/Icon';
|
||||
import Button from '@/components/Button';
|
||||
|
||||
export default {
|
||||
name: 'GetStarted',
|
||||
components: {
|
||||
PageHeader,
|
||||
Button
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sections: [
|
||||
{
|
||||
label: 'Organisation',
|
||||
|
||||
items: [
|
||||
{
|
||||
label: 'General',
|
||||
icon: 'general',
|
||||
description:
|
||||
'Setup your company information, email, country and fiscal year',
|
||||
showActions: false
|
||||
},
|
||||
{
|
||||
label: 'System',
|
||||
icon: 'general',
|
||||
description:
|
||||
'Setup system defaults like date format and currency precision',
|
||||
showActions: false
|
||||
},
|
||||
{
|
||||
label: 'Invoice',
|
||||
icon: 'invoice',
|
||||
description:
|
||||
'Customize your invoices by adding a logo and company address',
|
||||
showActions: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Accounts',
|
||||
|
||||
items: [
|
||||
{
|
||||
label: 'Review Accounts',
|
||||
icon: 'review-ac',
|
||||
description:
|
||||
'Review your chart of accounts, add any account or tax heads as needed',
|
||||
showActions: false
|
||||
},
|
||||
{
|
||||
label: 'Opening Balances',
|
||||
icon: 'opening-ac',
|
||||
description:
|
||||
'Setup your opening balances before performing any accounting entries',
|
||||
showActions: false
|
||||
},
|
||||
{
|
||||
label: 'Add Taxes',
|
||||
icon: 'percentage',
|
||||
description:
|
||||
'Setup your tax templates for your sales or purchase transactions',
|
||||
showActions: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Sales',
|
||||
|
||||
items: [
|
||||
{
|
||||
label: 'Add Items',
|
||||
icon: 'item',
|
||||
description:
|
||||
'Add products or services that you sell to your customers',
|
||||
showActions: false
|
||||
},
|
||||
{
|
||||
label: 'Add Customers',
|
||||
icon: 'customer',
|
||||
description: 'Add a few customers to create your first invoice',
|
||||
showActions: false
|
||||
},
|
||||
{
|
||||
label: 'Create Invoice',
|
||||
icon: 'sales-invoice',
|
||||
description:
|
||||
'Create your first invoice and mail it to your customer',
|
||||
showActions: false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Purchase',
|
||||
|
||||
items: [
|
||||
{
|
||||
label: 'Add Items',
|
||||
icon: 'item',
|
||||
description:
|
||||
'Add products or services that you buy from your suppliers',
|
||||
showActions: false
|
||||
},
|
||||
{
|
||||
label: 'Add Suppliers',
|
||||
icon: 'supplier',
|
||||
description: 'Add a few suppliers to create your first bill',
|
||||
showActions: false
|
||||
},
|
||||
{
|
||||
label: 'Create Bill',
|
||||
icon: 'purchase-invoice',
|
||||
description:
|
||||
'Create your first bill and mail it to your supplier',
|
||||
showActions: false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getIconComponent(name) {
|
||||
return {
|
||||
name,
|
||||
render(h) {
|
||||
return h(Icon, {
|
||||
props: Object.assign(
|
||||
{
|
||||
name,
|
||||
size: '18'
|
||||
},
|
||||
this.$attrs
|
||||
)
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -1,19 +1,19 @@
|
||||
import Vue from 'vue';
|
||||
import Router from 'vue-router';
|
||||
|
||||
import ListView from '@/pages/ListView/ListView';
|
||||
// standard views
|
||||
import Dashboard from '@/pages/Dashboard/Dashboard';
|
||||
import ListView from '@/pages/ListView/ListView';
|
||||
import PrintView from '@/pages/PrintView/PrintView';
|
||||
import QuickEditForm from '@/pages/QuickEditForm';
|
||||
|
||||
import Report from '@/pages/Report.vue';
|
||||
|
||||
// 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 = [
|
||||
@ -21,6 +21,10 @@ const routes = [
|
||||
path: '/',
|
||||
component: Dashboard
|
||||
},
|
||||
{
|
||||
path: '/get-started',
|
||||
component: GetStarted
|
||||
},
|
||||
{
|
||||
path: '/edit/JournalEntry/:name',
|
||||
name: 'JournalEntryForm',
|
||||
@ -29,7 +33,14 @@ const routes = [
|
||||
edit: QuickEditForm
|
||||
},
|
||||
props: {
|
||||
default: true,
|
||||
default: route => {
|
||||
// for sidebar item active state
|
||||
route.params.doctype = 'JournalEntry';
|
||||
return {
|
||||
doctype: 'JournalEntry',
|
||||
name: route.params.name
|
||||
};
|
||||
},
|
||||
edit: route => route.query
|
||||
}
|
||||
},
|
||||
|
@ -10,6 +10,11 @@ const config = {
|
||||
return companyName;
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
title: _('Get Started'),
|
||||
route: '/get-started',
|
||||
icon: getIcon('general', '24', '5')
|
||||
},
|
||||
{
|
||||
title: _('Dashboard'),
|
||||
route: '/',
|
||||
@ -118,15 +123,19 @@ const config = {
|
||||
]
|
||||
};
|
||||
|
||||
function getIcon(name) {
|
||||
function getIcon(name, size = '18', height = null) {
|
||||
return {
|
||||
name,
|
||||
render(h) {
|
||||
return h(Icon, {
|
||||
props: Object.assign({
|
||||
name,
|
||||
size: '18',
|
||||
}, this.$attrs)
|
||||
props: Object.assign(
|
||||
{
|
||||
name,
|
||||
size,
|
||||
height
|
||||
},
|
||||
this.$attrs
|
||||
)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user