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
23 changes: 23 additions & 0 deletions src/api/form.template/form.template.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,28 @@ export class FormTemplateController {
}
};

export = async (request: express.Request, response: express.Response) => {
try {
var id: uuid = await this._validator.requestParamAsUUID(
request,
'id'
);
const exportData = await this._service.export(id);

const { filename, sourceFileLocation }
= await Helper.storeTemplateToFileLocally(exportData);

var mimeType = Helper.getMimeType(sourceFileLocation);
response.setHeader('Content-type', mimeType);
response.setHeader('Content-disposition', 'attachment; filename=' + filename);

var filestream = fs.createReadStream(sourceFileLocation);
filestream.pipe(response);
} catch (error) {
ResponseHandler.handleError(request, response, error);
}
};



//#region Private Helper Methods
Expand Down Expand Up @@ -378,6 +400,7 @@ export class FormTemplateController {
}
}


updateFavourite = async (request: express.Request, response: express.Response) => {
try {
const id = request.params.id;
Expand Down
1 change: 1 addition & 0 deletions src/api/form.template/form.template.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const register = (app: express.Application): void => {
router.get('/:id', context(`${contextBase}.GetById`), controller.getById);
router.delete('/:id', context(`${contextBase}.Delete`), controller.delete);
router.get('/:id/details', context(`${contextBase}.GetDetailsById`), controller.getDetailsById);
router.get('/:id/export', context(`${contextBase}.Export`), controller.export);
router.put('/:id/favourites', context(`${contextBase}.UpdateFavourite`), controller.updateFavourite);

app.use('/api/v1/form-templates', router);
Expand Down
90 changes: 90 additions & 0 deletions src/database/services/form.template.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,96 @@ export class FormTemplateService extends BaseService {
}
};

public export = async (id: uuid): Promise<ExportFormTemplateDto> => {
try {
const template = await this._formTemplateRepository.findOne({
where: {
id: id,
DeletedAt: IsNull(),
},
relations: {
FormSections: {
FormFields: {
SkipLogic: {
Rules: {
FallbackRule: true,
BaseFallbackRuleEntity: true,
},
},
CalculateLogic: {
Rules: {
FallbackRule: true,
},
},
ValidateLogic: {
Rules: {
FallbackRule: true,
},
},
},
},
},
order: {
FormSections: {
CreatedAt: "ASC",
FormFields: {
CreatedAt: "ASC",
},
},
},
});

if (!template) {
ErrorHandler.throwNotFoundError('Form template not found!');
}

// Filter out deleted sections and fields
if (template.FormSections) {
template.FormSections = template.FormSections.filter(
(section) => section.DeletedAt === null
);

template.FormSections.forEach((section) => {
if (section.FormFields) {
section.FormFields = section.FormFields.filter(
(field) => field.DeletedAt === null
);
}
});
}

// Map sections to hierarchical structure
const mappedSections = await this.mapSections(template.FormSections);

// Populate operations for all form fields
await this.populateFormFieldsOperations(mappedSections);

// Create export DTO
const exportDto: ExportFormTemplateDto = {
Template: {
id: template.id,
Title: template.Title,
Description: template.Description,
CurrentVersion: template.Version,
TenantCode: template.TenantId,
Type: template.Type as any,
DisplayCode: template.DisplayCode,
OwnerUserId: template.OwnerUserId,
RootSectionId: template.RootSectionId,
DefaultSectionNumbering: template.DefaultSectionNumbering,
CreatedAt: template.CreatedAt,
UpdatedAt: template.UpdatedAt,
Sections: mappedSections,
},
};

return exportDto;
} catch (error) {
logger.error(`Error exporting form template: ${error.message}`);
ErrorHandler.throwInternalServerError(error.message, error);
}
};



//#region Privates
Expand Down
1 change: 0 additions & 1 deletion src/domain.types/form.template.domain.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ export interface FormTemplateSearchResponseDto extends BaseSearchResults {
}

export interface ExportFormTemplateDto {
Sections: any;
Template: TemplateDto;
}

Expand Down