Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { SpinnerModule } from '@oort-front/ui';
import { UnsubscribeComponent } from '../utils/unsubscribe/unsubscribe.component';
import {
FormHelpersService,
TemporaryFilesStorage,
transformSurveyData,
} from '../../services/form-helper/form-helper.service';
import { DialogModule } from '@oort-front/ui';
Expand Down Expand Up @@ -97,7 +98,7 @@ export class FormModalComponent
private storedMergedData: any;

public survey!: SurveyModel;
protected temporaryFilesStorage: any = {};
protected temporaryFilesStorage: TemporaryFilesStorage = {};

@ViewChild('formContainer') formContainer!: ElementRef;

Expand Down
7 changes: 5 additions & 2 deletions libs/shared/src/lib/components/form/form.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ import { FormBuilderService } from '../../services/form-builder/form-builder.ser
import { RecordHistoryComponent } from '../record-history/record-history.component';
import { TranslateService } from '@ngx-translate/core';
import { UnsubscribeComponent } from '../utils/unsubscribe/unsubscribe.component';
import { FormHelpersService } from '../../services/form-helper/form-helper.service';
import {
FormHelpersService,
TemporaryFilesStorage,
} from '../../services/form-helper/form-helper.service';
import { SnackbarService, UILayoutService } from '@oort-front/ui';
import { cloneDeep } from 'lodash';

Expand Down Expand Up @@ -55,7 +58,7 @@ export class FormComponent
/** Indicates whether the search is active */
public surveyActive = true;
/** Temporary storage for files */
public temporaryFilesStorage: Record<string, Array<File>> = {};
public temporaryFilesStorage: TemporaryFilesStorage = {};
/** Reference to the form container element */
@ViewChild('formContainer') formContainer!: ElementRef;
/** Date when the form was last modified */
Expand Down
31 changes: 27 additions & 4 deletions libs/shared/src/lib/services/form-builder/form-builder.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { BehaviorSubject } from 'rxjs';
import { SnackbarService } from '@oort-front/ui';
import {
FormHelpersService,
TemporaryFilesStorage,
transformSurveyData,
} from '../form-helper/form-helper.service';
import { difference } from 'lodash';
Expand Down Expand Up @@ -258,7 +259,7 @@ export class FormBuilderService {
public addEventsCallBacksToSurvey(
survey: SurveyModel,
selectedPageIndex: BehaviorSubject<number>,
temporaryFilesStorage: Record<string, Array<File>>
temporaryFilesStorage: TemporaryFilesStorage
) {
survey.onAfterRenderSurvey.add(() => {
// Open survey on a specific page (openOnQuestionValuesPage has priority over openOnPage)
Expand Down Expand Up @@ -315,11 +316,33 @@ export class FormBuilderService {
* @param temporaryFilesStorage Temporary files saved while executing the survey
* @param options Options regarding the upload
*/
private onUploadFiles(temporaryFilesStorage: any, options: any): void {
private onUploadFiles(
temporaryFilesStorage: TemporaryFilesStorage,
options: any
): void {
if (temporaryFilesStorage[options.name] !== undefined) {
temporaryFilesStorage[options.name].concat(options.files);
// Find if there are files for the same question
const cachedQuestion = temporaryFilesStorage[options.name].find(
(c) => c.question === options.question
);

// If there are, add the file to the existing array
if (cachedQuestion) {
cachedQuestion.files.concat(options.files);
} else {
// If not, create a new entry
temporaryFilesStorage[options.name].push({
files: options.files,
question: options.question,
});
}
} else {
temporaryFilesStorage[options.name] = options.files;
temporaryFilesStorage[options.name] = [
{
files: options.files,
question: options.question,
},
];
}
let content: any[] = [];
options.files.forEach((file: any) => {
Expand Down
86 changes: 52 additions & 34 deletions libs/shared/src/lib/services/form-helper/form-helper.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
import {
IPanel,
PageModel,
QuestionFileModel,
QuestionPanelDynamicModel,
SurveyModel,
} from 'survey-core';
Expand All @@ -22,6 +23,15 @@ import { WorkflowService } from '../workflow/workflow.service';
import { ApplicationService } from '../application/application.service';
import { DomService } from '../dom/dom.service';

/** Type definition for the temporary file storage object */
export type TemporaryFilesStorage = Record<
string,
{
question: QuestionFileModel;
files: File[];
}[]
>;

/**
* Applies custom logic to survey data values.
*
Expand Down Expand Up @@ -157,49 +167,59 @@ export class FormHelpersService {
*/
async uploadFiles(
survey: SurveyModel,
temporaryFilesStorage: any,
temporaryFilesStorage: TemporaryFilesStorage,
formId: string | undefined
): Promise<void> {
if (!formId) {
throw new Error('Form id is not defined');
}

const data = survey.data;
const questionsToUpload = Object.keys(temporaryFilesStorage);
for (const name of questionsToUpload) {
const files = temporaryFilesStorage[name];
for (const [index, file] of files.entries()) {
const path = await this.downloadService.uploadBlob(
file,
BlobType.RECORD_FILE,
formId
);
if (path) {
const fileContent = data[name][index].content;
data[name][index].content = path;

// Check if any other question is using the same file
survey.getAllQuestions().forEach((question) => {
const questionType = question.getType();
if (
questionType !== 'file' ||
// Only change files that are not in the temporary storage
// meaning their values came from the default values
!!temporaryFilesStorage[question.name]
)
return;

const files = data[question.name] ?? [];
files.forEach((file: any) => {
if (file && file.content === fileContent) {
file.content = path;
const cachedQuestions = temporaryFilesStorage[name];

if (!cachedQuestions) {
return;
}

for (const { files, question } of cachedQuestions) {
for (const [index, file] of files.entries()) {
const path = await this.downloadService.uploadBlob(
file,
BlobType.RECORD_FILE,
formId
);
if (path) {
const fileContent = question.value?.[index]?.content;
const value = cloneDeep(question.value);

if (question.value?.[index]?.content) {
value[index] = { ...value[index], content: path };
question.value = value;
}

// Check if any other question is using the same file
survey.getAllQuestions().forEach((question) => {
const questionType = question.getType();
if (
questionType !== 'file' ||
// Only change files that are not in the temporary storage
// meaning their values came from the default values
!!temporaryFilesStorage[question.name]
) {
return;
}

const files = survey.data[question.name] ?? [];
files.forEach((file: any) => {
if (file && file.content === fileContent) {
file.content = path;
}
});
});
});
}
}
}
}
survey.data = cloneDeep(data);
}

/**
Expand Down Expand Up @@ -496,9 +516,7 @@ export class FormHelpersService {
*
* @param storage Storage to clear
*/
public clearTemporaryFilesStorage(
storage: Record<string, Array<File>>
): void {
public clearTemporaryFilesStorage(storage: TemporaryFilesStorage): void {
Object.keys(storage).forEach((key) => {
delete storage[key];
});
Expand Down