Skip to content

Commit

Permalink
Support comment question split into multiple pages (#336)
Browse files Browse the repository at this point in the history
* Support comment question split into multiple pages

* Make pdf snapshots to be passed on all hosts
  • Loading branch information
dk981234 authored Sep 10, 2024
1 parent 89eb8d5 commit c0c113e
Show file tree
Hide file tree
Showing 16 changed files with 277 additions and 89 deletions.
2 changes: 2 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
process.env.TZ = 'GMT';

module.exports = {
globals: {
"ts-jest": {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"start": "npm run build_dev && live-server --port=7777",
"serve": "live-server --port=7777",
"test": "jest",
"test:update-snapshots": "jest --config './jest.update_snapshots.config.js'",
"test:update-snapshots": "jest --config ./jest.update_snapshots.config.js",
"testDev": "jest --watch",
"release": "standard-version --message \"Release: %s [azurepipelines skip]\" ",
"doc_gen": "node doc_generator/lib_docgenerator.js src/entries/pdf.ts",
Expand Down Expand Up @@ -56,4 +56,4 @@
"pre-push": "npm run pre-push-check"
}
}
}
}
3 changes: 3 additions & 0 deletions src/doc_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,9 @@ export class DocController extends DocOptions {
public addPage(): void {
this.doc.addPage();
}
public getCurrentPageIndex(): number {
return this.doc.getCurrentPageInfo().pageNumber - 1;
}
public setPage(index: number): void {
this.doc.setPage(index + 1);
}
Expand Down
9 changes: 6 additions & 3 deletions src/helper_survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,9 @@ export class SurveyHelper {
if(options.readOnly !== null && options.readOnly !== undefined) {
comment.isReadOnly = options.readOnly;
}
comment.textBrick = textFlat;
if(textFlat) {
comment.textBrick = textFlat;
}
return comment;
}
public static getQuestionOrCommentValue(question: Question, isQuestion: boolean = true): string {
Expand Down Expand Up @@ -573,7 +575,8 @@ export class SurveyHelper {
controller.popMargins();
return textFlat;
}
public static renderFlatBorders(controller: DocController, flat: PdfBrick): void {

public static renderFlatBorders(controller: DocController, flat: IRect & ISize & Pick<PdfBrick, 'formBorderColor'>): void {
if (!this.FORM_BORDER_VISIBLE) return;
const minSide: number = Math.min(flat.width, flat.height);
const visibleWidth: number = controller.unitHeight * this.VISIBLE_BORDER_SCALE * this.BORDER_SCALE;
Expand Down Expand Up @@ -679,7 +682,7 @@ export class SurveyHelper {
yBot: rect.yBot - scaleWidth
};
}
public static formScale(controller: DocController, flat: PdfBrick): number {
public static formScale(controller: DocController, flat: ISize): number {
const minSide: number = Math.min(flat.width, flat.height);
const borderWidth: number = 2.0 * controller.unitWidth * this.BORDER_SCALE;
return (minSide - borderWidth) / minSide;
Expand Down
5 changes: 5 additions & 0 deletions src/helper_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Question } from 'survey-core';
import { IPoint, IRect, IDocOptions, DocOptions } from './doc_controller';
import { IPdfBrick, PdfBrick } from './pdf_render/pdf_brick';
import { SurveyHelper } from './helper_survey';
import { SurveyPDF } from './survey';

export class TestHelper {
public static readonly BASE64_IMAGE_16PX: string = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAA3NCSVQICAjb4U/gAAAAt1BMVEVHcExTXGROYmJIT1ZPXmVJV11ES1JYZ24+SE5JU1s+R0xVYmtYZW1ETlRRXWVUYWpKV1xZZ25YZW5YanNrfIdTYWlaZ29nd4JUYmhIU1lHUVtRXWQ+SlA6QkouNzpFT1ZCS1JSXWVxhI98kp53iZZSXmVcaXE5QkdCTFNndn9WY2tZZm5canJfbXVbZ29hcHlXZGxtfYVNWmFRXWVCTFNKVl04QEdoeINnZGxrc3uAk6Fzb3dxg43scHiMAAAAKnRSTlMALwQXZU4MImyJQbCrPOPZRdOHx4X4t2fR0SfsoHhYseyioqbHwOy+59gMe1UiAAAAuElEQVQYlU2P5xKCQAyEI1gABVSKUu3tOgL2938u74Ybx/2xk3yT2SQAPw2Yb8KfRp6VzAxVDDVwYej1ZbHbG9tQTy030sJP+1po4MfSZs+qsrp+KubSg8e7Wq8mk/E44LinwqJr22IskCA4UgBiUqueUUqJ2gLzO0MCC8Ypx1MFXEIEqhFGjB/0zTXNbPvcXOkx7YjFbYDydsq7DIAeKyS9mSYadGBR51A0JVwy/dcyScFxwLAdgC+IFhIbrHyDqAAAAABJRU5ErkJggg==';
Expand Down Expand Up @@ -69,4 +70,8 @@ export class TestHelper {
SurveyHelper.getLocString(question.locTitle) +
(question.isRequired ? question.requiredText : '');
}
}

export class SurveyPDFTester extends SurveyPDF {
public get haveCommercialLicense(): boolean { return true; }
}
2 changes: 2 additions & 0 deletions src/pdf_render/pdf_brick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,13 @@ export class PdfBrick implements IPdfBrick {
protected getShouldRenderReadOnly(): boolean {
return SurveyHelper.shouldRenderReadOnly(this.question, this.controller);
}
public afterRenderCallback: () => void;
public async render(): Promise<void> {
if (this.getShouldRenderReadOnly()) {
await this.renderReadOnly();
}
else await this.renderInteractive();
this.afterRenderCallback && this.afterRenderCallback();
}
public async renderInteractive(): Promise<void> { }
public async renderReadOnly(): Promise<void> {
Expand Down
61 changes: 56 additions & 5 deletions src/pdf_render/pdf_textfield.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { IQuestion, QuestionTextModel, settings } from 'survey-core';
import { IRect, DocController } from '../doc_controller';
import { IPdfBrick, PdfBrick, TranslateXFunction } from './pdf_brick';
import { SurveyHelper } from '../helper_survey';
import { CompositeBrick } from './pdf_composite';

export class TextFieldBrick extends PdfBrick {
protected question: QuestionTextModel;
Expand Down Expand Up @@ -48,26 +49,76 @@ export class TextFieldBrick extends PdfBrick {
this.controller.doc.addField(inputField);
SurveyHelper.renderFlatBorders(this.controller, this);
}
protected shouldRenderFlatBorders() {
protected shouldRenderFlatBorders(): boolean {
return settings.readOnlyTextRenderMode === 'input';
}
protected getShouldRenderReadOnly(): boolean {
return SurveyHelper.shouldRenderReadOnly(this.question, this.controller, this.isReadOnly);
}
public textBrick: IPdfBrick;
private _textBrick: IPdfBrick;
public get textBrick(): IPdfBrick {
return this._textBrick;
}
public set textBrick(val: IPdfBrick) {
this._textBrick = val;
const unFoldedBricks = val.unfold();
const bricksCount = unFoldedBricks.length;
let renderedBricksCount = 0;
const bricksByPage: { [index: number]: Array<PdfBrick> } = {};
const afterRenderTextBrickCallback = (brick: PdfBrick) => {
if(this.shouldRenderFlatBorders()) {
renderedBricksCount++;
const currentPageNumber = this.controller.getCurrentPageIndex();
if(!bricksByPage[currentPageNumber]) {
bricksByPage[currentPageNumber] = [];
}
bricksByPage[currentPageNumber].push(brick);
if(renderedBricksCount >= bricksCount) {
const keys = Object.keys(bricksByPage);
const renderedOnOnePage = keys.length == 1;
keys.forEach((key: string) => {
const compositeBrick = new CompositeBrick();
bricksByPage[key as any].forEach((brick: PdfBrick) => {
compositeBrick.addBrick(brick);
});
const padding = this.controller.unitHeight * SurveyHelper.VALUE_READONLY_PADDING_SCALE;
const borderRect = {
xLeft: this.xLeft,
xRight: this.xRight,
width: this.width,
yTop: renderedOnOnePage ? this.yTop : compositeBrick.yTop - padding,
yBot: renderedOnOnePage ? this.yBot : compositeBrick.yBot + padding,
height: renderedOnOnePage ? this.height : compositeBrick.height + 2 * padding,
formBorderColor: this.formBorderColor,
};
this.controller.setPage(Number(key));
SurveyHelper.renderFlatBorders(this.controller, borderRect);
this.controller.setPage(currentPageNumber);
});
}
}
};
unFoldedBricks.forEach((brick: PdfBrick) => {
brick.afterRenderCallback = afterRenderTextBrickCallback.bind(this, brick);
});
}
public async renderReadOnly(): Promise<void> {
this.controller.pushMargins(this.xLeft,
this.controller.paperWidth - this.xRight);
if (this.inputType === 'color') {
this.renderColorQuestion();
} else {
await this.textBrick.render();
if(this.shouldRenderFlatBorders()) {
SurveyHelper.renderFlatBorders(this.controller, this);
}
}
this.controller.popMargins();
}
public unfold(): IPdfBrick[] {
if (this.getShouldRenderReadOnly() && this.inputType !== 'color') {
return this.textBrick.unfold();
} else {
return super.unfold();
}
}
public translateX(func: TranslateXFunction): void {
const res = func(this.xLeft, this.xRight);
this._xLeft = res.xLeft;
Expand Down
5 changes: 1 addition & 4 deletions tests/event_header.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { PagePacker } from '../src/page_layout/page_packer';
import { IPdfBrick } from '../src/pdf_render/pdf_brick';
import { TextBoldBrick } from '../src/pdf_render/pdf_textbold';
import { SurveyHelper } from '../src/helper_survey';
import { TestHelper } from '../src/helper_test';
import { SurveyPDFTester, TestHelper } from '../src/helper_test';
let __dummy_tx = new FlatTextbox(null, null, null);

test('Event render header simple text', async () => {
Expand Down Expand Up @@ -176,9 +176,6 @@ test('Event render footer center middle text', async () => {
};
TestHelper.equalRect(expect, packs[0][1], assumeText);
});
class SurveyPDFTester extends SurveyPDF {
public get haveCommercialLicense(): boolean { return true; }
}
test('Have commercial license: true', async () => {
let json: any = {
questions: [
Expand Down
79 changes: 26 additions & 53 deletions tests/flat_matrixdynamic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { RowlineBrick } from '../src/pdf_render/pdf_rowline';
import { SurveyHelper } from '../src/helper_survey';
import { TestHelper } from '../src/helper_test';
import { CompositeBrick } from '../src/pdf_render/pdf_composite';
import { checkFlatSnapshot } from './snapshot_helper';
import { AdornersOptions } from '../src/event_handler/adorners';
let __dummy_dd = new FlatDropdown(null, null, null);
let __dummy_md = new FlatMatrixDynamic(null, null, null);
let __dummy_tx = new FlatExpression(null, null, null);
Expand Down Expand Up @@ -481,60 +483,31 @@ test('Check matrix dynamic two columns one row narrow width', async () => {
TestHelper.equalRect(expect, flats[0][0], assumeMatrix);
});
test('Check matrixdynamic with totals', async () => {
let json: any = {
showQuestionNumbers: 'off',
elements: [
{
await checkFlatSnapshot(
{
showQuestionNumbers: 'off',
elements: [
{

type: 'matrixdynamic',
name: 'madintotals',
showHeader: false,
rowCount: 1,
titleLocation: 'hidden',
columns: [
{
totalType: 'sum',
totalFormat: 'test',
name: 'id'
}
]
}
]
};
let survey: SurveyPDF = new SurveyPDF(json, TestHelper.defaultOptions);
let controller: DocController = new DocController(TestHelper.defaultOptions);
let flats: IPdfBrick[][] = await FlatSurvey.generateFlats(survey, controller);
expect(flats.length).toBe(1);
expect(flats[0].length).toBe(2);
controller.margins.left += controller.unitWidth;
let unfoldRow1Flats: IPdfBrick[] = await flats[0][0].unfold();
expect(unfoldRow1Flats.length).toBe(2);
let unfolFooterFlats: IPdfBrick[] = flats[0][1].unfold();
expect(unfolFooterFlats.length).toBe(1);
let assumeQuestion1: IRect = {
xLeft: controller.leftTopPoint.xLeft,
xRight: controller.paperWidth - controller.margins.right,
yTop: controller.leftTopPoint.yTop + SurveyHelper.EPSILON,
yBot: controller.leftTopPoint.yTop + SurveyHelper.EPSILON +
controller.unitHeight
};
expect(unfoldRow1Flats[1] instanceof RowlineBrick).toBe(true);
TestHelper.equalRect(expect, unfoldRow1Flats[0], assumeQuestion1);
let assumeFooter: IRect = {
xLeft: controller.leftTopPoint.xLeft,
xRight: controller.paperWidth - controller.margins.right,
yTop: assumeQuestion1.yBot + SurveyHelper.EPSILON + FlatMatrixDynamic.GAP_BETWEEN_ROWS * controller.unitHeight,
yBot: assumeQuestion1.yBot + SurveyHelper.EPSILON +
controller.unitHeight * (1 + FlatMatrixDynamic.GAP_BETWEEN_ROWS + 2 * SurveyHelper.VALUE_READONLY_PADDING_SCALE)
};
TestHelper.equalRect(expect, unfolFooterFlats[0], assumeFooter);
let assumeMatrix: IRect = {
xLeft: controller.leftTopPoint.xLeft,
xRight: controller.paperWidth - controller.margins.right,
yTop: controller.leftTopPoint.yTop,
yBot: assumeFooter.yBot
};
TestHelper.equalRect(expect, SurveyHelper.mergeRects(...flats[0]), assumeMatrix);
type: 'matrixdynamic',
name: 'madintotals',
showHeader: false,
rowCount: 1,
titleLocation: 'hidden',
columns: [
{
totalType: 'sum',
totalFormat: 'test',
name: 'id'
}
]
}
]
}, {
snapshotName: 'matrixdynamic_with_totals',
isCorrectEvent: (options: AdornersOptions) => {
return options.question.getType() == 'matrixdynamic';
} });
});
test('Check matrix dynamic column width', async () => {
let json: any = {
Expand Down
12 changes: 6 additions & 6 deletions tests/flat_matrixmultiple.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { TestHelper } from '../src/helper_test';
import { QuestionMatrixDropdownModel } from 'survey-core';
import { FlatRepository } from '../src/flat_layout/flat_repository';
import { CompositeBrick } from '../src/pdf_render/pdf_composite';
import { checkFlatSnapshots } from './snapshot_helper';
import { checkFlatSnapshot } from './snapshot_helper';
import { AdornersOptions } from '../src/event_handler/adorners';
let __dummy_dd = new FlatDropdown(null, null, null);
let __dummy_mm = new FlatMatrixMultiple(null, null, null);
Expand Down Expand Up @@ -823,7 +823,7 @@ test('Check matrix multiple zero columns one row with detailPanel', async () =>
test('Check matrix multiple with showInMulipleColumns - list mode', async () => {
const controllerOptions = TestHelper.defaultOptions;
controllerOptions.matrixRenderAs = 'list';
await checkFlatSnapshots({
await checkFlatSnapshot({
questions: [
{
'type': 'matrixdropdown',
Expand Down Expand Up @@ -861,7 +861,7 @@ test('Check matrix multiple with showInMulipleColumns - list mode', async () =>
test('Check matrix multiple with showInMulipleColumns and totals - wide mode', async () => {
const controllerOptions = TestHelper.defaultOptions;
controllerOptions.format = 'a3';
await checkFlatSnapshots({
await checkFlatSnapshot({
questions: [
{
'type': 'matrixdropdown',
Expand Down Expand Up @@ -900,7 +900,7 @@ test('Check matrix multiple with showInMulipleColumns and totals - wide mode', a
test('Check matrix multiple with showInMulipleColumns and totals - list mode', async () => {
const controllerOptions = TestHelper.defaultOptions;
controllerOptions.matrixRenderAs = 'list';
await checkFlatSnapshots({
await checkFlatSnapshot({
questions: [
{
'type': 'matrixdropdown',
Expand Down Expand Up @@ -939,7 +939,7 @@ test('Check matrix multiple with showInMulipleColumns and totals - list mode', a
test('Check matrix multiple with empty totals - list mode', async () => {
const controllerOptions = TestHelper.defaultOptions;
controllerOptions.matrixRenderAs = 'list';
await checkFlatSnapshots({
await checkFlatSnapshot({
questions: [
{
'type': 'matrixdropdown',
Expand Down Expand Up @@ -972,7 +972,7 @@ test('Check matrix multiple with empty totals - list mode', async () => {
test('Check matrix multiple with empty totals - wide mode', async () => {
const controllerOptions = TestHelper.defaultOptions;
controllerOptions.format = 'a3';
await checkFlatSnapshots({
await checkFlatSnapshot({
questions: [
{
'type': 'matrixdropdown',
Expand Down
Loading

0 comments on commit c0c113e

Please sign in to comment.