mirror of
https://github.com/frappe/books.git
synced 2025-01-23 07:08:36 +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 = {
|
module.exports = {
|
||||||
name: 'AccountingSettings',
|
name: 'AccountingSettings',
|
||||||
@ -27,7 +29,7 @@ module.exports = {
|
|||||||
return {
|
return {
|
||||||
isGroup: 0,
|
isGroup: 0,
|
||||||
rootType: 'Expense'
|
rootType: 'Expense'
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -41,7 +43,7 @@ module.exports = {
|
|||||||
return {
|
return {
|
||||||
isGroup: 0,
|
isGroup: 0,
|
||||||
rootType: 'Expense'
|
rootType: 'Expense'
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -55,7 +57,7 @@ module.exports = {
|
|||||||
|
|
||||||
{
|
{
|
||||||
fieldname: 'currency',
|
fieldname: 'currency',
|
||||||
label: 'Country Currency',
|
label: 'Currency',
|
||||||
fieldtype: 'Data',
|
fieldtype: 'Data',
|
||||||
required: 0
|
required: 0
|
||||||
},
|
},
|
||||||
@ -102,6 +104,6 @@ module.exports = {
|
|||||||
'country',
|
'country',
|
||||||
'currency',
|
'currency',
|
||||||
'fiscalYearStart',
|
'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.metaCache = {};
|
||||||
|
|
||||||
frappe.syncDoc(require('../fixtures/invoicePrint'));
|
|
||||||
|
|
||||||
// init naming series if missing
|
// init naming series if missing
|
||||||
await naming.createNumberSeries('SINV-', 'SalesInvoiceSettings');
|
await naming.createNumberSeries('SINV-', 'SalesInvoiceSettings');
|
||||||
await naming.createNumberSeries('PINV-', 'PurchaseInvoiceSettings');
|
await naming.createNumberSeries('PINV-', 'PurchaseInvoiceSettings');
|
||||||
@ -27,10 +25,10 @@ module.exports = async function postStart() {
|
|||||||
await naming.createNumberSeries('PREC-', 'PurchaseReceiptSettings');
|
await naming.createNumberSeries('PREC-', 'PurchaseReceiptSettings');
|
||||||
|
|
||||||
// fetch singles
|
// fetch singles
|
||||||
// these will be available as
|
// so that they are available synchronously
|
||||||
// frappe.SystemSettings and frappe.AccountingSettings
|
|
||||||
await frappe.getSingle('SystemSettings');
|
await frappe.getSingle('SystemSettings');
|
||||||
await frappe.getSingle('AccountingSettings');
|
await frappe.getSingle('AccountingSettings');
|
||||||
|
await frappe.getSingle('GetStarted');
|
||||||
|
|
||||||
// cache currency symbols for frappe.format
|
// cache currency symbols for frappe.format
|
||||||
frappe.currencySymbols = await getCurrencySymbols();
|
frappe.currencySymbols = await getCurrencySymbols();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<button
|
<button
|
||||||
class="focus:outline-none rounded-md shadow-button"
|
class="focus:outline-none rounded-md shadow-button flex-center"
|
||||||
:style="style"
|
:style="style"
|
||||||
:class="_class"
|
:class="_class"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
@ -16,7 +16,7 @@ requireComponent.keys().forEach(fileName => {
|
|||||||
const componentConfig = requireComponent(fileName);
|
const componentConfig = requireComponent(fileName);
|
||||||
|
|
||||||
let match = fileName.match(/\.\/(\d+)\/((\w|-)+).vue/);
|
let match = fileName.match(/\.\/(\d+)\/((\w|-)+).vue/);
|
||||||
let [_, size, name] = match || [];
|
let [, size, name] = match || [];
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
components[size] = components[size] || {};
|
components[size] = components[size] || {};
|
||||||
@ -26,7 +26,7 @@ requireComponent.keys().forEach(fileName => {
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Icon',
|
name: 'Icon',
|
||||||
props: ['size', 'name', 'active'],
|
props: ['name', 'active', 'size', 'height'],
|
||||||
computed: {
|
computed: {
|
||||||
iconComponent() {
|
iconComponent() {
|
||||||
try {
|
try {
|
||||||
@ -44,6 +44,10 @@ export default {
|
|||||||
'24': 'w-6 h-6'
|
'24': 'w-6 h-6'
|
||||||
}[this.size];
|
}[this.size];
|
||||||
|
|
||||||
|
if (this.height) {
|
||||||
|
sizeClass = `w-${this.height} h-${this.height}`;
|
||||||
|
}
|
||||||
|
|
||||||
return [sizeClass, 'fill-current'];
|
return [sizeClass, 'fill-current'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
<div class="window-no-drag">
|
<div class="window-no-drag">
|
||||||
<WindowControls v-if="platform === 'Mac'" class="px-3 mb-6" />
|
<WindowControls v-if="platform === 'Mac'" class="px-3 mb-6" />
|
||||||
<div class="px-3">
|
<div class="px-3">
|
||||||
<h6 class="text-base font-semibold" @click="$router.push('/')">
|
<h6 class="text-lg font-semibold" @click="$router.push('/')">
|
||||||
{{ companyName }}
|
{{ companyName }}
|
||||||
</h6>
|
</h6>
|
||||||
</div>
|
</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="mt-1 first:mt-0" v-for="group in groups" :key="group.title">
|
||||||
<div
|
<div
|
||||||
class="px-3 py-2 flex items-center rounded-lg cursor-pointer hover:bg-white"
|
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 Vue from 'vue';
|
||||||
import Router from 'vue-router';
|
import Router from 'vue-router';
|
||||||
|
|
||||||
import ListView from '@/pages/ListView/ListView';
|
// standard views
|
||||||
import Dashboard from '@/pages/Dashboard/Dashboard';
|
import Dashboard from '@/pages/Dashboard/Dashboard';
|
||||||
|
import ListView from '@/pages/ListView/ListView';
|
||||||
import PrintView from '@/pages/PrintView/PrintView';
|
import PrintView from '@/pages/PrintView/PrintView';
|
||||||
import QuickEditForm from '@/pages/QuickEditForm';
|
import QuickEditForm from '@/pages/QuickEditForm';
|
||||||
|
|
||||||
import Report from '@/pages/Report.vue';
|
import Report from '@/pages/Report.vue';
|
||||||
|
|
||||||
|
// custom views
|
||||||
|
import GetStarted from '@/pages/GetStarted';
|
||||||
import ChartOfAccounts from '@/pages/ChartOfAccounts';
|
import ChartOfAccounts from '@/pages/ChartOfAccounts';
|
||||||
|
|
||||||
import InvoiceForm from '@/pages/InvoiceForm';
|
import InvoiceForm from '@/pages/InvoiceForm';
|
||||||
import JournalEntryForm from '@/pages/JournalEntryForm';
|
import JournalEntryForm from '@/pages/JournalEntryForm';
|
||||||
|
|
||||||
|
|
||||||
Vue.use(Router);
|
Vue.use(Router);
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
@ -21,6 +21,10 @@ const routes = [
|
|||||||
path: '/',
|
path: '/',
|
||||||
component: Dashboard
|
component: Dashboard
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/get-started',
|
||||||
|
component: GetStarted
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/edit/JournalEntry/:name',
|
path: '/edit/JournalEntry/:name',
|
||||||
name: 'JournalEntryForm',
|
name: 'JournalEntryForm',
|
||||||
@ -29,7 +33,14 @@ const routes = [
|
|||||||
edit: QuickEditForm
|
edit: QuickEditForm
|
||||||
},
|
},
|
||||||
props: {
|
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
|
edit: route => route.query
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -10,6 +10,11 @@ const config = {
|
|||||||
return companyName;
|
return companyName;
|
||||||
},
|
},
|
||||||
groups: [
|
groups: [
|
||||||
|
{
|
||||||
|
title: _('Get Started'),
|
||||||
|
route: '/get-started',
|
||||||
|
icon: getIcon('general', '24', '5')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: _('Dashboard'),
|
title: _('Dashboard'),
|
||||||
route: '/',
|
route: '/',
|
||||||
@ -118,15 +123,19 @@ const config = {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
function getIcon(name) {
|
function getIcon(name, size = '18', height = null) {
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
render(h) {
|
render(h) {
|
||||||
return h(Icon, {
|
return h(Icon, {
|
||||||
props: Object.assign({
|
props: Object.assign(
|
||||||
name,
|
{
|
||||||
size: '18',
|
name,
|
||||||
}, this.$attrs)
|
size,
|
||||||
|
height
|
||||||
|
},
|
||||||
|
this.$attrs
|
||||||
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user