mirror of
https://github.com/frappe/books.git
synced 2025-01-22 22:58:28 +00:00
fix(ui): use common form like ui for setup wizard
This commit is contained in:
parent
f94ae5c2d2
commit
703b1d2138
@ -8,18 +8,20 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "logo",
|
"fieldname": "logo",
|
||||||
"label": "Company Logo",
|
"label": "Company Logo",
|
||||||
"fieldtype": "AttachImage"
|
"fieldtype": "AttachImage",
|
||||||
|
"section": "Default"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "country",
|
"fieldname": "companyName",
|
||||||
"label": "Country",
|
"label": "Company Name",
|
||||||
"fieldtype": "AutoComplete",
|
"placeholder": "Company Name",
|
||||||
"placeholder": "Select Country",
|
"fieldtype": "Data",
|
||||||
"required": true
|
"required": true,
|
||||||
|
"section": "Default"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "fullname",
|
"fieldname": "fullname",
|
||||||
"label": "Your Name",
|
"label": "Full Name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"placeholder": "John Doe",
|
"placeholder": "John Doe",
|
||||||
"required": true
|
"required": true
|
||||||
@ -32,31 +34,11 @@
|
|||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "companyName",
|
"fieldname": "country",
|
||||||
"label": "Company Name",
|
"label": "Country",
|
||||||
"placeholder": "Company Name",
|
"fieldtype": "AutoComplete",
|
||||||
"fieldtype": "Data",
|
"placeholder": "Select Country",
|
||||||
"required": true
|
"section": "Locale",
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "bankName",
|
|
||||||
"label": "Bank Name",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"placeholder": "Prime Bank",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "fiscalYearStart",
|
|
||||||
"label": "Fiscal Year Start Date",
|
|
||||||
"placeholder": "Fiscal Year Start Date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "fiscalYearEnd",
|
|
||||||
"label": "Fiscal Year End Date",
|
|
||||||
"placeholder": "Fiscal Year End Date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -64,6 +46,15 @@
|
|||||||
"label": "Currency",
|
"label": "Currency",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"placeholder": "Currency",
|
"placeholder": "Currency",
|
||||||
|
"section": "Locale",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "bankName",
|
||||||
|
"label": "Bank Name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"placeholder": "Prime Bank",
|
||||||
|
"section": "Accounting",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -71,12 +62,30 @@
|
|||||||
"label": "Chart of Accounts",
|
"label": "Chart of Accounts",
|
||||||
"fieldtype": "AutoComplete",
|
"fieldtype": "AutoComplete",
|
||||||
"placeholder": "Select CoA",
|
"placeholder": "Select CoA",
|
||||||
|
"section": "Accounting",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "fiscalYearStart",
|
||||||
|
"label": "Fiscal Year Start Date",
|
||||||
|
"placeholder": "Fiscal Year Start Date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"section": "Accounting",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "fiscalYearEnd",
|
||||||
|
"label": "Fiscal Year End Date",
|
||||||
|
"placeholder": "Fiscal Year End Date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"section": "Accounting",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "completed",
|
"fieldname": "completed",
|
||||||
"label": "Completed",
|
"label": "Completed",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
|
"hidden": true,
|
||||||
"readOnly": true
|
"readOnly": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
'w-20 h-20': size !== 'small',
|
'w-20 h-20': size !== 'small',
|
||||||
'w-12 h-12': size === 'small',
|
'w-12 h-12': size === 'small',
|
||||||
}"
|
}"
|
||||||
|
:title="df?.label"
|
||||||
>
|
>
|
||||||
<img :src="value" v-if="value" />
|
<img :src="value" v-if="value" />
|
||||||
<div :class="[!isReadOnly ? 'group-hover:opacity-90' : '']" v-else>
|
<div :class="[!isReadOnly ? 'group-hover:opacity-90' : '']" v-else>
|
||||||
@ -60,10 +61,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { Field } from 'schemas/types';
|
||||||
import { fyo } from 'src/initFyo';
|
import { fyo } from 'src/initFyo';
|
||||||
import { selectFile } from 'src/utils/ipcCalls';
|
import { selectFile } from 'src/utils/ipcCalls';
|
||||||
import { getDataURL } from 'src/utils/misc';
|
import { getDataURL } from 'src/utils/misc';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import FeatherIcon from '../FeatherIcon.vue';
|
import FeatherIcon from '../FeatherIcon.vue';
|
||||||
import Base from './Base.vue';
|
import Base from './Base.vue';
|
||||||
|
|
||||||
@ -73,6 +75,7 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
letterPlaceholder: { type: String, default: '' },
|
letterPlaceholder: { type: String, default: '' },
|
||||||
value: { type: String, default: '' },
|
value: { type: String, default: '' },
|
||||||
|
df: { type: Object as PropType<Field> },
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async handleClick() {
|
async handleClick() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div :title="df.label">
|
||||||
<div :class="labelClasses" v-if="showLabel">
|
<div :class="labelClasses" v-if="showLabel">
|
||||||
{{ df.label }}
|
{{ df.label }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,12 @@
|
|||||||
<div class="flex bg-gray-25 overflow-x-auto">
|
<div class="flex bg-gray-25 overflow-x-auto">
|
||||||
<div class="flex flex-1 flex-col">
|
<div class="flex flex-1 flex-col">
|
||||||
<!-- Page Header (Title, Buttons, etc) -->
|
<!-- Page Header (Title, Buttons, etc) -->
|
||||||
<PageHeader :title="title" :border="false" :searchborder="searchborder">
|
<PageHeader
|
||||||
|
v-if="showHeader"
|
||||||
|
:title="title"
|
||||||
|
:border="false"
|
||||||
|
:searchborder="searchborder"
|
||||||
|
>
|
||||||
<template #left>
|
<template #left>
|
||||||
<slot name="header-left" />
|
<slot name="header-left" />
|
||||||
</template>
|
</template>
|
||||||
@ -32,13 +37,16 @@
|
|||||||
<slot name="quickedit" />
|
<slot name="quickedit" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
import PageHeader from './PageHeader.vue';
|
import PageHeader from './PageHeader.vue';
|
||||||
export default {
|
|
||||||
|
export default defineComponent({
|
||||||
components: { PageHeader },
|
components: { PageHeader },
|
||||||
props: {
|
props: {
|
||||||
title: { type: String, default: '' },
|
title: { type: String, default: '' },
|
||||||
|
showHeader: { type: Boolean, default: true },
|
||||||
searchborder: { type: Boolean, default: true },
|
searchborder: { type: Boolean, default: true },
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -151,7 +151,7 @@ export default defineComponent({
|
|||||||
return {
|
return {
|
||||||
errors: {},
|
errors: {},
|
||||||
docOrNull: null,
|
docOrNull: null,
|
||||||
activeTab: 'Default',
|
activeTab: this.t`Default`,
|
||||||
groupedFields: null,
|
groupedFields: null,
|
||||||
quickEditDoc: null,
|
quickEditDoc: null,
|
||||||
isPrintable: false,
|
isPrintable: false,
|
||||||
@ -173,6 +173,9 @@ export default defineComponent({
|
|||||||
await this.setDoc();
|
await this.setDoc();
|
||||||
focusedDocsRef.add(this.docOrNull);
|
focusedDocsRef.add(this.docOrNull);
|
||||||
this.updateGroupedFields();
|
this.updateGroupedFields();
|
||||||
|
if (this.groupedFields) {
|
||||||
|
this.activeTab = [...this.groupedFields.keys()][0];
|
||||||
|
}
|
||||||
this.isPrintable = await isPrintable(this.schemaName);
|
this.isPrintable = await isPrintable(this.schemaName);
|
||||||
},
|
},
|
||||||
activated(): void {
|
activated(): void {
|
||||||
|
@ -2,14 +2,15 @@
|
|||||||
<div v-if="(fields ?? []).length > 0">
|
<div v-if="(fields ?? []).length > 0">
|
||||||
<div
|
<div
|
||||||
v-if="showTitle && title"
|
v-if="showTitle && title"
|
||||||
class="flex justify-between items-center cursor-pointer select-none"
|
class="flex justify-between items-center select-none"
|
||||||
:class="collapsed ? '' : 'mb-4'"
|
:class="[collapsed ? '' : 'mb-4', collapsible ? 'cursor-pointer' : '']"
|
||||||
@click="collapsed = !collapsed"
|
@click="toggleCollapsed"
|
||||||
>
|
>
|
||||||
<h2 class="text-base text-gray-900 font-semibold">
|
<h2 class="text-base text-gray-900 font-semibold">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</h2>
|
</h2>
|
||||||
<feather-icon
|
<feather-icon
|
||||||
|
v-if="collapsible"
|
||||||
:name="collapsed ? 'chevron-up' : 'chevron-down'"
|
:name="collapsed ? 'chevron-up' : 'chevron-down'"
|
||||||
class="w-4 h-4 text-gray-600"
|
class="w-4 h-4 text-gray-600"
|
||||||
/>
|
/>
|
||||||
@ -54,6 +55,7 @@ export default defineComponent({
|
|||||||
errors: Object as PropType<Record<string, string>>,
|
errors: Object as PropType<Record<string, string>>,
|
||||||
showTitle: Boolean,
|
showTitle: Boolean,
|
||||||
doc: { type: Object as PropType<Doc>, required: true },
|
doc: { type: Object as PropType<Doc>, required: true },
|
||||||
|
collapsible: { type: Boolean, default: true },
|
||||||
fields: Array as PropType<Field[]>,
|
fields: Array as PropType<Field[]>,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@ -64,6 +66,15 @@ export default defineComponent({
|
|||||||
mounted() {
|
mounted() {
|
||||||
focusOrSelectFormControl(this.doc, this.$refs.nameField);
|
focusOrSelectFormControl(this.doc, this.$refs.nameField);
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
toggleCollapsed() {
|
||||||
|
if (!this.collapsible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.collapsed = !this.collapsed;
|
||||||
|
},
|
||||||
|
},
|
||||||
components: { FormControl },
|
components: { FormControl },
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,146 +1,161 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<FormContainer
|
||||||
class="flex-1 bg-gray-25 flex justify-center items-center"
|
:show-header="false"
|
||||||
|
class="justify-content items-center h-full"
|
||||||
:class="{ 'window-drag': platform !== 'Windows' }"
|
:class="{ 'window-drag': platform !== 'Windows' }"
|
||||||
>
|
>
|
||||||
<!-- Setup Wizard Slide -->
|
<template #body>
|
||||||
<Slide
|
<FormHeader
|
||||||
:primary-disabled="!valuesFilled || loading"
|
:form-title="t`Set up your organization`"
|
||||||
:secondary-disabled="loading"
|
class="sticky top-0 bg-white border-b"
|
||||||
@primary-clicked="submit()"
|
>
|
||||||
@secondary-clicked="$emit('setup-canceled')"
|
</FormHeader>
|
||||||
:class="{ 'window-no-drag': platform !== 'Windows' }"
|
|
||||||
>
|
|
||||||
<template #title>
|
|
||||||
{{ t`Set up your organization` }}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #content>
|
<!-- Section Container -->
|
||||||
<div v-if="doc">
|
<div class="overflow-auto custom-scroll" v-if="hasDoc">
|
||||||
<!-- Image Section -->
|
<CommonFormSection
|
||||||
<div class="flex items-center p-4 gap-4">
|
v-for="([name, fields], idx) in activeGroup.entries()"
|
||||||
<FormControl
|
:key="name + idx"
|
||||||
:df="getField('logo')"
|
ref="section"
|
||||||
:value="doc.logo"
|
class="p-4"
|
||||||
:read-only="loading"
|
:class="idx !== 0 && activeGroup.size > 1 ? 'border-t' : ''"
|
||||||
@change="(value) => setValue('logo', value)"
|
:show-title="activeGroup.size > 1 && name !== t`Default`"
|
||||||
/>
|
:title="name"
|
||||||
<div>
|
:fields="fields"
|
||||||
<FormControl
|
:doc="doc"
|
||||||
ref="companyField"
|
:errors="errors"
|
||||||
:df="getField('companyName')"
|
:collapsible="false"
|
||||||
:value="doc.companyName"
|
@value-change="onValueChange"
|
||||||
:read-only="loading"
|
/>
|
||||||
@change="(value) => setValue('companyName', value)"
|
</div>
|
||||||
input-class="
|
|
||||||
font-semibold
|
|
||||||
text-xl
|
|
||||||
"
|
|
||||||
:autofocus="true"
|
|
||||||
/>
|
|
||||||
<FormControl
|
|
||||||
:df="getField('email')"
|
|
||||||
:value="doc.email"
|
|
||||||
:read-only="loading"
|
|
||||||
@change="(value) => setValue('email', value)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p
|
<!-- Buttons Bar -->
|
||||||
class="-mt-6 text-sm absolute text-red-400 w-full"
|
<div
|
||||||
style="left: 7.75rem"
|
class="
|
||||||
v-if="emailError"
|
mt-auto
|
||||||
>
|
p-4
|
||||||
{{ emailError }}
|
flex
|
||||||
</p>
|
items-center
|
||||||
|
justify-between
|
||||||
<TwoColumnForm :doc="doc" :read-only="loading" />
|
border-t
|
||||||
<Button
|
flex-shrink-0
|
||||||
v-if="fyo.store.isDevelopment"
|
sticky
|
||||||
class="m-4 text-sm min-w-28"
|
bottom-0
|
||||||
@click="fill"
|
bg-white
|
||||||
>Fill</Button
|
"
|
||||||
>
|
>
|
||||||
</div>
|
<p v-if="loading" class="text-base text-gray-600">
|
||||||
</template>
|
{{ t`Loading instance...` }}
|
||||||
<template #secondaryButton>{{ t`Cancel` }}</template>
|
</p>
|
||||||
<template #primaryButton>{{
|
<Button v-if="!loading" class="w-24" @click="$emit('setup-canceled')">{{
|
||||||
loading ? t`Setting up...` : t`Submit`
|
t`Cancel`
|
||||||
}}</template>
|
}}</Button>
|
||||||
</Slide>
|
<Button
|
||||||
</div>
|
v-if="fyo.store.isDevelopment && !loading"
|
||||||
|
class="w-24 ml-auto mr-4"
|
||||||
|
:disabled="loading"
|
||||||
|
@click="fill"
|
||||||
|
>Fill</Button
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
class="w-24"
|
||||||
|
:disabled="!areAllValuesFilled || loading"
|
||||||
|
@click="submit"
|
||||||
|
>{{ t`Submit` }}</Button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</FormContainer>
|
||||||
</template>
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
<script>
|
import { DocValue } from 'fyo/core/types';
|
||||||
|
import { Doc } from 'fyo/model/doc';
|
||||||
|
import { ValidationError } from 'fyo/utils/errors';
|
||||||
|
import { Field } from 'schemas/types';
|
||||||
import Button from 'src/components/Button.vue';
|
import Button from 'src/components/Button.vue';
|
||||||
import FormControl from 'src/components/Controls/FormControl.vue';
|
import FormContainer from 'src/components/FormContainer.vue';
|
||||||
import TwoColumnForm from 'src/components/TwoColumnForm.vue';
|
import FormHeader from 'src/components/FormHeader.vue';
|
||||||
import { getErrorMessage } from 'src/utils';
|
import { getErrorMessage } from 'src/utils';
|
||||||
import { getSetupWizardDoc } from 'src/utils/misc';
|
import { getSetupWizardDoc } from 'src/utils/misc';
|
||||||
import { showMessageDialog } from 'src/utils/ui';
|
import {
|
||||||
import Slide from './Slide.vue';
|
getFieldsGroupedByTabAndSection,
|
||||||
|
showMessageDialog,
|
||||||
|
} from 'src/utils/ui';
|
||||||
|
import { computed, defineComponent } from 'vue';
|
||||||
|
import CommonFormSection from '../CommonForm/CommonFormSection.vue';
|
||||||
|
|
||||||
export default {
|
export default defineComponent({
|
||||||
name: 'SetupWizard',
|
name: 'SetupWizard',
|
||||||
emits: ['setup-complete', 'setup-canceled'],
|
emits: ['setup-complete', 'setup-canceled'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
doc: null,
|
docOrNull: null,
|
||||||
|
errors: {},
|
||||||
loading: false,
|
loading: false,
|
||||||
valuesFilled: false,
|
} as {
|
||||||
emailError: null,
|
errors: Record<string, string>;
|
||||||
|
docOrNull: null | Doc;
|
||||||
|
loading: boolean;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
provide() {
|
provide() {
|
||||||
return {
|
return {
|
||||||
schemaName: 'SetupWizard',
|
schemaName: computed(() => this.docOrNull?.schemaName),
|
||||||
name: 'SetupWizard',
|
name: computed(() => this.docOrNull?.name),
|
||||||
|
doc: computed(() => this.docOrNull),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
TwoColumnForm,
|
|
||||||
FormControl,
|
|
||||||
Slide,
|
|
||||||
Button,
|
Button,
|
||||||
|
FormContainer,
|
||||||
|
FormHeader,
|
||||||
|
CommonFormSection,
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
this.doc = await getSetupWizardDoc();
|
this.docOrNull = getSetupWizardDoc();
|
||||||
this.doc.on('change', () => {
|
|
||||||
this.valuesFilled = this.allValuesFilled();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this.fyo.store.isDevelopment) {
|
if (this.fyo.store.isDevelopment) {
|
||||||
|
// @ts-ignore
|
||||||
window.sw = this;
|
window.sw = this;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fill() {
|
async fill() {
|
||||||
|
if (!this.hasDoc) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await this.doc.set('companyName', "Lin's Things");
|
await this.doc.set('companyName', "Lin's Things");
|
||||||
await this.doc.set('email', 'lin@lthings.com');
|
await this.doc.set('email', 'lin@lthings.com');
|
||||||
await this.doc.set('fullname', 'Lin Slovenly');
|
await this.doc.set('fullname', 'Lin Slovenly');
|
||||||
await this.doc.set('bankName', 'Max Finance');
|
await this.doc.set('bankName', 'Max Finance');
|
||||||
await this.doc.set('country', 'India');
|
await this.doc.set('country', 'India');
|
||||||
},
|
},
|
||||||
getField(fieldname) {
|
async onValueChange(field: Field, value: DocValue) {
|
||||||
return this.doc.schema?.fields.find((f) => f.fieldname === fieldname);
|
if (!this.hasDoc) {
|
||||||
},
|
return;
|
||||||
setValue(fieldname, value) {
|
}
|
||||||
this.emailError = null;
|
|
||||||
this.doc.set(fieldname, value).catch((e) => {
|
const { fieldname } = field;
|
||||||
if (fieldname === 'email') {
|
delete this.errors[fieldname];
|
||||||
this.emailError = getErrorMessage(e, this.doc);
|
|
||||||
|
try {
|
||||||
|
await this.doc.set(fieldname, value);
|
||||||
|
} catch (err) {
|
||||||
|
if (!(err instanceof Error)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
},
|
this.errors[fieldname] = getErrorMessage(err, this.doc as Doc);
|
||||||
allValuesFilled() {
|
}
|
||||||
const values = this.doc.schema.fields
|
|
||||||
.filter((f) => f.required)
|
|
||||||
.map((f) => this.doc[f.fieldname]);
|
|
||||||
return values.every(Boolean);
|
|
||||||
},
|
},
|
||||||
async submit() {
|
async submit() {
|
||||||
if (!this.allValuesFilled()) {
|
if (!this.hasDoc) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.areAllValuesFilled) {
|
||||||
return await showMessageDialog({
|
return await showMessageDialog({
|
||||||
message: this.t`Please fill all values`,
|
message: this.t`Please fill all values`,
|
||||||
});
|
});
|
||||||
@ -150,5 +165,40 @@ export default {
|
|||||||
this.$emit('setup-complete', this.doc.getValidDict());
|
this.$emit('setup-complete', this.doc.getValidDict());
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
computed: {
|
||||||
|
hasDoc(): boolean {
|
||||||
|
return this.docOrNull instanceof Doc;
|
||||||
|
},
|
||||||
|
doc(): Doc {
|
||||||
|
if (this.docOrNull instanceof Doc) {
|
||||||
|
return this.docOrNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Doc is null`);
|
||||||
|
},
|
||||||
|
areAllValuesFilled(): boolean {
|
||||||
|
if (!this.hasDoc) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const values = this.doc.schema.fields
|
||||||
|
.filter((f) => f.required)
|
||||||
|
.map((f) => this.doc[f.fieldname]);
|
||||||
|
|
||||||
|
return values.every(Boolean);
|
||||||
|
},
|
||||||
|
activeGroup(): Map<string, Field[]> {
|
||||||
|
if (!this.hasDoc) {
|
||||||
|
return new Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
const groupedFields = getFieldsGroupedByTabAndSection(
|
||||||
|
this.doc.schema,
|
||||||
|
this.doc
|
||||||
|
);
|
||||||
|
|
||||||
|
return [...groupedFields.values()][0];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="w-form shadow-lg rounded-lg border relative bg-white"
|
|
||||||
style="height: 700px"
|
|
||||||
>
|
|
||||||
<!-- Slide Title -->
|
|
||||||
<div class="p-4">
|
|
||||||
<h1 class="text-2xl font-semibold select-none">
|
|
||||||
<slot name="title"></slot>
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
<!-- Slide Content -->
|
|
||||||
<div>
|
|
||||||
<slot name="content"></slot>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Slide Buttons -->
|
|
||||||
<div
|
|
||||||
class="flex justify-between px-4 pb-4 absolute w-form"
|
|
||||||
style="top: 100%; transform: translateY(-100%)"
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
class="text-sm text-grey-900 min-w-28"
|
|
||||||
@click="$emit('secondary-clicked')"
|
|
||||||
:disabled="secondaryDisabled"
|
|
||||||
>
|
|
||||||
<slot name="secondaryButton"></slot>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
@click="$emit('primary-clicked')"
|
|
||||||
type="primary"
|
|
||||||
class="text-sm text-white min-w-28"
|
|
||||||
:disabled="primaryDisabled"
|
|
||||||
>
|
|
||||||
<slot name="primaryButton"></slot>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Button from 'src/components/Button.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
emits: ['primary-clicked', 'secondary-clicked'],
|
|
||||||
components: { Button },
|
|
||||||
props: {
|
|
||||||
usePrimary: { type: Boolean, default: true },
|
|
||||||
primaryDisabled: { type: Boolean, default: false },
|
|
||||||
secondaryDisabled: { type: Boolean, default: false },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
@ -49,12 +49,12 @@ export function getDatesAndPeriodList(period: PeriodKey): {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getSetupWizardDoc() {
|
export function getSetupWizardDoc() {
|
||||||
/**
|
/**
|
||||||
* This is used cause when setup wizard is running
|
* This is used cause when setup wizard is running
|
||||||
* the database isn't yet initialized.
|
* the database isn't yet initialized.
|
||||||
*/
|
*/
|
||||||
return await fyo.doc.getNewDoc(
|
return fyo.doc.getNewDoc(
|
||||||
'SetupWizard',
|
'SetupWizard',
|
||||||
{},
|
{},
|
||||||
false,
|
false,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user