Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support comment question split into multiple pages #336

Merged
merged 2 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading