2
0
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:
Faris Ansari 2019-12-21 20:16:50 +05:30
parent c9d0219320
commit 86d841da7a
9 changed files with 261 additions and 24 deletions

View File

@ -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'
]
};

View 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'
}
]
};

View File

@ -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();

View File

@ -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"

View File

@ -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'];
}
}

View File

@ -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
View 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>

View File

@ -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
}
},

View File

@ -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
)
});
}
};