feat: add mobile css
This commit is contained in:
@@ -6,4 +6,6 @@ export abstract class AbstractBuilder {
|
|||||||
public abstract getLabelledRowHeight(): number;
|
public abstract getLabelledRowHeight(): number;
|
||||||
|
|
||||||
public abstract save(name: string);
|
public abstract save(name: string);
|
||||||
|
|
||||||
|
public abstract getImageScale(): number;
|
||||||
}
|
}
|
||||||
|
|||||||
35
src/elements/abstract-container-element.ts
Normal file
35
src/elements/abstract-container-element.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { AbstractElement } from './abstract-element';
|
||||||
|
import { IContext } from './context';
|
||||||
|
|
||||||
|
export abstract class AbstractContainerElement extends AbstractElement {
|
||||||
|
public pdfElements: AbstractElement[] = [];
|
||||||
|
public htmlElements: AbstractElement[] = [];
|
||||||
|
public contextElements: AbstractElement[] = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
maxWidth: number | undefined,
|
||||||
|
elements: AbstractElement[] = [],
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
|
) {
|
||||||
|
super(x, y, maxWidth, context);
|
||||||
|
this.htmlElements = this.context.isHtml
|
||||||
|
? elements.filter((el) => el.context.isHtml)
|
||||||
|
: [];
|
||||||
|
this.pdfElements = this.context.isPdf
|
||||||
|
? elements.filter((el) => el.context.isPdf)
|
||||||
|
: [];
|
||||||
|
this.contextElements = this.context.isHtml
|
||||||
|
? this.htmlElements
|
||||||
|
: this.pdfElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getElements(): AbstractElement[] {
|
||||||
|
const elements: AbstractElement[] = [];
|
||||||
|
for (const element of this.contextElements) {
|
||||||
|
elements.push(...element.getElements());
|
||||||
|
}
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,32 @@
|
|||||||
import jsPDF from 'jspdf';
|
import jsPDF from 'jspdf';
|
||||||
import { MARGINS } from '../constants';
|
import { MARGINS } from '../constants';
|
||||||
|
import { IContext } from './context';
|
||||||
|
|
||||||
export abstract class AbstractElement {
|
export abstract class AbstractElement {
|
||||||
|
public static readonly DEFAULT_CONTEXT: IContext = {
|
||||||
|
isHtml: true,
|
||||||
|
isPdf: true,
|
||||||
|
name: 'element',
|
||||||
|
};
|
||||||
|
|
||||||
public x: number;
|
public x: number;
|
||||||
public y: number;
|
public y: number;
|
||||||
public maxWidth?: number;
|
public maxWidth?: number;
|
||||||
|
public context: IContext = AbstractElement.DEFAULT_CONTEXT;
|
||||||
|
|
||||||
constructor(x: number, y: number, maxWidth?: number | undefined) {
|
constructor(
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
maxWidth?: number | undefined,
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
|
) {
|
||||||
this.x = x >= MARGINS.left ? x : MARGINS.left;
|
this.x = x >= MARGINS.left ? x : MARGINS.left;
|
||||||
this.y = y >= MARGINS.top ? y : MARGINS.top;
|
this.y = y >= MARGINS.top ? y : MARGINS.top;
|
||||||
this.maxWidth = maxWidth;
|
this.maxWidth = maxWidth;
|
||||||
|
this.context = {
|
||||||
|
...this.context,
|
||||||
|
...context,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public getHeightFromPx(doc: jsPDF, size: number) {
|
public getHeightFromPx(doc: jsPDF, size: number) {
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
import { AbstractElement } from './abstract-element';
|
import { AbstractElement } from './abstract-element';
|
||||||
import jsPDF from 'jspdf';
|
import jsPDF from 'jspdf';
|
||||||
import { Box } from './box';
|
import { Box } from './box';
|
||||||
|
import { IContext } from './context';
|
||||||
|
|
||||||
export class Blank extends Box {
|
export class Blank extends Box {
|
||||||
constructor(x: number, y: number, w: number, h: number) {
|
constructor(
|
||||||
super(x, y, w, h);
|
x: number,
|
||||||
|
y: number,
|
||||||
|
w: number,
|
||||||
|
h: number,
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
|
) {
|
||||||
|
super(x, y, w, h, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static heightBlank(h: number) {
|
public static heightBlank(h: number) {
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
import { AbstractElement } from './abstract-element';
|
import { AbstractElement } from './abstract-element';
|
||||||
import jsPDF from 'jspdf';
|
import jsPDF from 'jspdf';
|
||||||
|
import { IContext } from './context';
|
||||||
|
|
||||||
export class Box extends AbstractElement {
|
export class Box extends AbstractElement {
|
||||||
public w: number;
|
public w: number;
|
||||||
public h: number;
|
public h: number;
|
||||||
|
|
||||||
constructor(x: number, y: number, w: number, h: number) {
|
constructor(
|
||||||
super(x, y, w);
|
x: number,
|
||||||
|
y: number,
|
||||||
|
w: number,
|
||||||
|
h: number,
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
|
) {
|
||||||
|
super(x, y, w, context);
|
||||||
this.w = w;
|
this.w = w;
|
||||||
this.h = h;
|
this.h = h;
|
||||||
}
|
}
|
||||||
@@ -30,6 +37,7 @@ export class Box extends AbstractElement {
|
|||||||
const css = `box-${this.w ?? 0}-${this.h ?? 0}`;
|
const css = `box-${this.w ?? 0}-${this.h ?? 0}`;
|
||||||
div.classList.add(`box`);
|
div.classList.add(`box`);
|
||||||
div.classList.add(css);
|
div.classList.add(css);
|
||||||
|
div.classList.add(this.context.name);
|
||||||
if (!cssRules.includes(css)) {
|
if (!cssRules.includes(css)) {
|
||||||
cssRules.push(css);
|
cssRules.push(css);
|
||||||
let rule = 'width: 100%;';
|
let rule = 'width: 100%;';
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
import { AbstractElement } from './abstract-element';
|
import { AbstractElement } from './abstract-element';
|
||||||
import jsPDF from 'jspdf';
|
import jsPDF from 'jspdf';
|
||||||
|
import { IContext } from './context';
|
||||||
|
import { AbstractContainerElement } from './abstract-container-element';
|
||||||
|
|
||||||
export class Column extends AbstractElement {
|
export class Column extends AbstractContainerElement {
|
||||||
public elements: AbstractElement[] = [];
|
constructor(
|
||||||
|
x: number,
|
||||||
constructor(x: number, y: number, elements: AbstractElement[]) {
|
y: number,
|
||||||
super(x, y);
|
elements: AbstractElement[],
|
||||||
this.elements = elements;
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
|
) {
|
||||||
|
super(x, y, undefined, elements, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public prepareRender(doc: jsPDF, _maxWidth?: number): jsPDF {
|
public prepareRender(doc: jsPDF, _maxWidth?: number): jsPDF {
|
||||||
const elements = this.elements ?? [];
|
const elements = this.pdfElements ?? [];
|
||||||
|
|
||||||
let currentY = this.y;
|
let currentY = this.y;
|
||||||
for (let i = 0; i < elements.length; i++) {
|
for (let i = 0; i < elements.length; i++) {
|
||||||
@@ -37,7 +41,8 @@ export class Column extends AbstractElement {
|
|||||||
): Document {
|
): Document {
|
||||||
const div = doc.createElement('div');
|
const div = doc.createElement('div');
|
||||||
div.classList.add(`column`);
|
div.classList.add(`column`);
|
||||||
const elements = this.elements ?? [];
|
div.classList.add(this.context.name);
|
||||||
|
const elements = this.htmlElements ?? [];
|
||||||
for (let i = 0; i < elements.length; i++) {
|
for (let i = 0; i < elements.length; i++) {
|
||||||
const element = elements[i];
|
const element = elements[i];
|
||||||
element.renderHtml(doc, div, cssRules, sheet);
|
element.renderHtml(doc, div, cssRules, sheet);
|
||||||
@@ -47,8 +52,8 @@ export class Column extends AbstractElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getHeight(doc): number {
|
public getHeight(doc): number {
|
||||||
return this.elements.length > 0
|
return this.pdfElements.length > 0
|
||||||
? this.elements
|
? this.pdfElements
|
||||||
.map((e) => e.getHeight(doc))
|
.map((e) => e.getHeight(doc))
|
||||||
.reduce((p, c, i) => {
|
.reduce((p, c, i) => {
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
@@ -60,20 +65,8 @@ export class Column extends AbstractElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getCheckNewPageHeight(doc?: jsPDF): number {
|
public getCheckNewPageHeight(doc?: jsPDF): number {
|
||||||
return this.elements.length > 0
|
return this.pdfElements.length > 0
|
||||||
? this.elements[0].getCheckNewPageHeight(doc)
|
? this.pdfElements[0].getCheckNewPageHeight(doc)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getElements(): AbstractElement[] {
|
|
||||||
const elements: AbstractElement[] = [];
|
|
||||||
for (const element of this.elements) {
|
|
||||||
elements.push(...element.getElements());
|
|
||||||
}
|
|
||||||
return elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
public isEmpty(): boolean {
|
|
||||||
return this.elements.length === 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
5
src/elements/context.ts
Normal file
5
src/elements/context.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export interface IContext {
|
||||||
|
name: string;
|
||||||
|
isHtml: boolean;
|
||||||
|
isPdf: boolean;
|
||||||
|
}
|
||||||
@@ -1,12 +1,20 @@
|
|||||||
import { Box } from './box';
|
import { Box } from './box';
|
||||||
import jsPDF from 'jspdf';
|
import jsPDF from 'jspdf';
|
||||||
import { AbstractElement } from './abstract-element';
|
import { AbstractElement } from './abstract-element';
|
||||||
|
import { IContext } from './context';
|
||||||
|
|
||||||
export class Image extends Box {
|
export class Image extends Box {
|
||||||
public imageData: string;
|
public imageData: string;
|
||||||
|
|
||||||
constructor(x: number, y: number, w: number, h: number, imageData: string) {
|
constructor(
|
||||||
super(x, y, w, h);
|
x: number,
|
||||||
|
y: number,
|
||||||
|
w: number,
|
||||||
|
h: number,
|
||||||
|
imageData: string,
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
|
) {
|
||||||
|
super(x, y, w, h, context);
|
||||||
this.imageData = imageData;
|
this.imageData = imageData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,18 +37,16 @@ export class Image extends Box {
|
|||||||
): Document {
|
): Document {
|
||||||
const img = doc.createElement('img');
|
const img = doc.createElement('img');
|
||||||
img.src = this.imageData;
|
img.src = this.imageData;
|
||||||
const css = `img-${this.w ?? 0}-${this.h ?? 0}`;
|
const css = `img-${this.w ?? 0}`;
|
||||||
img.classList.add(`img`);
|
img.classList.add(`img`);
|
||||||
img.classList.add(css);
|
img.classList.add(css);
|
||||||
|
img.classList.add(this.context.name);
|
||||||
if (!cssRules.includes(css)) {
|
if (!cssRules.includes(css)) {
|
||||||
cssRules.push(css);
|
cssRules.push(css);
|
||||||
let rule = '';
|
let rule = '';
|
||||||
if (this.w > 0) {
|
if (this.w > 0) {
|
||||||
rule += `width: ${this.w}px;`;
|
rule += `width: ${this.w}px;`;
|
||||||
}
|
}
|
||||||
if (this.h > 0) {
|
|
||||||
rule += `height: ${this.h}px;`;
|
|
||||||
}
|
|
||||||
if (rule.length > 0) {
|
if (rule.length > 0) {
|
||||||
sheet.innerHTML += ` .${css} { ${rule} }`;
|
sheet.innerHTML += ` .${css} { ${rule} }`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
TEXT_SIZE,
|
TEXT_SIZE,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
import { AbstractElement } from './abstract-element';
|
import { AbstractElement } from './abstract-element';
|
||||||
|
import { IContext } from './context';
|
||||||
|
|
||||||
export class LabelledText extends Text {
|
export class LabelledText extends Text {
|
||||||
public label: string;
|
public label: string;
|
||||||
@@ -19,9 +20,10 @@ export class LabelledText extends Text {
|
|||||||
label: string,
|
label: string,
|
||||||
text: string,
|
text: string,
|
||||||
textOptions?: TextOptionsLight,
|
textOptions?: TextOptionsLight,
|
||||||
labelOptions?: TextOptionsLight
|
labelOptions?: TextOptionsLight,
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
) {
|
) {
|
||||||
super(x, y, text, textOptions);
|
super(x, y, text, textOptions, context);
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.labelOptions = labelOptions;
|
this.labelOptions = labelOptions;
|
||||||
const textMaxWidth = this.textOptions?.maxWidth ?? 0;
|
const textMaxWidth = this.textOptions?.maxWidth ?? 0;
|
||||||
@@ -54,6 +56,8 @@ export class LabelledText extends Text {
|
|||||||
): Document {
|
): Document {
|
||||||
const div = doc.createElement('div');
|
const div = doc.createElement('div');
|
||||||
div.classList.add(`column`);
|
div.classList.add(`column`);
|
||||||
|
div.classList.add(`labelled-text`);
|
||||||
|
div.classList.add(this.context.name);
|
||||||
const label = doc.createElement('p');
|
const label = doc.createElement('p');
|
||||||
const text = doc.createElement('p');
|
const text = doc.createElement('p');
|
||||||
const labelCss = `label-${LABEL_SIZE}`;
|
const labelCss = `label-${LABEL_SIZE}`;
|
||||||
@@ -62,11 +66,13 @@ export class LabelledText extends Text {
|
|||||||
text.classList.add(textCss);
|
text.classList.add(textCss);
|
||||||
if (!cssRules.includes(labelCss)) {
|
if (!cssRules.includes(labelCss)) {
|
||||||
cssRules.push(labelCss);
|
cssRules.push(labelCss);
|
||||||
sheet.innerHTML += ` .${labelCss} { font-size: ${HTML_LABEL_SIZE}rem }`;
|
sheet.innerHTML += ` .${labelCss} { font-size: ${HTML_LABEL_SIZE}rem; margin: 0; }`;
|
||||||
}
|
}
|
||||||
if (!cssRules.includes(textCss)) {
|
if (!cssRules.includes(textCss)) {
|
||||||
cssRules.push(textCss);
|
cssRules.push(textCss);
|
||||||
sheet.innerHTML += ` .${textCss} { font-size: ${HTML_TEXT_SIZE}rem }`;
|
sheet.innerHTML += ` .${textCss} { font-size: ${HTML_TEXT_SIZE}rem; margin-top: 0.5rem; margin-bottom: 0.5rem; }`;
|
||||||
|
sheet.innerHTML += ` .labelled-text { margin-top: 0.5rem; margin-bottom: 0.5rem; }`;
|
||||||
|
sheet.innerHTML += ` .labelled-text > .${textCss} { font-size: ${HTML_TEXT_SIZE}rem; margin: 0; }`;
|
||||||
}
|
}
|
||||||
label.innerHTML = i18nLocalize(this.label);
|
label.innerHTML = i18nLocalize(this.label);
|
||||||
text.innerHTML = i18nLocalize(this.text);
|
text.innerHTML = i18nLocalize(this.text);
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { Row } from './row';
|
import { Row } from './row';
|
||||||
import { Text } from './text';
|
import { Text } from './text';
|
||||||
import { MultilineText } from './multiline-text';
|
import { MultilineText } from './multiline-text';
|
||||||
|
import { IContext } from './context';
|
||||||
|
import { AbstractElement } from './abstract-element';
|
||||||
|
|
||||||
export class LabelledValue extends Row {
|
export class LabelledValue extends Row {
|
||||||
public label: string;
|
public label: string;
|
||||||
@@ -11,7 +13,8 @@ export class LabelledValue extends Row {
|
|||||||
value: number,
|
value: number,
|
||||||
widthPercents?: number[],
|
widthPercents?: number[],
|
||||||
multiline = false,
|
multiline = false,
|
||||||
maxWidth?: number
|
maxWidth?: number,
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
0,
|
0,
|
||||||
@@ -24,9 +27,21 @@ export class LabelledValue extends Row {
|
|||||||
],
|
],
|
||||||
maxWidth,
|
maxWidth,
|
||||||
widthPercents,
|
widthPercents,
|
||||||
[]
|
[],
|
||||||
|
context
|
||||||
);
|
);
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public renderHtml(
|
||||||
|
doc: Document,
|
||||||
|
parent: HTMLElement,
|
||||||
|
cssRules: string[],
|
||||||
|
sheet: HTMLStyleElement
|
||||||
|
): Document {
|
||||||
|
const resultDoc = super.renderHtml(doc, parent, cssRules, sheet);
|
||||||
|
parent.lastElementChild?.classList?.add('labelled-value');
|
||||||
|
return resultDoc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { Column } from './column';
|
|||||||
import { LabelledValue } from './labelled-value';
|
import { LabelledValue } from './labelled-value';
|
||||||
import jsPDF from 'jspdf';
|
import jsPDF from 'jspdf';
|
||||||
import { MARGINS } from '../constants';
|
import { MARGINS } from '../constants';
|
||||||
|
import { IContext } from './context';
|
||||||
|
import { AbstractElement } from './abstract-element';
|
||||||
|
|
||||||
export class LabelledValues extends Row {
|
export class LabelledValues extends Row {
|
||||||
public labelledValues: { label: string; value: number }[];
|
public labelledValues: { label: string; value: number }[];
|
||||||
@@ -13,9 +15,10 @@ export class LabelledValues extends Row {
|
|||||||
y: number,
|
y: number,
|
||||||
labelledValues: { label: string; value: number }[],
|
labelledValues: { label: string; value: number }[],
|
||||||
nbrOfCol?: number,
|
nbrOfCol?: number,
|
||||||
multiline = false
|
multiline = false,
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
) {
|
) {
|
||||||
super(x, y, []);
|
super(x, y, [], undefined, undefined, undefined, context);
|
||||||
this.labelledValues = labelledValues;
|
this.labelledValues = labelledValues;
|
||||||
this.nbrOfCol = nbrOfCol ?? 3;
|
this.nbrOfCol = nbrOfCol ?? 3;
|
||||||
if (this.nbrOfCol > 3) {
|
if (this.nbrOfCol > 3) {
|
||||||
@@ -35,7 +38,9 @@ export class LabelledValues extends Row {
|
|||||||
rest > 2 ? nbrPerCol + 1 : nbrPerCol,
|
rest > 2 ? nbrPerCol + 1 : nbrPerCol,
|
||||||
];
|
];
|
||||||
for (let i = 0; i < this.nbrOfCol; i++) {
|
for (let i = 0; i < this.nbrOfCol; i++) {
|
||||||
this.elements[i] = new Column(0, 0, []);
|
this.contextElements[i] = new Column(0, 0, [], {
|
||||||
|
name: `${this.context.name}-column`,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
for (let i = 0; i < labelledValues.length; i++) {
|
for (let i = 0; i < labelledValues.length; i++) {
|
||||||
if (i < nbrPerCols[0]) {
|
if (i < nbrPerCols[0]) {
|
||||||
@@ -45,7 +50,7 @@ export class LabelledValues extends Row {
|
|||||||
} else {
|
} else {
|
||||||
currentIndex = 2;
|
currentIndex = 2;
|
||||||
}
|
}
|
||||||
(<Column>this.elements[currentIndex]).elements.push(
|
(<Column>this.contextElements[currentIndex]).contextElements.push(
|
||||||
new LabelledValue(
|
new LabelledValue(
|
||||||
labelledValues[i].label,
|
labelledValues[i].label,
|
||||||
labelledValues[i].value,
|
labelledValues[i].value,
|
||||||
@@ -55,7 +60,7 @@ export class LabelledValues extends Row {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.elements.push(
|
this.contextElements.push(
|
||||||
new Column(
|
new Column(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -67,7 +72,10 @@ export class LabelledValues extends Row {
|
|||||||
widthPercent,
|
widthPercent,
|
||||||
multiline
|
multiline
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
|
{
|
||||||
|
name: `${this.context.name}-column`,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -77,8 +85,8 @@ export class LabelledValues extends Row {
|
|||||||
public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF {
|
public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF {
|
||||||
const pageWidth = doc.internal.pageSize.width;
|
const pageWidth = doc.internal.pageSize.width;
|
||||||
const rowWidth = pageWidth - this.x - MARGINS.right;
|
const rowWidth = pageWidth - this.x - MARGINS.right;
|
||||||
for (const column of this.elements) {
|
for (const column of this.pdfElements) {
|
||||||
for (const labelledValue of (<Column>column).elements) {
|
for (const labelledValue of (<Column>column).pdfElements) {
|
||||||
labelledValue.maxWidth = rowWidth / this.nbrOfCol;
|
labelledValue.maxWidth = rowWidth / this.nbrOfCol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { AbstractElement } from './abstract-element';
|
|||||||
import jsPDF, { TextOptionsLight } from 'jspdf';
|
import jsPDF, { TextOptionsLight } from 'jspdf';
|
||||||
import { HTML_TEXT_SIZE, i18nLocalize, TEXT_SIZE } from '../constants';
|
import { HTML_TEXT_SIZE, i18nLocalize, TEXT_SIZE } from '../constants';
|
||||||
import { Text } from './text';
|
import { Text } from './text';
|
||||||
|
import { IContext } from './context';
|
||||||
|
|
||||||
export class MultilineText extends Text {
|
export class MultilineText extends Text {
|
||||||
private nbrLine = 1;
|
private nbrLine = 1;
|
||||||
@@ -10,9 +11,10 @@ export class MultilineText extends Text {
|
|||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
text: string,
|
text: string,
|
||||||
textOptions?: TextOptionsLight
|
textOptions?: TextOptionsLight,
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
) {
|
) {
|
||||||
super(x, y, text, textOptions);
|
super(x, y, text, textOptions, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF {
|
public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF {
|
||||||
@@ -42,9 +44,11 @@ export class MultilineText extends Text {
|
|||||||
const css = `text-${TEXT_SIZE}`;
|
const css = `text-${TEXT_SIZE}`;
|
||||||
text.classList.add(`multiline-text`);
|
text.classList.add(`multiline-text`);
|
||||||
text.classList.add(css);
|
text.classList.add(css);
|
||||||
|
text.classList.add(this.context.name);
|
||||||
if (!cssRules.includes(css)) {
|
if (!cssRules.includes(css)) {
|
||||||
cssRules.push(css);
|
cssRules.push(css);
|
||||||
sheet.innerHTML += ` .${css} { font-size: ${HTML_TEXT_SIZE}rem }`;
|
sheet.innerHTML += ` .${css} { font-size: ${HTML_TEXT_SIZE}rem }`;
|
||||||
|
sheet.innerHTML += ` .labelled-text > .${css} { font-size: ${HTML_TEXT_SIZE}rem; margin: 0; }`;
|
||||||
}
|
}
|
||||||
text.innerHTML = i18nLocalize(this.text);
|
text.innerHTML = i18nLocalize(this.text);
|
||||||
parent.append(text);
|
parent.append(text);
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { AbstractElement } from './abstract-element';
|
import { AbstractElement } from './abstract-element';
|
||||||
import jsPDF from 'jspdf';
|
import jsPDF from 'jspdf';
|
||||||
import { MARGINS } from '../constants';
|
import { MARGINS } from '../constants';
|
||||||
|
import { IContext } from './context';
|
||||||
|
import { AbstractContainerElement } from './abstract-container-element';
|
||||||
|
|
||||||
export class Row extends AbstractElement {
|
export class Row extends AbstractContainerElement {
|
||||||
public elements: AbstractElement[] = [];
|
|
||||||
public widthPercents?: number[];
|
public widthPercents?: number[];
|
||||||
public maxWidths?: number[];
|
public maxWidths?: number[];
|
||||||
|
|
||||||
@@ -13,16 +14,16 @@ export class Row extends AbstractElement {
|
|||||||
elements: AbstractElement[],
|
elements: AbstractElement[],
|
||||||
maxWidth?: number | undefined,
|
maxWidth?: number | undefined,
|
||||||
widthPercents?: number[],
|
widthPercents?: number[],
|
||||||
maxWidths?: number[]
|
maxWidths?: number[],
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
) {
|
) {
|
||||||
super(x, y, maxWidth);
|
super(x, y, maxWidth, elements, context);
|
||||||
this.elements = elements ?? [];
|
|
||||||
this.widthPercents = widthPercents ?? [];
|
this.widthPercents = widthPercents ?? [];
|
||||||
this.maxWidths = maxWidths ?? [];
|
this.maxWidths = maxWidths ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF {
|
public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF {
|
||||||
const elements = this.elements ?? [];
|
const elements = this.pdfElements ?? [];
|
||||||
let maxWidths = this.maxWidths ?? [];
|
let maxWidths = this.maxWidths ?? [];
|
||||||
let widthPercents = this.widthPercents ?? [];
|
let widthPercents = this.widthPercents ?? [];
|
||||||
|
|
||||||
@@ -68,7 +69,8 @@ export class Row extends AbstractElement {
|
|||||||
): Document {
|
): Document {
|
||||||
const div = doc.createElement('div');
|
const div = doc.createElement('div');
|
||||||
div.classList.add(`row`);
|
div.classList.add(`row`);
|
||||||
const elements = this.elements ?? [];
|
div.classList.add(this.context.name);
|
||||||
|
const elements = this.htmlElements ?? [];
|
||||||
for (let i = 0; i < elements.length; i++) {
|
for (let i = 0; i < elements.length; i++) {
|
||||||
const element = elements[i];
|
const element = elements[i];
|
||||||
element.renderHtml(doc, div, cssRules, sheet);
|
element.renderHtml(doc, div, cssRules, sheet);
|
||||||
@@ -79,7 +81,7 @@ export class Row extends AbstractElement {
|
|||||||
|
|
||||||
public getHeight(doc?: jsPDF): number {
|
public getHeight(doc?: jsPDF): number {
|
||||||
let maxHeight = 0;
|
let maxHeight = 0;
|
||||||
for (const element of this.elements) {
|
for (const element of this.pdfElements) {
|
||||||
maxHeight = Math.max(maxHeight, element.getHeight(doc));
|
maxHeight = Math.max(maxHeight, element.getHeight(doc));
|
||||||
}
|
}
|
||||||
return maxHeight;
|
return maxHeight;
|
||||||
@@ -87,21 +89,9 @@ export class Row extends AbstractElement {
|
|||||||
|
|
||||||
public getCheckNewPageHeight(doc?: jsPDF): number {
|
public getCheckNewPageHeight(doc?: jsPDF): number {
|
||||||
let maxHeight = 0;
|
let maxHeight = 0;
|
||||||
for (const element of this.elements) {
|
for (const element of this.pdfElements) {
|
||||||
maxHeight = Math.max(maxHeight, element.getCheckNewPageHeight(doc));
|
maxHeight = Math.max(maxHeight, element.getCheckNewPageHeight(doc));
|
||||||
}
|
}
|
||||||
return maxHeight;
|
return maxHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getElements(): AbstractElement[] {
|
|
||||||
const elements: AbstractElement[] = [];
|
|
||||||
for (const element of this.elements) {
|
|
||||||
elements.push(...element.getElements());
|
|
||||||
}
|
|
||||||
return elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
public isEmpty(): boolean {
|
|
||||||
return this.elements.length === 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
import { AbstractElement } from './abstract-element';
|
import { AbstractElement } from './abstract-element';
|
||||||
import jsPDF from 'jspdf';
|
import jsPDF from 'jspdf';
|
||||||
import { MARGINS } from '../constants';
|
import { MARGINS } from '../constants';
|
||||||
|
import { IContext } from './context';
|
||||||
|
|
||||||
export class Separator extends AbstractElement {
|
export class Separator extends AbstractElement {
|
||||||
constructor(x: number, y: number, maxWidth?: number | undefined) {
|
constructor(
|
||||||
super(x, y, maxWidth);
|
x: number,
|
||||||
|
y: number,
|
||||||
|
maxWidth?: number | undefined,
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
|
) {
|
||||||
|
super(x, y, maxWidth, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getHeight(_doc?: jsPDF): number {
|
public getHeight(_doc?: jsPDF): number {
|
||||||
@@ -41,6 +47,7 @@ export class Separator extends AbstractElement {
|
|||||||
): Document {
|
): Document {
|
||||||
const div = doc.createElement('div');
|
const div = doc.createElement('div');
|
||||||
div.classList.add(`separator`);
|
div.classList.add(`separator`);
|
||||||
|
div.classList.add(this.context.name);
|
||||||
parent.append(div);
|
parent.append(div);
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { AbstractElement } from './abstract-element';
|
import { AbstractElement } from './abstract-element';
|
||||||
import jsPDF, { TextOptionsLight } from 'jspdf';
|
import jsPDF, { TextOptionsLight } from 'jspdf';
|
||||||
import { HTML_TEXT_SIZE, i18nLocalize, TEXT_SIZE } from '../constants';
|
import { HTML_TEXT_SIZE, i18nLocalize, TEXT_SIZE } from '../constants';
|
||||||
|
import { IContext } from './context';
|
||||||
|
|
||||||
export class Text extends AbstractElement {
|
export class Text extends AbstractElement {
|
||||||
public text: string;
|
public text: string;
|
||||||
@@ -10,9 +11,10 @@ export class Text extends AbstractElement {
|
|||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
text: string,
|
text: string,
|
||||||
textOptions?: TextOptionsLight
|
textOptions?: TextOptionsLight,
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
) {
|
) {
|
||||||
super(x, y, textOptions?.maxWidth);
|
super(x, y, textOptions?.maxWidth, context);
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.textOptions = textOptions;
|
this.textOptions = textOptions;
|
||||||
}
|
}
|
||||||
@@ -46,10 +48,12 @@ export class Text extends AbstractElement {
|
|||||||
const css = `text-${TEXT_SIZE}`;
|
const css = `text-${TEXT_SIZE}`;
|
||||||
text.classList.add(`ellipsis`);
|
text.classList.add(`ellipsis`);
|
||||||
text.classList.add(css);
|
text.classList.add(css);
|
||||||
|
text.classList.add(this.context.name);
|
||||||
text.innerHTML = i18nLocalize(i18nLocalize(this.text));
|
text.innerHTML = i18nLocalize(i18nLocalize(this.text));
|
||||||
if (!cssRules.includes(css)) {
|
if (!cssRules.includes(css)) {
|
||||||
cssRules.push(css);
|
cssRules.push(css);
|
||||||
sheet.innerHTML += ` .${css} { font-size: ${HTML_TEXT_SIZE}rem }`;
|
sheet.innerHTML += ` .${css} { font-size: ${HTML_TEXT_SIZE}rem }`;
|
||||||
|
sheet.innerHTML += ` .labelled-text > .${css} { font-size: ${HTML_TEXT_SIZE}rem; margin: 0; }`;
|
||||||
}
|
}
|
||||||
parent.append(text);
|
parent.append(text);
|
||||||
return doc;
|
return doc;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import jsPDF from 'jspdf';
|
|||||||
import { MARGINS } from '../constants';
|
import { MARGINS } from '../constants';
|
||||||
import { Text } from './text';
|
import { Text } from './text';
|
||||||
import { MultilineText } from './multiline-text';
|
import { MultilineText } from './multiline-text';
|
||||||
|
import { IContext } from './context';
|
||||||
|
import { AbstractElement } from './abstract-element';
|
||||||
|
|
||||||
export class Texts extends Row {
|
export class Texts extends Row {
|
||||||
public texts: string[];
|
public texts: string[];
|
||||||
@@ -14,9 +16,10 @@ export class Texts extends Row {
|
|||||||
y: number,
|
y: number,
|
||||||
texts: string[],
|
texts: string[],
|
||||||
nbrOfCol?: number,
|
nbrOfCol?: number,
|
||||||
multiline = false
|
multiline = false,
|
||||||
|
context: Partial<IContext> = AbstractElement.DEFAULT_CONTEXT
|
||||||
) {
|
) {
|
||||||
super(x, y, []);
|
super(x, y, [], undefined, undefined, undefined, context);
|
||||||
this.texts = texts;
|
this.texts = texts;
|
||||||
this.nbrOfCol = nbrOfCol ?? 4;
|
this.nbrOfCol = nbrOfCol ?? 4;
|
||||||
if (this.nbrOfCol > 4) {
|
if (this.nbrOfCol > 4) {
|
||||||
@@ -34,7 +37,7 @@ export class Texts extends Row {
|
|||||||
rest > 3 ? nbrPerCol + 1 : nbrPerCol,
|
rest > 3 ? nbrPerCol + 1 : nbrPerCol,
|
||||||
];
|
];
|
||||||
for (let i = 0; i < this.nbrOfCol; i++) {
|
for (let i = 0; i < this.nbrOfCol; i++) {
|
||||||
this.elements[i] = new Column(0, 0, []);
|
this.contextElements[i] = new Column(0, 0, []);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < texts.length; i++) {
|
for (let i = 0; i < texts.length; i++) {
|
||||||
if (i < nbrPerCols[0]) {
|
if (i < nbrPerCols[0]) {
|
||||||
@@ -46,7 +49,7 @@ export class Texts extends Row {
|
|||||||
} else {
|
} else {
|
||||||
currentIndex = 3;
|
currentIndex = 3;
|
||||||
}
|
}
|
||||||
(<Column>this.elements[currentIndex]).elements.push(
|
(<Column>this.contextElements[currentIndex]).contextElements.push(
|
||||||
new Row(0, 0, [
|
new Row(0, 0, [
|
||||||
multiline
|
multiline
|
||||||
? new MultilineText(0, 0, texts[i])
|
? new MultilineText(0, 0, texts[i])
|
||||||
@@ -55,7 +58,7 @@ export class Texts extends Row {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.elements.push(
|
this.contextElements.push(
|
||||||
new Column(
|
new Column(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -76,8 +79,8 @@ export class Texts extends Row {
|
|||||||
public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF {
|
public prepareRender(doc: jsPDF, maxWidth?: number): jsPDF {
|
||||||
const pageWidth = doc.internal.pageSize.width;
|
const pageWidth = doc.internal.pageSize.width;
|
||||||
const rowWidth = pageWidth - this.x - MARGINS.right;
|
const rowWidth = pageWidth - this.x - MARGINS.right;
|
||||||
for (const column of this.elements) {
|
for (const column of this.pdfElements) {
|
||||||
for (const labelledValue of (<Column>column).elements) {
|
for (const labelledValue of (<Column>column).pdfElements) {
|
||||||
labelledValue.maxWidth = rowWidth / this.nbrOfCol;
|
labelledValue.maxWidth = rowWidth / this.nbrOfCol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
import { AbstractElement } from './elements/abstract-element';
|
import { AbstractElement } from './elements/abstract-element';
|
||||||
import { AbstractBuilder } from './abstract-builder';
|
import { AbstractBuilder } from './abstract-builder';
|
||||||
import { saveAs } from 'file-saver';
|
import { saveAs } from 'file-saver';
|
||||||
import { i18n } from './constants';
|
import {
|
||||||
|
HTML_LABEL_SIZE,
|
||||||
|
HTML_TEXT_SIZE,
|
||||||
|
i18n,
|
||||||
|
LABEL_SIZE,
|
||||||
|
TEXT_SIZE,
|
||||||
|
} from './constants';
|
||||||
|
|
||||||
export class HtmlBuilder extends AbstractBuilder {
|
export class HtmlBuilder extends AbstractBuilder {
|
||||||
public doc: Document;
|
public doc: Document;
|
||||||
@@ -12,16 +18,26 @@ export class HtmlBuilder extends AbstractBuilder {
|
|||||||
this.doc = document.implementation.createHTMLDocument();
|
this.doc = document.implementation.createHTMLDocument();
|
||||||
const style = document.createElement('style');
|
const style = document.createElement('style');
|
||||||
style.innerHTML = '.column { display: flex; flex-direction: column; }';
|
style.innerHTML = '.column { display: flex; flex-direction: column; }';
|
||||||
|
style.innerHTML += ' .main-column { align-items: center; }';
|
||||||
|
style.innerHTML += ' .row { display: flex; flex-direction: row }';
|
||||||
|
style.innerHTML += ' .row:not(.labelled-value) { gap: 5em; }';
|
||||||
style.innerHTML +=
|
style.innerHTML +=
|
||||||
' .row { display: flex; flex-direction: row; gap: 10px; }';
|
' .row.labelled-value { gap: 10px; justify-content: space-between; }';
|
||||||
style.innerHTML +=
|
style.innerHTML +=
|
||||||
' .separator { border: 1px solid; width: 100%; height: 0px }';
|
' .separator { border: 1px solid; width: 100%; height: 0px }';
|
||||||
style.appendChild(document.createTextNode(''));
|
style.appendChild(document.createTextNode(''));
|
||||||
this.doc.head.appendChild(style);
|
this.doc.head.appendChild(style);
|
||||||
this.styleSheet = style;
|
this.styleSheet = style;
|
||||||
const meta = document.createElement('meta');
|
const meta1 = document.createElement('meta');
|
||||||
meta.setAttribute('charset', 'UTF-8');
|
meta1.setAttribute('charset', 'UTF-8');
|
||||||
this.doc.head.appendChild(meta);
|
this.doc.head.appendChild(meta1);
|
||||||
|
const meta2 = document.createElement('meta');
|
||||||
|
meta2.setAttribute('name', 'viewport');
|
||||||
|
meta2.setAttribute(
|
||||||
|
'content',
|
||||||
|
'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=yes'
|
||||||
|
);
|
||||||
|
this.doc.head.appendChild(meta2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getLabelledRowHeight(): number {
|
public getLabelledRowHeight(): number {
|
||||||
@@ -43,8 +59,31 @@ export class HtmlBuilder extends AbstractBuilder {
|
|||||||
|
|
||||||
public build(elements: AbstractElement[]) {
|
public build(elements: AbstractElement[]) {
|
||||||
const cssList: string[] = [];
|
const cssList: string[] = [];
|
||||||
for (const element of elements) {
|
for (const element of elements.filter((el) => el.context.isHtml)) {
|
||||||
element.renderHtml(this.doc, this.doc.body, cssList, this.styleSheet);
|
element.renderHtml(this.doc, this.doc.body, cssList, this.styleSheet);
|
||||||
}
|
}
|
||||||
|
// Mobile start
|
||||||
|
this.styleSheet.innerHTML += ' @media screen and (max-width: 959px) {';
|
||||||
|
this.styleSheet.innerHTML += ` .text-${TEXT_SIZE} { font-size: ${
|
||||||
|
2 * HTML_TEXT_SIZE
|
||||||
|
}rem; }`;
|
||||||
|
this.styleSheet.innerHTML += ` .labelled-text > .text-${TEXT_SIZE} { font-size: ${
|
||||||
|
2 * HTML_TEXT_SIZE
|
||||||
|
}rem; margin: 0; }`;
|
||||||
|
this.styleSheet.innerHTML += ` .label-${LABEL_SIZE} { font-size: ${
|
||||||
|
2 * HTML_LABEL_SIZE
|
||||||
|
}rem; }`;
|
||||||
|
this.styleSheet.innerHTML +=
|
||||||
|
' .main-column { align-items: stretch; overflow-x: hidden; }';
|
||||||
|
this.styleSheet.innerHTML +=
|
||||||
|
' .row:not(.labelled-value) { flex-wrap: wrap; gap: 0 5em; }';
|
||||||
|
this.styleSheet.innerHTML += ' .skills { width: 100%; }';
|
||||||
|
this.styleSheet.innerHTML += ' .skills-column { width: 100%; }';
|
||||||
|
this.styleSheet.innerHTML += ' }';
|
||||||
|
// Mobile end
|
||||||
|
}
|
||||||
|
|
||||||
|
public getImageScale(): number {
|
||||||
|
return 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
273
src/main.ts
273
src/main.ts
@@ -104,20 +104,31 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
value: item.data.data.total.value,
|
value: item.data.data.total.value,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.sort((a, b) => a.label.localeCompare(b.label))
|
.sort((a, b) => a.label.localeCompare(b.label)),
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
|
{ name: 'skills' }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const talentsByName: { [name: string]: { count: number; test: string } } = {};
|
||||||
|
|
||||||
|
actor.itemCategories.talent.forEach((item) => {
|
||||||
|
const name = item.name;
|
||||||
|
if (talentsByName[name] == null) {
|
||||||
|
talentsByName[name] = { count: 1, test: item.data.data.tests.value };
|
||||||
|
} else {
|
||||||
|
talentsByName[name].count++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const talents = new LabelledValues(
|
const talents = new LabelledValues(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
actor.itemCategories.talent
|
Object.entries(talentsByName)
|
||||||
.map((item) => {
|
.map(([name, value]) => {
|
||||||
return {
|
return {
|
||||||
label:
|
label: value.test.length > 0 ? `${name} : ${value.test}` : name,
|
||||||
item.data.data.tests.value.length > 0
|
value: value.count,
|
||||||
? `${item.name} : ${item.data.data.tests.value}`
|
|
||||||
: item.name,
|
|
||||||
value: item.data.data.advances.value,
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.sort((a, b) => a.label.localeCompare(b.label)),
|
.sort((a, b) => a.label.localeCompare(b.label)),
|
||||||
@@ -376,22 +387,40 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
|
|
||||||
const labelledRowHeight = docBuilder.getLabelledRowHeight();
|
const labelledRowHeight = docBuilder.getLabelledRowHeight();
|
||||||
|
|
||||||
const imageWidth = 25;
|
const imageWidth = 25 * docBuilder.getImageScale();
|
||||||
const imageY = labelledRowHeight + MARGINS.top + 2;
|
const imageY = labelledRowHeight + MARGINS.top + 2;
|
||||||
const actorImageElement =
|
const actorImageElementPdf =
|
||||||
actorImageData != null
|
actorImageData != null
|
||||||
? new Image(0, imageY, imageWidth, imageWidth, actorImageData)
|
? new Image(0, imageY, imageWidth, imageWidth, actorImageData, {
|
||||||
: new Box(0, imageY, imageWidth, imageWidth);
|
isHtml: false,
|
||||||
|
})
|
||||||
|
: new Box(0, imageY, imageWidth, imageWidth, {
|
||||||
|
isHtml: false,
|
||||||
|
});
|
||||||
|
const actorImageElementHtml =
|
||||||
|
actorImageData != null
|
||||||
|
? new Image(0, imageY, imageWidth, imageWidth, actorImageData, {
|
||||||
|
isPdf: false,
|
||||||
|
})
|
||||||
|
: new Box(0, imageY, imageWidth, imageWidth, {
|
||||||
|
isPdf: false,
|
||||||
|
});
|
||||||
|
|
||||||
docBuilder.build([
|
docBuilder.build([
|
||||||
actorImageElement,
|
actorImageElementPdf,
|
||||||
new Column(0, 0, [
|
new Column(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
[
|
||||||
new Row(0, 0, [
|
new Row(0, 0, [
|
||||||
new LabelledText(0, 0, 'Name', `${actor.name}`),
|
new LabelledText(0, 0, 'Name', `${actor.name}`),
|
||||||
new LabelledText(0, 0, 'Species', `${actorDetails?.species?.value}`),
|
new LabelledText(0, 0, 'Species', `${actorDetails?.species?.value}`),
|
||||||
new LabelledText(0, 0, 'Gender', `${actorDetails?.gender?.value}`),
|
new LabelledText(0, 0, 'Gender', `${actorDetails?.gender?.value}`),
|
||||||
]),
|
]),
|
||||||
new Row(imageWidth + MARGINS.left + 1, 0, [
|
new Row(
|
||||||
|
imageWidth + MARGINS.left + 1,
|
||||||
|
0,
|
||||||
|
[
|
||||||
new LabelledText(0, 0, 'Class', `${careerDetail?.class?.value}`),
|
new LabelledText(0, 0, 'Class', `${careerDetail?.class?.value}`),
|
||||||
new LabelledText(
|
new LabelledText(
|
||||||
0,
|
0,
|
||||||
@@ -400,12 +429,101 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
`${careerDetail?.careergroup?.value}`
|
`${careerDetail?.careergroup?.value}`
|
||||||
),
|
),
|
||||||
new LabelledText(0, 0, 'Career', `${currentCareer?.name}`),
|
new LabelledText(0, 0, 'Career', `${currentCareer?.name}`),
|
||||||
|
],
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
{ isHtml: false }
|
||||||
|
),
|
||||||
|
new Row(
|
||||||
|
imageWidth + MARGINS.left + 1,
|
||||||
|
0,
|
||||||
|
[
|
||||||
|
new LabelledText(0, 0, 'Status', `${actorDetails?.status?.value}`),
|
||||||
|
new LabelledText(0, 0, 'Age', `${actorDetails?.age?.value}`),
|
||||||
|
new LabelledText(0, 0, 'Height', `${actorDetails?.height?.value}`),
|
||||||
|
new LabelledText(0, 0, 'Weight', `${actorDetails?.weight?.value}`),
|
||||||
|
new LabelledText(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'Hair Colour',
|
||||||
|
`${actorDetails?.haircolour?.value}`
|
||||||
|
),
|
||||||
|
],
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
{ isHtml: false }
|
||||||
|
),
|
||||||
|
new Row(
|
||||||
|
imageWidth + MARGINS.left + 1,
|
||||||
|
0,
|
||||||
|
[
|
||||||
|
new LabelledText(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'Eye Colour',
|
||||||
|
`${actorDetails?.eyecolour?.value}`
|
||||||
|
),
|
||||||
|
new LabelledText(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'Distinguishing Mark',
|
||||||
|
`${actorDetails?.distinguishingmark?.value}`
|
||||||
|
),
|
||||||
|
new LabelledText(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'Star Sign',
|
||||||
|
`${actorDetails?.starsign?.value}`
|
||||||
|
),
|
||||||
|
],
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
{ isHtml: false }
|
||||||
|
),
|
||||||
|
new Row(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
[
|
||||||
|
actorImageElementHtml,
|
||||||
|
new Column(0, 0, [
|
||||||
|
new Row(imageWidth + MARGINS.left + 1, 0, [
|
||||||
|
new LabelledText(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'Class',
|
||||||
|
`${careerDetail?.class?.value}`
|
||||||
|
),
|
||||||
|
new LabelledText(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'Career Group',
|
||||||
|
`${careerDetail?.careergroup?.value}`
|
||||||
|
),
|
||||||
|
new LabelledText(0, 0, 'Career', `${currentCareer?.name}`),
|
||||||
]),
|
]),
|
||||||
new Row(imageWidth + MARGINS.left + 1, 0, [
|
new Row(imageWidth + MARGINS.left + 1, 0, [
|
||||||
new LabelledText(0, 0, 'Status', `${actorDetails?.status?.value}`),
|
new LabelledText(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'Status',
|
||||||
|
`${actorDetails?.status?.value}`
|
||||||
|
),
|
||||||
new LabelledText(0, 0, 'Age', `${actorDetails?.age?.value}`),
|
new LabelledText(0, 0, 'Age', `${actorDetails?.age?.value}`),
|
||||||
new LabelledText(0, 0, 'Height', `${actorDetails?.height?.value}`),
|
new LabelledText(
|
||||||
new LabelledText(0, 0, 'Weight', `${actorDetails?.weight?.value}`),
|
0,
|
||||||
|
0,
|
||||||
|
'Height',
|
||||||
|
`${actorDetails?.height?.value}`
|
||||||
|
),
|
||||||
|
new LabelledText(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'Weight',
|
||||||
|
`${actorDetails?.weight?.value}`
|
||||||
|
),
|
||||||
new LabelledText(
|
new LabelledText(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -426,8 +544,20 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
'Distinguishing Mark',
|
'Distinguishing Mark',
|
||||||
`${actorDetails?.distinguishingmark?.value}`
|
`${actorDetails?.distinguishingmark?.value}`
|
||||||
),
|
),
|
||||||
new LabelledText(0, 0, 'Star Sign', `${actorDetails?.starsign?.value}`),
|
new LabelledText(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'Star Sign',
|
||||||
|
`${actorDetails?.starsign?.value}`
|
||||||
|
),
|
||||||
]),
|
]),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
{ isPdf: false }
|
||||||
|
),
|
||||||
Blank.heightBlank(2),
|
Blank.heightBlank(2),
|
||||||
new Row(0, 0, [
|
new Row(0, 0, [
|
||||||
new LabelledText(0, 0, 'CHARAbbrev.WS', `${actorCharacs?.ws?.value}`),
|
new LabelledText(0, 0, 'CHARAbbrev.WS', `${actorCharacs?.ws?.value}`),
|
||||||
@@ -436,10 +566,25 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
new LabelledText(0, 0, 'CHARAbbrev.T', `${actorCharacs?.t?.value}`),
|
new LabelledText(0, 0, 'CHARAbbrev.T', `${actorCharacs?.t?.value}`),
|
||||||
new LabelledText(0, 0, 'CHARAbbrev.I', `${actorCharacs?.i?.value}`),
|
new LabelledText(0, 0, 'CHARAbbrev.I', `${actorCharacs?.i?.value}`),
|
||||||
new LabelledText(0, 0, 'CHARAbbrev.Ag', `${actorCharacs?.ag?.value}`),
|
new LabelledText(0, 0, 'CHARAbbrev.Ag', `${actorCharacs?.ag?.value}`),
|
||||||
new LabelledText(0, 0, 'CHARAbbrev.Dex', `${actorCharacs?.dex?.value}`),
|
new LabelledText(
|
||||||
new LabelledText(0, 0, 'CHARAbbrev.Int', `${actorCharacs?.int?.value}`),
|
0,
|
||||||
|
0,
|
||||||
|
'CHARAbbrev.Dex',
|
||||||
|
`${actorCharacs?.dex?.value}`
|
||||||
|
),
|
||||||
|
new LabelledText(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'CHARAbbrev.Int',
|
||||||
|
`${actorCharacs?.int?.value}`
|
||||||
|
),
|
||||||
new LabelledText(0, 0, 'CHARAbbrev.WP', `${actorCharacs?.wp?.value}`),
|
new LabelledText(0, 0, 'CHARAbbrev.WP', `${actorCharacs?.wp?.value}`),
|
||||||
new LabelledText(0, 0, 'CHARAbbrev.Fel', `${actorCharacs?.fel?.value}`),
|
new LabelledText(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'CHARAbbrev.Fel',
|
||||||
|
`${actorCharacs?.fel?.value}`
|
||||||
|
),
|
||||||
]),
|
]),
|
||||||
new Row(0, 0, [
|
new Row(0, 0, [
|
||||||
new LabelledText(0, 0, 'Move', `${actorDetails?.move?.value}`),
|
new LabelledText(0, 0, 'Move', `${actorDetails?.move?.value}`),
|
||||||
@@ -467,15 +612,17 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
new Separator(0, 0),
|
new Separator(0, 0),
|
||||||
new Text(0, 0, `${i18nLocalize('Talents')} : ${i18nLocalize('Tests')}`),
|
new Text(0, 0, `${i18nLocalize('Talents')} : ${i18nLocalize('Tests')}`),
|
||||||
talents,
|
talents,
|
||||||
traits.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0),
|
traits.contextElements.length > 0
|
||||||
traits.elements.length > 0
|
? new Separator(0, 0)
|
||||||
|
: Blank.heightBlank(0),
|
||||||
|
traits.contextElements.length > 0
|
||||||
? new Text(0, 0, 'Traits')
|
? new Text(0, 0, 'Traits')
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
traits,
|
traits,
|
||||||
weaponsMelee.elements.length > 0
|
weaponsMelee.contextElements.length > 0
|
||||||
? new Separator(0, 0)
|
? new Separator(0, 0)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
weaponsMelee.elements.length > 0
|
weaponsMelee.contextElements.length > 0
|
||||||
? new Text(
|
? new Text(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -487,10 +634,10 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
)
|
)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
weaponsMelee,
|
weaponsMelee,
|
||||||
weaponsRanged.elements.length > 0
|
weaponsRanged.contextElements.length > 0
|
||||||
? new Separator(0, 0)
|
? new Separator(0, 0)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
weaponsRanged.elements.length > 0
|
weaponsRanged.contextElements.length > 0
|
||||||
? new Text(
|
? new Text(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -502,10 +649,10 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
)
|
)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
weaponsRanged,
|
weaponsRanged,
|
||||||
ammunitions.elements.length > 0
|
ammunitions.contextElements.length > 0
|
||||||
? new Separator(0, 0)
|
? new Separator(0, 0)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
ammunitions.elements.length > 0
|
ammunitions.contextElements.length > 0
|
||||||
? new Text(
|
? new Text(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -517,13 +664,17 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
)
|
)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
ammunitions,
|
ammunitions,
|
||||||
armours.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0),
|
armours.contextElements.length > 0
|
||||||
armours.elements.length > 0
|
? new Separator(0, 0)
|
||||||
|
: Blank.heightBlank(0),
|
||||||
|
armours.contextElements.length > 0
|
||||||
? new Text(0, 0, 'Armour')
|
? new Text(0, 0, 'Armour')
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
armours,
|
armours,
|
||||||
petty.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0),
|
petty.contextElements.length > 0
|
||||||
petty.elements.length > 0
|
? new Separator(0, 0)
|
||||||
|
: Blank.heightBlank(0),
|
||||||
|
petty.contextElements.length > 0
|
||||||
? new Text(
|
? new Text(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -535,8 +686,10 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
)
|
)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
petty,
|
petty,
|
||||||
spell.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0),
|
spell.contextElements.length > 0
|
||||||
spell.elements.length > 0
|
? new Separator(0, 0)
|
||||||
|
: Blank.heightBlank(0),
|
||||||
|
spell.contextElements.length > 0
|
||||||
? new Text(
|
? new Text(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -550,8 +703,10 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
)
|
)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
spell,
|
spell,
|
||||||
blessing.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0),
|
blessing.contextElements.length > 0
|
||||||
blessing.elements.length > 0
|
? new Separator(0, 0)
|
||||||
|
: Blank.heightBlank(0),
|
||||||
|
blessing.contextElements.length > 0
|
||||||
? new Text(
|
? new Text(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -561,8 +716,10 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
)
|
)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
blessing,
|
blessing,
|
||||||
miracle.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0),
|
miracle.contextElements.length > 0
|
||||||
miracle.elements.length > 0
|
? new Separator(0, 0)
|
||||||
|
: Blank.heightBlank(0),
|
||||||
|
miracle.contextElements.length > 0
|
||||||
? new Text(
|
? new Text(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -575,32 +732,38 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
new Separator(0, 0),
|
new Separator(0, 0),
|
||||||
trappingsHeader,
|
trappingsHeader,
|
||||||
trappings,
|
trappings,
|
||||||
psychology.elements.length > 0
|
psychology.contextElements.length > 0
|
||||||
? new Separator(0, 0)
|
? new Separator(0, 0)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
psychology.elements.length > 0
|
psychology.contextElements.length > 0
|
||||||
? new Text(0, 0, 'Psychology')
|
? new Text(0, 0, 'Psychology')
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
psychology,
|
psychology,
|
||||||
critical.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0),
|
critical.contextElements.length > 0
|
||||||
critical.elements.length > 0
|
? new Separator(0, 0)
|
||||||
|
: Blank.heightBlank(0),
|
||||||
|
critical.contextElements.length > 0
|
||||||
? new Text(0, 0, 'Criticals')
|
? new Text(0, 0, 'Criticals')
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
critical,
|
critical,
|
||||||
disease.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0),
|
disease.contextElements.length > 0
|
||||||
disease.elements.length > 0
|
? new Separator(0, 0)
|
||||||
|
: Blank.heightBlank(0),
|
||||||
|
disease.contextElements.length > 0
|
||||||
? new Text(0, 0, 'Diseases')
|
? new Text(0, 0, 'Diseases')
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
disease,
|
disease,
|
||||||
injury.elements.length > 0 ? new Separator(0, 0) : Blank.heightBlank(0),
|
injury.contextElements.length > 0
|
||||||
injury.elements.length > 0
|
? new Separator(0, 0)
|
||||||
|
: Blank.heightBlank(0),
|
||||||
|
injury.contextElements.length > 0
|
||||||
? new Text(0, 0, 'Injuries')
|
? new Text(0, 0, 'Injuries')
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
injury,
|
injury,
|
||||||
mutationP.elements.length > 0
|
mutationP.contextElements.length > 0
|
||||||
? new Separator(0, 0)
|
? new Separator(0, 0)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
mutationP.elements.length > 0
|
mutationP.contextElements.length > 0
|
||||||
? new Text(
|
? new Text(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -608,10 +771,10 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
)
|
)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
mutationP,
|
mutationP,
|
||||||
mutationM.elements.length > 0
|
mutationM.contextElements.length > 0
|
||||||
? new Separator(0, 0)
|
? new Separator(0, 0)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
mutationM.elements.length > 0
|
mutationM.contextElements.length > 0
|
||||||
? new Text(
|
? new Text(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -619,7 +782,11 @@ async function generate(actor: Actor & any, docBuilder: AbstractBuilder) {
|
|||||||
)
|
)
|
||||||
: Blank.heightBlank(0),
|
: Blank.heightBlank(0),
|
||||||
mutationM,
|
mutationM,
|
||||||
]),
|
],
|
||||||
|
{
|
||||||
|
name: 'main-column',
|
||||||
|
}
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
docBuilder.save(`${actor.name}`);
|
docBuilder.save(`${actor.name}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export class PdfBuilder extends AbstractBuilder {
|
|||||||
|
|
||||||
public build(elements: AbstractElement[]) {
|
public build(elements: AbstractElement[]) {
|
||||||
const finalElements: AbstractElement[] = [];
|
const finalElements: AbstractElement[] = [];
|
||||||
for (const element of elements) {
|
for (const element of elements.filter((el) => el.context.isPdf)) {
|
||||||
element.prepareRender(this.doc);
|
element.prepareRender(this.doc);
|
||||||
finalElements.push(...element.getElements());
|
finalElements.push(...element.getElements());
|
||||||
}
|
}
|
||||||
@@ -69,4 +69,8 @@ export class PdfBuilder extends AbstractBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getImageScale(): number {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user