2
0
mirror of https://github.com/frappe/books.git synced 2024-09-19 19:19:02 +00:00

feat: modal to selct print size

This commit is contained in:
18alantom 2023-06-02 16:21:27 +05:30
parent 8f0f154549
commit 5ec0270540
5 changed files with 290 additions and 2 deletions

View File

@ -7,6 +7,8 @@ import { Fyo } from 'fyo';
export class PrintTemplate extends Doc {
name?: string;
type?: string;
width?: number;
height?: number;
template?: string;
isCustom?: boolean;

View File

@ -23,6 +23,18 @@
"fieldtype": "Text",
"required": true
},
{
"fieldname": "height",
"label": "Height (in cm)",
"fieldtype": "Float",
"default": 29.7
},
{
"fieldname": "width",
"label": "Width (in cm)",
"fieldtype": "Float",
"default": 21
},
{
"fieldname": "isCustom",
"label": "Is Custom",

View File

@ -52,6 +52,7 @@ import { getPathAndMakePDF } from 'src/utils/printTemplates';
import { PrintValues } from 'src/utils/types';
import { defineComponent, PropType } from 'vue';
import ScaledContainer from './ScaledContainer.vue';
import { VueElement } from 'vue';
export const baseSafeTemplate = `<main class="h-full w-full bg-white">
<p class="p-4 text-red-500">
@ -165,7 +166,7 @@ export default defineComponent({
return '';
},
},
};
} as {} /** to silence :is type check */;
},
},
components: { ScaledContainer, ErrorBoundary },

View File

@ -0,0 +1,252 @@
<template>
<div class="w-form">
<FormHeader :form-title="t`Set Print Size`" />
<hr />
<div class="p-4 w-full flex flex-col gap-4">
<p class="text-base text-gray-900">
{{
t`Select a pre-defined page size, or set a custom page size for your Print Template.`
}}
</p>
<Select
:df="df"
:value="size"
@change="sizeChange"
:border="true"
:show-label="true"
/>
<div class="flex gap-4 w-full">
<Float
class="w-full"
:df="fyo.getField('PrintTemplate', 'height')"
:border="true"
:show-label="true"
:value="height"
@change="(v) => valueChange(v, 'height')"
/>
<Float
class="w-full"
:df="fyo.getField('PrintTemplate', 'width')"
:border="true"
:show-label="true"
:value="width"
@change="(v) => valueChange(v, 'width')"
/>
</div>
</div>
<div class="flex border-t p-4">
<Button class="ml-auto" type="primary" @click="done">{{
t`Done`
}}</Button>
</div>
</div>
</template>
<script lang="ts">
import { PrintTemplate } from 'models/baseModels/PrintTemplate';
import { OptionField } from 'schemas/types';
import Button from 'src/components/Button.vue';
import Float from 'src/components/Controls/Float.vue';
import Select from 'src/components/Controls/Select.vue';
import FormHeader from 'src/components/FormHeader.vue';
import { defineComponent } from 'vue';
const printSizes = [
'A0',
'A1',
'A2',
'A3',
'A4',
'A5',
'A6',
'A7',
'A8',
'A9',
'B0',
'B1',
'B2',
'B3',
'B4',
'B5',
'B6',
'B7',
'B8',
'B9',
'Letter',
'Legal',
'Executive',
'C5E',
'Comm10',
'DLE',
'Folio',
'Ledger',
'Tabloid',
'Custom',
] as const;
type SizeName = typeof printSizes[number];
const paperSizeMap: Record<SizeName, { width: number; height: number }> = {
A0: {
width: 84.1,
height: 118.9,
},
A1: {
width: 59.4,
height: 84.1,
},
A2: {
width: 42,
height: 59.4,
},
A3: {
width: 29.7,
height: 42,
},
A4: {
width: 21,
height: 29.7,
},
A5: {
width: 14.8,
height: 21,
},
A6: {
width: 10.5,
height: 14.8,
},
A7: {
width: 7.4,
height: 10.5,
},
A8: {
width: 5.2,
height: 7.4,
},
A9: {
width: 3.7,
height: 5.2,
},
B0: {
width: 100,
height: 141.4,
},
B1: {
width: 70.7,
height: 100,
},
B2: {
width: 50,
height: 70.7,
},
B3: {
width: 35.3,
height: 50,
},
B4: {
width: 25,
height: 35.3,
},
B5: {
width: 17.6,
height: 25,
},
B6: {
width: 12.5,
height: 17.6,
},
B7: {
width: 8.8,
height: 12.5,
},
B8: {
width: 6.2,
height: 8.8,
},
B9: {
width: 4.4,
height: 6.2,
},
Letter: {
width: 21.59,
height: 27.94,
},
Legal: {
width: 21.59,
height: 35.56,
},
Executive: {
width: 19.05,
height: 25.4,
},
C5E: {
width: 16.3,
height: 22.9,
},
Comm10: {
width: 10.5,
height: 24.1,
},
DLE: {
width: 11,
height: 22,
},
Folio: {
width: 21,
height: 33,
},
Ledger: {
width: 43.2,
height: 27.9,
},
Tabloid: {
width: 27.9,
height: 43.2,
},
Custom: {
width: -1,
height: -1,
},
};
export default defineComponent({
props: { doc: { type: PrintTemplate, required: true } },
data() {
return { size: 'A4', width: 21, height: 29.7 };
},
components: { Float, FormHeader, Select, Button },
methods: {
sizeChange(v: string) {
const size = paperSizeMap[v as SizeName];
if (!size) {
return;
}
this.height = size.height;
this.width = size.width;
},
valueChange(v: number, name: 'width' | 'height') {
if (this[name] === v) {
return;
}
this.size = 'Custom';
this[name] = v;
},
done() {
this.doc.set('width', this.width);
this.doc.set('height', this.height);
this.$emit('done');
},
},
computed: {
df(): OptionField {
return {
label: 'Page Size',
fieldname: 'size',
fieldtype: 'Select',
options: printSizes.map((value) => ({ value, label: value })),
default: 'A4',
};
},
},
});
</script>

View File

@ -203,6 +203,13 @@
</div>
</div>
</div>
<Modal
v-if="doc"
:open-modal="showSizeModal"
@closemodal="showSizeModal = !showSizeModal"
>
<SetPrintSize :doc="doc" @done="showSizeModal = !showSizeModal" />
</Modal>
</div>
</template>
<script lang="ts">
@ -216,6 +223,7 @@ import Button from 'src/components/Button.vue';
import FormControl from 'src/components/Controls/FormControl.vue';
import DropdownWithActions from 'src/components/DropdownWithActions.vue';
import HorizontalResizer from 'src/components/HorizontalResizer.vue';
import Modal from 'src/components/Modal.vue';
import PageHeader from 'src/components/PageHeader.vue';
import ShortcutKeys from 'src/components/ShortcutKeys.vue';
import { handleErrorWithDialog } from 'src/errorHandling';
@ -231,12 +239,12 @@ import {
import { docsPathRef, showSidebar } from 'src/utils/refs';
import { DocRef, PrintValues } from 'src/utils/types';
import {
ShortcutKey,
focusOrSelectFormControl,
getActionsForDoc,
getDocFromNameIfExistsElseNew,
openSettings,
selectTextFile,
ShortcutKey,
} from 'src/utils/ui';
import { useDocShortcuts } from 'src/utils/vueUtils';
import { getMapFromList } from 'utils/index';
@ -244,6 +252,7 @@ import { computed, defineComponent, inject, ref } from 'vue';
import PrintContainer from './PrintContainer.vue';
import TemplateBuilderHint from './TemplateBuilderHint.vue';
import TemplateEditor from './TemplateEditor.vue';
import SetPrintSize from './SetPrintSize.vue';
export default defineComponent({
props: { name: String },
@ -257,6 +266,8 @@ export default defineComponent({
FormControl,
TemplateBuilderHint,
ShortcutKeys,
Modal,
SetPrintSize,
},
setup() {
const doc = ref(null) as DocRef<PrintTemplate>;
@ -286,6 +297,7 @@ export default defineComponent({
scale: 0.6,
panelWidth: 22 /** rem */ * 16 /** px */,
templateChanged: false,
showSizeModal: false,
preEditMode: {
scale: 0.6,
showSidebar: true,
@ -297,6 +309,7 @@ export default defineComponent({
hints?: Record<string, unknown>;
values: null | PrintValues;
displayDoc: PrintTemplate | null;
showSizeModal: boolean;
scale: number;
panelWidth: number;
templateChanged: boolean;
@ -632,6 +645,14 @@ export default defineComponent({
},
});
if (this.doc.isCustom && !this.showSizeModal) {
actions.push({
label: this.t`Set Print Size`,
group: this.t`Action`,
action: () => (this.showSizeModal = true),
});
}
if (this.doc.isCustom) {
actions.push({
label: this.t`Select Template File`,