mirror of
https://github.com/frappe/books.git
synced 2025-02-02 12:08:27 +00:00
fix(ux): display template compilation errors
- fix failing tests due vue imports on ts-node compile - prevent fyo access in templates - update default template - change outline colour
This commit is contained in:
parent
8f84f2677c
commit
dced1ed559
@ -11,7 +11,6 @@ import {
|
|||||||
import { DEFAULT_CURRENCY } from 'fyo/utils/consts';
|
import { DEFAULT_CURRENCY } from 'fyo/utils/consts';
|
||||||
import { ValidationError } from 'fyo/utils/errors';
|
import { ValidationError } from 'fyo/utils/errors';
|
||||||
import { addItem, getExchangeRate, getNumberSeries } from 'models/helpers';
|
import { addItem, getExchangeRate, getNumberSeries } from 'models/helpers';
|
||||||
import { validateBatch } from 'models/inventory/helpers';
|
|
||||||
import { InventorySettings } from 'models/inventory/InventorySettings';
|
import { InventorySettings } from 'models/inventory/InventorySettings';
|
||||||
import { StockTransfer } from 'models/inventory/StockTransfer';
|
import { StockTransfer } from 'models/inventory/StockTransfer';
|
||||||
import { Transactional } from 'models/Transactional/Transactional';
|
import { Transactional } from 'models/Transactional/Transactional';
|
||||||
|
@ -6,20 +6,60 @@
|
|||||||
>
|
>
|
||||||
<!-- Template -->
|
<!-- Template -->
|
||||||
<component
|
<component
|
||||||
|
v-if="!error"
|
||||||
class="flex-1 bg-white"
|
class="flex-1 bg-white"
|
||||||
:doc="values.doc"
|
:doc="values.doc"
|
||||||
:print="values.print"
|
:print="values.print"
|
||||||
:is="{ template, props: ['doc', 'print'] }"
|
:is="templateComponent"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- Compilation Error -->
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="
|
||||||
|
h-full
|
||||||
|
bg-red-100
|
||||||
|
w-full
|
||||||
|
text-2xl text-gray-900
|
||||||
|
flex flex-col
|
||||||
|
gap-4
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<h1 class="text-4xl font-bold text-red-500 p-4 border-b border-red-200">
|
||||||
|
{{ t`Template Compilation Error` }}
|
||||||
|
</h1>
|
||||||
|
<p class="px-4 font-semibold">{{ error.message }}</p>
|
||||||
|
<pre v-if="error.codeframe" class="px-4 text-xl text-gray-700">{{
|
||||||
|
error.codeframe
|
||||||
|
}}</pre>
|
||||||
|
</div>
|
||||||
</ScaledContainer>
|
</ScaledContainer>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import {
|
||||||
|
compile,
|
||||||
|
CompilerError,
|
||||||
|
generateCodeFrame,
|
||||||
|
SourceLocation,
|
||||||
|
} from '@vue/compiler-dom';
|
||||||
import { getPathAndMakePDF } from 'src/utils/printTemplates';
|
import { getPathAndMakePDF } from 'src/utils/printTemplates';
|
||||||
import { PrintValues } from 'src/utils/types';
|
import { PrintValues } from 'src/utils/types';
|
||||||
import { defineComponent, PropType } from 'vue';
|
import { defineComponent, PropType } from 'vue';
|
||||||
import ScaledContainer from './ScaledContainer.vue';
|
import ScaledContainer from './ScaledContainer.vue';
|
||||||
|
|
||||||
|
export const baseSafeTemplate = `<main class="h-full w-full bg-white">
|
||||||
|
<p class="p-4 text-red-500">
|
||||||
|
<span class="font-bold">ERROR</span>: Template failed to load due to errors.
|
||||||
|
</p>
|
||||||
|
</main>
|
||||||
|
`;
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
data() {
|
||||||
|
return { error: null } as {
|
||||||
|
error: null | { codeframe: string; message: string };
|
||||||
|
};
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
template: { type: String, required: true },
|
template: { type: String, required: true },
|
||||||
scale: { type: Number, default: 0.65 },
|
scale: { type: Number, default: 0.65 },
|
||||||
@ -28,7 +68,30 @@ export default defineComponent({
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
template(value: string) {
|
||||||
|
this.compile(value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.compile(this.template);
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
compile(template: string) {
|
||||||
|
this.error = null;
|
||||||
|
return compile(template, {
|
||||||
|
hoistStatic: true,
|
||||||
|
onWarn: this.onError,
|
||||||
|
onError: this.onError,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError({ message, loc }: CompilerError) {
|
||||||
|
const codeframe = loc ? this.getCodeFrame(loc) : '';
|
||||||
|
this.error = { codeframe, message };
|
||||||
|
},
|
||||||
|
getCodeFrame(loc: SourceLocation) {
|
||||||
|
return generateCodeFrame(this.template, loc.start.offset, loc.end.offset);
|
||||||
|
},
|
||||||
async savePDF(name?: string) {
|
async savePDF(name?: string) {
|
||||||
/**
|
/**
|
||||||
* To be called through ref by the parent component.
|
* To be called through ref by the parent component.
|
||||||
@ -43,6 +106,27 @@ export default defineComponent({
|
|||||||
await getPathAndMakePDF(name ?? this.t`Entry`, innerHTML);
|
await getPathAndMakePDF(name ?? this.t`Entry`, innerHTML);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
templateComponent() {
|
||||||
|
let template = this.template;
|
||||||
|
if (this.error) {
|
||||||
|
template = baseSafeTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
template,
|
||||||
|
props: ['doc', 'print'],
|
||||||
|
computed: {
|
||||||
|
fyo() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
platform() {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
components: { ScaledContainer },
|
components: { ScaledContainer },
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
outline-color: theme('colors.pink.500');
|
outline-color: theme('colors.pink.400');
|
||||||
font-variation-settings: 'slnt' 0deg;
|
font-variation-settings: 'slnt' 0deg;
|
||||||
}
|
}
|
||||||
.italic {
|
.italic {
|
||||||
|
@ -8,7 +8,6 @@ import {
|
|||||||
getRandomString,
|
getRandomString,
|
||||||
getValueMapFromList,
|
getValueMapFromList,
|
||||||
} from 'utils/index';
|
} from 'utils/index';
|
||||||
import { updatePrintTemplates } from './printTemplates';
|
|
||||||
|
|
||||||
export async function initializeInstance(
|
export async function initializeInstance(
|
||||||
dbPath: string,
|
dbPath: string,
|
||||||
@ -34,7 +33,6 @@ export async function initializeInstance(
|
|||||||
await setInstanceId(fyo);
|
await setInstanceId(fyo);
|
||||||
await setOpenCount(fyo);
|
await setOpenCount(fyo);
|
||||||
await setCurrencySymbols(fyo);
|
await setCurrencySymbols(fyo);
|
||||||
await updatePrintTemplates(fyo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function closeDbIfConnected(fyo: Fyo) {
|
async function closeDbIfConnected(fyo: Fyo) {
|
||||||
|
@ -351,7 +351,9 @@ function getNameAndTypeFromTemplateFile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const baseTemplate = `<main class="h-full w-full bg-white">
|
export const baseTemplate = `<main class="h-full w-full bg-white">
|
||||||
<header class="p-4 flex justify-between bg-gray-50">
|
|
||||||
|
<!-- Edit This Code -->
|
||||||
|
<header class="p-4 flex justify-between border-b">
|
||||||
<h2
|
<h2
|
||||||
class="font-semibold text-2xl"
|
class="font-semibold text-2xl"
|
||||||
:style="{ color: print.color }"
|
:style="{ color: print.color }"
|
||||||
@ -362,4 +364,11 @@ export const baseTemplate = `<main class="h-full w-full bg-white">
|
|||||||
{{ doc.name }}
|
{{ doc.name }}
|
||||||
</h2>
|
</h2>
|
||||||
</header>
|
</header>
|
||||||
</main>`;
|
|
||||||
|
<div class="p-4 text-gray-600">
|
||||||
|
Edit the code in the Template Editor on the right
|
||||||
|
to create your own personalized custom template.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
`;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user