281 lines
6.9 KiB
TypeScript
281 lines
6.9 KiB
TypeScript
import {
|
|
Plugin,
|
|
PropPanel,
|
|
DEFAULT_FONT_NAME,
|
|
getFallbackFontName,
|
|
PropPanelSchema,
|
|
PropPanelWidgetProps,
|
|
} from "@pdfme/common";
|
|
import { text } from "@pdfme/schemas";
|
|
import type { TextSchema } from "@pdfme/schemas/dist/types/src/text/types";
|
|
|
|
import {
|
|
DEFAULT_FONT_SIZE,
|
|
DEFAULT_ALIGNMENT,
|
|
DEFAULT_VERTICAL_ALIGNMENT,
|
|
DEFAULT_CHARACTER_SPACING,
|
|
DEFAULT_LINE_HEIGHT,
|
|
VERTICAL_ALIGN_TOP,
|
|
VERTICAL_ALIGN_MIDDLE,
|
|
VERTICAL_ALIGN_BOTTOM,
|
|
DEFAULT_FONT_COLOR,
|
|
DYNAMIC_FIT_VERTICAL,
|
|
DYNAMIC_FIT_HORIZONTAL,
|
|
DEFAULT_DYNAMIC_FIT,
|
|
DEFAULT_DYNAMIC_MIN_FONT_SIZE,
|
|
DEFAULT_DYNAMIC_MAX_FONT_SIZE,
|
|
ALIGN_RIGHT,
|
|
ALIGN_CENTER,
|
|
DEFAULT_OPACITY,
|
|
HEX_COLOR_PATTERN,
|
|
} from "./constants";
|
|
import {
|
|
GebaeudeStammdaten,
|
|
Rechnungen,
|
|
} from "@ibcornelsen/database/client";
|
|
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
|
|
import { zodGetKeys } from "#lib/helpers/zod";
|
|
import { verbrauchsausweisWohnenPDFValidator } from "#lib/validators/verbrauchsausweis-wohnen-pdf-validator";
|
|
|
|
const UseDynamicFontSize = (props: PropPanelWidgetProps) => {
|
|
const { rootElement, changeSchemas, activeSchema, i18n } = props;
|
|
|
|
const checkbox = document.createElement("input");
|
|
checkbox.type = "checkbox";
|
|
checkbox.checked = Boolean((activeSchema as any)?.dynamicFontSize);
|
|
checkbox.onchange = (e: any) => {
|
|
const val = e.target.checked
|
|
? {
|
|
min: DEFAULT_DYNAMIC_MIN_FONT_SIZE,
|
|
max: DEFAULT_DYNAMIC_MAX_FONT_SIZE,
|
|
fit: DEFAULT_DYNAMIC_FIT,
|
|
}
|
|
: undefined;
|
|
changeSchemas([
|
|
{ key: "dynamicFontSize", value: val, schemaId: activeSchema.id },
|
|
]);
|
|
};
|
|
const label = document.createElement("label");
|
|
label.innerText = i18n("schemas.text.dynamicFontSize") || "";
|
|
label.style.cssText = "display: flex; width: 100%;";
|
|
label.appendChild(checkbox);
|
|
rootElement.appendChild(label);
|
|
};
|
|
|
|
type AusweisIndex = keyof Omit<Omit<VerbrauchsausweisWohnenClient, "gebaeude_aufnahme_allgemein">, "rechnungen">
|
|
| `gebaeude_aufnahme_allgemein.${keyof VerbrauchsausweisWohnenClient["gebaeude_aufnahme_allgemein"]}`
|
|
| `gebaeude_aufnahme_allgemein.gebaeude_stammdaten.${keyof VerbrauchsausweisWohnenClient["gebaeude_aufnahme_allgemein"]["gebaeude_stammdaten"]}`
|
|
| `rechnungen.${keyof Rechnungen}`;
|
|
|
|
const ausweisKeys = zodGetKeys(verbrauchsausweisWohnenPDFValidator);
|
|
|
|
const variableOptions: {
|
|
label: string;
|
|
value: AusweisIndex;
|
|
}[] = ausweisKeys.map((key: AusweisIndex) => ({ label: key as string, value: key }));
|
|
|
|
interface VariableSchema extends TextSchema {
|
|
variable: AusweisIndex | undefined
|
|
}
|
|
|
|
const propPanel: PropPanel<VariableSchema> = {
|
|
schema: ({ options, activeSchema, i18n }) => {
|
|
const font = options.font || {
|
|
[DEFAULT_FONT_NAME]: { data: "", fallback: true },
|
|
};
|
|
const fontNames = Object.keys(font);
|
|
const fallbackFontName = getFallbackFontName(font);
|
|
|
|
const enableDynamicFont = Boolean(
|
|
(activeSchema as any)?.dynamicFontSize
|
|
);
|
|
|
|
const textSchema: Record<string, PropPanelSchema> = {
|
|
variable: {
|
|
title: "Variable",
|
|
type: "string",
|
|
widget: "select",
|
|
props: { options: variableOptions },
|
|
span: 24,
|
|
},
|
|
fontName: {
|
|
title: i18n("schemas.text.fontName"),
|
|
type: "string",
|
|
widget: "select",
|
|
default: fallbackFontName,
|
|
props: {
|
|
options: fontNames.map((name) => ({
|
|
label: name,
|
|
value: name,
|
|
})),
|
|
},
|
|
span: 12,
|
|
},
|
|
fontSize: {
|
|
title: i18n("schemas.text.size"),
|
|
type: "number",
|
|
widget: "inputNumber",
|
|
span: 6,
|
|
disabled: enableDynamicFont,
|
|
},
|
|
characterSpacing: {
|
|
title: i18n("schemas.text.spacing"),
|
|
type: "number",
|
|
widget: "inputNumber",
|
|
span: 6,
|
|
},
|
|
alignment: {
|
|
title: i18n("schemas.text.textAlign"),
|
|
type: "string",
|
|
widget: "select",
|
|
props: {
|
|
options: [
|
|
{
|
|
label: i18n("schemas.left"),
|
|
value: DEFAULT_ALIGNMENT,
|
|
},
|
|
{ label: i18n("schemas.center"), value: ALIGN_CENTER },
|
|
{ label: i18n("schemas.right"), value: ALIGN_RIGHT },
|
|
],
|
|
},
|
|
span: 8,
|
|
},
|
|
verticalAlignment: {
|
|
title: i18n("schemas.text.verticalAlign"),
|
|
type: "string",
|
|
widget: "select",
|
|
props: {
|
|
options: [
|
|
{
|
|
label: i18n("schemas.top"),
|
|
value: VERTICAL_ALIGN_TOP,
|
|
},
|
|
{
|
|
label: i18n("schemas.middle"),
|
|
value: VERTICAL_ALIGN_MIDDLE,
|
|
},
|
|
{
|
|
label: i18n("schemas.bottom"),
|
|
value: VERTICAL_ALIGN_BOTTOM,
|
|
},
|
|
],
|
|
},
|
|
span: 8,
|
|
},
|
|
lineHeight: {
|
|
title: i18n("schemas.text.lineHeight"),
|
|
type: "number",
|
|
widget: "inputNumber",
|
|
props: {
|
|
step: 0.1,
|
|
},
|
|
span: 8,
|
|
},
|
|
useDynamicFontSize: {
|
|
type: "boolean",
|
|
widget: "UseDynamicFontSize",
|
|
bind: false,
|
|
span: 16,
|
|
},
|
|
dynamicFontSize: {
|
|
type: "object",
|
|
widget: "card",
|
|
column: 3,
|
|
properties: {
|
|
min: {
|
|
title: i18n("schemas.text.min"),
|
|
type: "number",
|
|
widget: "inputNumber",
|
|
hidden: !enableDynamicFont,
|
|
},
|
|
max: {
|
|
title: i18n("schemas.text.max"),
|
|
type: "number",
|
|
widget: "inputNumber",
|
|
hidden: !enableDynamicFont,
|
|
},
|
|
fit: {
|
|
title: i18n("schemas.text.fit"),
|
|
type: "string",
|
|
widget: "select",
|
|
hidden: !enableDynamicFont,
|
|
props: {
|
|
options: [
|
|
{
|
|
label: i18n("schemas.horizontal"),
|
|
value: DYNAMIC_FIT_HORIZONTAL,
|
|
},
|
|
{
|
|
label: i18n("schemas.vertical"),
|
|
value: DYNAMIC_FIT_VERTICAL,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
fontColor: {
|
|
title: i18n("schemas.textColor"),
|
|
type: "string",
|
|
widget: "color",
|
|
rules: [
|
|
{
|
|
pattern: HEX_COLOR_PATTERN,
|
|
message: i18n("hexColorPrompt"),
|
|
},
|
|
],
|
|
},
|
|
backgroundColor: {
|
|
title: i18n("schemas.bgColor"),
|
|
type: "string",
|
|
widget: "color",
|
|
rules: [
|
|
{
|
|
pattern: HEX_COLOR_PATTERN,
|
|
message: i18n("hexColorPrompt"),
|
|
},
|
|
],
|
|
},
|
|
};
|
|
|
|
return textSchema;
|
|
},
|
|
widgets: { UseDynamicFontSize },
|
|
defaultValue: "Type Something...",
|
|
defaultSchema: {
|
|
type: "variable",
|
|
position: { x: 0, y: 0 },
|
|
width: 45,
|
|
height: 10,
|
|
rotate: 0,
|
|
alignment: DEFAULT_ALIGNMENT,
|
|
verticalAlignment: DEFAULT_VERTICAL_ALIGNMENT,
|
|
fontSize: DEFAULT_FONT_SIZE,
|
|
lineHeight: DEFAULT_LINE_HEIGHT,
|
|
characterSpacing: DEFAULT_CHARACTER_SPACING,
|
|
dynamicFontSize: undefined,
|
|
fontColor: DEFAULT_FONT_COLOR,
|
|
fontName: undefined,
|
|
backgroundColor: "",
|
|
opacity: DEFAULT_OPACITY,
|
|
variable: undefined
|
|
}
|
|
};
|
|
|
|
export const variable: Plugin<VariableSchema> = {
|
|
ui: function(props) {
|
|
// Wir binden die inputs auf dieses Element, damit wir die Werte später auslesen können.
|
|
if (props.schema.variable && this) {
|
|
props.value = (this as unknown as Record<string, string>)[props.schema.variable] as string;
|
|
}
|
|
return text.ui(props);
|
|
},
|
|
pdf: (props) => {
|
|
if (props.schema.variable && this) {
|
|
props.value = (this as unknown as Record<string, string>)[props.schema.variable] as string;
|
|
}
|
|
text.pdf(props);
|
|
},
|
|
propPanel,
|
|
};
|