fix
This commit is contained in:
@@ -230,6 +230,7 @@ exports.createPDFFromDocTemplateName = (req, res) => {
|
|||||||
console.log('what', __dirname.replace('/controllers', ''));
|
console.log('what', __dirname.replace('/controllers', ''));
|
||||||
var inputData = JSON.parse(req.query.inputData);
|
var inputData = JSON.parse(req.query.inputData);
|
||||||
var docTemplateName = req.query.docTemplateName;
|
var docTemplateName = req.query.docTemplateName;
|
||||||
|
const site = splitSite.findSiteNumber(req);
|
||||||
const eventIds =inputData?.eventIds;
|
const eventIds =inputData?.eventIds;
|
||||||
Event.find({ '_id': { $in: eventIds } }).then((events) => {
|
Event.find({ '_id': { $in: eventIds } }).then((events) => {
|
||||||
const docData = {
|
const docData = {
|
||||||
@@ -263,10 +264,13 @@ exports.createPDFFromDocTemplateName = (req, res) => {
|
|||||||
});
|
});
|
||||||
// var transportationId = req.body.transportationId;d
|
// var transportationId = req.body.transportationId;d
|
||||||
// var transportationName = req.body.transportationName;
|
// var transportationName = req.body.transportationName;
|
||||||
DocTemplate.find({name: docTemplateName}).then((data) => {
|
DocTemplate.findOne({
|
||||||
|
name: docTemplateName,
|
||||||
|
site,
|
||||||
|
"file.0": { $exists: true }
|
||||||
|
}).sort({ edit_date: -1, updatedAt: -1, createdAt: -1 }).then((docTemplate) => {
|
||||||
try {
|
try {
|
||||||
if (data && data.length > 0) {
|
if (docTemplate) {
|
||||||
var docTemplate = data[0] || {};
|
|
||||||
var templateDoc = `${__dirname.replace('/controllers', '')}${docTemplate?.file[0]?.url}`;
|
var templateDoc = `${__dirname.replace('/controllers', '')}${docTemplate?.file[0]?.url}`;
|
||||||
var outputFileRandom = Math.ceil(Math.random() * 100000000);
|
var outputFileRandom = Math.ceil(Math.random() * 100000000);
|
||||||
var outputFile = `/tmp/${docTemplate.name}_${outputFileRandom}.docx`;
|
var outputFile = `/tmp/${docTemplate.name}_${outputFileRandom}.docx`;
|
||||||
@@ -329,6 +333,10 @@ exports.createPDFFromDocTemplateName = (req, res) => {
|
|||||||
libre.convert(infile, extend, undefined, (err, done) => {
|
libre.convert(infile, extend, undefined, (err, done) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('Error converting file:', err);
|
console.log('Error converting file:', err);
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error converting doc file to PDF"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// Here in done you have pdf file which you can save or transfer in another stream
|
// Here in done you have pdf file which you can save or transfer in another stream
|
||||||
fs.writeFileSync(outputPdfPath, done);
|
fs.writeFileSync(outputPdfPath, done);
|
||||||
@@ -336,21 +344,33 @@ exports.createPDFFromDocTemplateName = (req, res) => {
|
|||||||
res.download(outputPdfPath, function(error) {
|
res.download(outputPdfPath, function(error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.log('Error in sending download file ${outputPdfPath}');
|
console.log('Error in sending download file ${outputPdfPath}');
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error downloading generated PDF"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error generating PDF from doc template"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
res.status(404).send({
|
res.status(404).send({
|
||||||
success: false,
|
success: false,
|
||||||
message: "Docs Template doesn't exist"
|
message: "Docs Template doesn't exist for this site, or file not uploaded yet"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error processing doc template"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
res.status(500).send({
|
res.status(500).send({
|
||||||
@@ -366,6 +386,7 @@ exports.createDocFromDocTemplateName = (req, res) => {
|
|||||||
var inputData = JSON.parse(req.query.inputData);
|
var inputData = JSON.parse(req.query.inputData);
|
||||||
const eventIds = inputData?.eventIds;
|
const eventIds = inputData?.eventIds;
|
||||||
var docTemplateName = req.query.docTemplateName;
|
var docTemplateName = req.query.docTemplateName;
|
||||||
|
const site = splitSite.findSiteNumber(req);
|
||||||
Event.find({ '_id': { $in: eventIds } }).then((events) => {
|
Event.find({ '_id': { $in: eventIds } }).then((events) => {
|
||||||
const docData = {
|
const docData = {
|
||||||
events: []
|
events: []
|
||||||
@@ -397,10 +418,13 @@ exports.createDocFromDocTemplateName = (req, res) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
DocTemplate.find({name: docTemplateName}).then((data) => {
|
DocTemplate.findOne({
|
||||||
|
name: docTemplateName,
|
||||||
|
site,
|
||||||
|
"file.0": { $exists: true }
|
||||||
|
}).sort({ edit_date: -1, updatedAt: -1, createdAt: -1 }).then((docTemplate) => {
|
||||||
try {
|
try {
|
||||||
if (data && data.length > 0) {
|
if (docTemplate) {
|
||||||
var docTemplate = data[0] || {};
|
|
||||||
var templateDoc = `${__dirname.replace('/controllers', '')}${docTemplate?.file[0]?.url}`;
|
var templateDoc = `${__dirname.replace('/controllers', '')}${docTemplate?.file[0]?.url}`;
|
||||||
var outputFileRandom = Math.ceil(Math.random() * 100000000);
|
var outputFileRandom = Math.ceil(Math.random() * 100000000);
|
||||||
var outputFile = `/tmp/${docTemplate.name}_${outputFileRandom}.docx`;
|
var outputFile = `/tmp/${docTemplate.name}_${outputFileRandom}.docx`;
|
||||||
@@ -445,6 +469,10 @@ exports.createDocFromDocTemplateName = (req, res) => {
|
|||||||
res.download(outputFilename, (error) => {
|
res.download(outputFilename, (error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.log('Error in downloading excel')
|
console.log('Error in downloading excel')
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error downloading generated doc file"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -453,11 +481,15 @@ exports.createDocFromDocTemplateName = (req, res) => {
|
|||||||
} else {
|
} else {
|
||||||
res.status(404).send({
|
res.status(404).send({
|
||||||
success: false,
|
success: false,
|
||||||
message: "Docs Template doesn't exist"
|
message: "Docs Template doesn't exist for this site, or file not uploaded yet"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error processing doc template"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
res.status(500).send({
|
res.status(500).send({
|
||||||
|
|||||||
176
app/controllers/template-file.controller.js
Normal file
176
app/controllers/template-file.controller.js
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
const db = require("../models");
|
||||||
|
const { splitSite } = require("../middlewares");
|
||||||
|
|
||||||
|
const DocTemplate = db.doctemplate;
|
||||||
|
const ExcelTemplate = db.exceltemplate;
|
||||||
|
|
||||||
|
const TEMPLATE_DEFINITIONS = [
|
||||||
|
{
|
||||||
|
key: "medical_notifications_template",
|
||||||
|
label: "Medical Notifications Template",
|
||||||
|
type: "doc",
|
||||||
|
templateName: "med_notification",
|
||||||
|
modelPath: "doctemplate",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "visit_record_template",
|
||||||
|
label: "Visit Record Template",
|
||||||
|
type: "sheet",
|
||||||
|
templateName: "visit_record_sheet",
|
||||||
|
modelPath: "xlsxtemplate",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const getTemplateDefinition = (key) => TEMPLATE_DEFINITIONS.find((item) => item.key === key);
|
||||||
|
|
||||||
|
const getModelByDefinition = (definition) => (
|
||||||
|
definition.type === "doc" ? DocTemplate : ExcelTemplate
|
||||||
|
);
|
||||||
|
|
||||||
|
const findOrCreateTemplateDoc = async (definition, site, userName) => {
|
||||||
|
const model = getModelByDefinition(definition);
|
||||||
|
let templateDoc = await model.findOne({
|
||||||
|
name: definition.templateName,
|
||||||
|
site,
|
||||||
|
}).sort({ createdAt: -1 });
|
||||||
|
|
||||||
|
if (!templateDoc) {
|
||||||
|
templateDoc = await model.create({
|
||||||
|
name: definition.templateName,
|
||||||
|
status: "active",
|
||||||
|
site,
|
||||||
|
file: [],
|
||||||
|
create_by: userName,
|
||||||
|
create_date: new Date(),
|
||||||
|
edit_by: userName,
|
||||||
|
edit_date: new Date(),
|
||||||
|
edit_history: [{ employee: userName, date: new Date() }],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return templateDoc;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.listTemplates = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const site = splitSite.findSiteNumber(req);
|
||||||
|
const templateRows = [];
|
||||||
|
|
||||||
|
for (const definition of TEMPLATE_DEFINITIONS) {
|
||||||
|
const model = getModelByDefinition(definition);
|
||||||
|
const templateDoc = await model.findOne({
|
||||||
|
name: definition.templateName,
|
||||||
|
site,
|
||||||
|
}).sort({ createdAt: -1 });
|
||||||
|
const latestFile = templateDoc?.file?.[0] || null;
|
||||||
|
|
||||||
|
templateRows.push({
|
||||||
|
key: definition.key,
|
||||||
|
label: definition.label,
|
||||||
|
templateType: definition.type,
|
||||||
|
templateName: definition.templateName,
|
||||||
|
site,
|
||||||
|
templateId: templateDoc?.id || null,
|
||||||
|
file: latestFile
|
||||||
|
? {
|
||||||
|
name: latestFile.name || "",
|
||||||
|
originalName: latestFile.originalName || latestFile.name || "",
|
||||||
|
url: latestFile.url || "",
|
||||||
|
uploadedAt: latestFile.uploadedAt || templateDoc?.edit_date || templateDoc?.updatedAt || null,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
success: true,
|
||||||
|
data: templateRows,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.prepareUploadContext = async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const definition = getTemplateDefinition(req.params.key);
|
||||||
|
if (!definition) {
|
||||||
|
return res.status(404).send({
|
||||||
|
success: false,
|
||||||
|
message: "Template key is not supported.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const site = splitSite.findSiteNumber(req);
|
||||||
|
const userName = req.headers["x-user-name"] || "system";
|
||||||
|
const templateDoc = await findOrCreateTemplateDoc(definition, site, userName);
|
||||||
|
|
||||||
|
req.templateDefinition = definition;
|
||||||
|
req.templateDoc = templateDoc;
|
||||||
|
|
||||||
|
req.query.objectId = templateDoc.id;
|
||||||
|
req.query.name = definition.templateName;
|
||||||
|
req.query.fileType = "template";
|
||||||
|
req.query.model = definition.modelPath;
|
||||||
|
req.query.date = Date.now().toString();
|
||||||
|
|
||||||
|
return next();
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.uploadTemplate = async (req, res) => {
|
||||||
|
try {
|
||||||
|
const templateDoc = req.templateDoc;
|
||||||
|
const definition = req.templateDefinition;
|
||||||
|
if (!templateDoc || !definition || !req.file) {
|
||||||
|
return res.status(400).send({
|
||||||
|
success: false,
|
||||||
|
message: "Template upload request is invalid.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const userName = req.headers["x-user-name"] || "system";
|
||||||
|
const fileUrl = `/files/${definition.modelPath}/${templateDoc.id}/template/${req.file.filename}`;
|
||||||
|
const fileRecord = {
|
||||||
|
name: req.file.filename,
|
||||||
|
originalName: req.file.originalname,
|
||||||
|
url: fileUrl,
|
||||||
|
uploadedAt: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
templateDoc.file = [fileRecord];
|
||||||
|
templateDoc.status = "active";
|
||||||
|
templateDoc.edit_by = userName;
|
||||||
|
templateDoc.edit_date = new Date();
|
||||||
|
templateDoc.edit_history = [
|
||||||
|
...(templateDoc.edit_history || []),
|
||||||
|
{ employee: userName, date: new Date() },
|
||||||
|
];
|
||||||
|
await templateDoc.save();
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
key: definition.key,
|
||||||
|
templateName: definition.templateName,
|
||||||
|
templateType: definition.type,
|
||||||
|
templateId: templateDoc.id,
|
||||||
|
site: templateDoc.site,
|
||||||
|
file: fileRecord,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -171,6 +171,7 @@ exports.createPDFFromSheetTemplateName = (req, res) => {
|
|||||||
const eventIds = inputData?.eventIds;
|
const eventIds = inputData?.eventIds;
|
||||||
console.log('eventIds',eventIds);
|
console.log('eventIds',eventIds);
|
||||||
var excelTemplateName = req.query.excelTemplateName;
|
var excelTemplateName = req.query.excelTemplateName;
|
||||||
|
const site = splitSite.findSiteNumber(req);
|
||||||
console.log('template', excelTemplateName);
|
console.log('template', excelTemplateName);
|
||||||
|
|
||||||
Event.find({ '_id': { $in: eventIds } }).then((events) => {
|
Event.find({ '_id': { $in: eventIds } }).then((events) => {
|
||||||
@@ -233,10 +234,13 @@ exports.createPDFFromSheetTemplateName = (req, res) => {
|
|||||||
|
|
||||||
// var transportationId = req.body.transportationId;d
|
// var transportationId = req.body.transportationId;d
|
||||||
// var transportationName = req.body.transportationName;
|
// var transportationName = req.body.transportationName;
|
||||||
ExcelTemplate.find({name: excelTemplateName}).then((data) => {
|
ExcelTemplate.findOne({
|
||||||
|
name: excelTemplateName,
|
||||||
|
site,
|
||||||
|
"file.0": { $exists: true }
|
||||||
|
}).sort({ edit_date: -1, updatedAt: -1, createdAt: -1 }).then((excelTemplate) => {
|
||||||
try {
|
try {
|
||||||
if (data && data.length > 0) {
|
if (excelTemplate) {
|
||||||
var excelTemplate = data[0] || {};
|
|
||||||
var templateExcel = `${__dirname.replace('/controllers', '')}${excelTemplate?.file[0]?.url}`;
|
var templateExcel = `${__dirname.replace('/controllers', '')}${excelTemplate?.file[0]?.url}`;
|
||||||
var outputFileRandom = Math.ceil(Math.random() * 100000000);
|
var outputFileRandom = Math.ceil(Math.random() * 100000000);
|
||||||
var outputFile = `/tmp/${excelTemplate.name}_${outputFileRandom}.xlsx`;
|
var outputFile = `/tmp/${excelTemplate.name}_${outputFileRandom}.xlsx`;
|
||||||
@@ -265,6 +269,10 @@ exports.createPDFFromSheetTemplateName = (req, res) => {
|
|||||||
libre.convert(infile, extend, undefined, (err, done) => {
|
libre.convert(infile, extend, undefined, (err, done) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('Error converting file:', err);
|
console.log('Error converting file:', err);
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error converting sheet file to PDF"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// Here in done you have pdf file which you can save or transfer in another stream
|
// Here in done you have pdf file which you can save or transfer in another stream
|
||||||
fs.writeFileSync(outputPdfPath, done);
|
fs.writeFileSync(outputPdfPath, done);
|
||||||
@@ -272,21 +280,33 @@ exports.createPDFFromSheetTemplateName = (req, res) => {
|
|||||||
res.download(outputPdfPath, function(error) {
|
res.download(outputPdfPath, function(error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.log('Error in sending download file ${outputPdfPath}');
|
console.log('Error in sending download file ${outputPdfPath}');
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error downloading generated PDF"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error generating PDF from sheet template"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
res.status(404).send({
|
res.status(404).send({
|
||||||
success: false,
|
success: false,
|
||||||
message: "Sheet Template doesn't exist"
|
message: "Sheet Template doesn't exist for this site, or file not uploaded yet"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error processing sheet template"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
res.status(500).send({
|
res.status(500).send({
|
||||||
@@ -306,6 +326,7 @@ exports.createSheetFromTemplateName = (req, res) => {
|
|||||||
var inputData = JSON.parse(req.query.inputData);
|
var inputData = JSON.parse(req.query.inputData);
|
||||||
const eventIds = inputData?.eventIds;
|
const eventIds = inputData?.eventIds;
|
||||||
var excelTemplateName = req.query.excelTemplateName;
|
var excelTemplateName = req.query.excelTemplateName;
|
||||||
|
const site = splitSite.findSiteNumber(req);
|
||||||
|
|
||||||
Event.find({ '_id': { $in: eventIds } }).then((events) => {
|
Event.find({ '_id': { $in: eventIds } }).then((events) => {
|
||||||
Resource.find({}).then((resources) => {
|
Resource.find({}).then((resources) => {
|
||||||
@@ -362,10 +383,13 @@ exports.createSheetFromTemplateName = (req, res) => {
|
|||||||
}
|
}
|
||||||
// var transportationId = req.body.transportationId;d
|
// var transportationId = req.body.transportationId;d
|
||||||
// var transportationName = req.body.transportationName;
|
// var transportationName = req.body.transportationName;
|
||||||
ExcelTemplate.find({name: excelTemplateName}).then((data) => {
|
ExcelTemplate.findOne({
|
||||||
|
name: excelTemplateName,
|
||||||
|
site,
|
||||||
|
"file.0": { $exists: true }
|
||||||
|
}).sort({ edit_date: -1, updatedAt: -1, createdAt: -1 }).then((excelTemplate) => {
|
||||||
try {
|
try {
|
||||||
if (data && data.length > 0) {
|
if (excelTemplate) {
|
||||||
var excelTemplate = data[0] || {};
|
|
||||||
var templateExcel = `${__dirname.replace('/controllers', '')}${excelTemplate?.file[0]?.url}`;
|
var templateExcel = `${__dirname.replace('/controllers', '')}${excelTemplate?.file[0]?.url}`;
|
||||||
var outputFileRandom = Math.ceil(Math.random() * 100000000);
|
var outputFileRandom = Math.ceil(Math.random() * 100000000);
|
||||||
var outputFile = `/tmp/${excelTemplate.name}_${outputFileRandom}.xlsx`;
|
var outputFile = `/tmp/${excelTemplate.name}_${outputFileRandom}.xlsx`;
|
||||||
@@ -387,17 +411,25 @@ exports.createSheetFromTemplateName = (req, res) => {
|
|||||||
res.download(outputFile, (error) => {
|
res.download(outputFile, (error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.log('Error in downloading excel')
|
console.log('Error in downloading excel')
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error downloading generated sheet file"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
console.log('Download finish');
|
console.log('Download finish');
|
||||||
} else {
|
} else {
|
||||||
res.status(404).send({
|
res.status(404).send({
|
||||||
success: false,
|
success: false,
|
||||||
message: "Sheet Template doesn't exist"
|
message: "Sheet Template doesn't exist for this site, or file not uploaded yet"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
|
return res.status(500).send({
|
||||||
|
success: false,
|
||||||
|
message: "Error processing sheet template"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
res.status(500).send({
|
res.status(500).send({
|
||||||
|
|||||||
29
app/routes/template-file.route.js
Normal file
29
app/routes/template-file.route.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
const { authJwt } = require("../middlewares");
|
||||||
|
const uploadPhysicalFile = require("../middlewares/upload_physical");
|
||||||
|
|
||||||
|
module.exports = (app) => {
|
||||||
|
const templates = require("../controllers/template-file.controller.js");
|
||||||
|
const router = require("express").Router();
|
||||||
|
|
||||||
|
const handleUploadMiddleware = (req, res, next) => {
|
||||||
|
uploadPhysicalFile(req, res, (err) => {
|
||||||
|
if (err) {
|
||||||
|
return res.status(500).send({
|
||||||
|
message: `Upload Error: ${err.message || err}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return next();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
router.get("/", [authJwt.verifyToken], templates.listTemplates);
|
||||||
|
router.post(
|
||||||
|
"/:key/upload",
|
||||||
|
[authJwt.verifyToken],
|
||||||
|
templates.prepareUploadContext,
|
||||||
|
handleUploadMiddleware,
|
||||||
|
templates.uploadTemplate
|
||||||
|
);
|
||||||
|
|
||||||
|
app.use("/api/template-files", router);
|
||||||
|
};
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"files": {
|
"files": {
|
||||||
"main.css": "/static/css/main.46cc12be.css",
|
"main.css": "/static/css/main.46cc12be.css",
|
||||||
"main.js": "/static/js/main.3ecb6fce.js",
|
"main.js": "/static/js/main.1eb25967.js",
|
||||||
"static/js/787.c4e7f8f9.chunk.js": "/static/js/787.c4e7f8f9.chunk.js",
|
"static/js/787.c4e7f8f9.chunk.js": "/static/js/787.c4e7f8f9.chunk.js",
|
||||||
"static/media/landing.png": "/static/media/landing.d4c6072db7a67dff6a78.png",
|
"static/media/landing.png": "/static/media/landing.d4c6072db7a67dff6a78.png",
|
||||||
"index.html": "/index.html",
|
"index.html": "/index.html",
|
||||||
"main.46cc12be.css.map": "/static/css/main.46cc12be.css.map",
|
"main.46cc12be.css.map": "/static/css/main.46cc12be.css.map",
|
||||||
"main.3ecb6fce.js.map": "/static/js/main.3ecb6fce.js.map",
|
"main.1eb25967.js.map": "/static/js/main.1eb25967.js.map",
|
||||||
"787.c4e7f8f9.chunk.js.map": "/static/js/787.c4e7f8f9.chunk.js.map"
|
"787.c4e7f8f9.chunk.js.map": "/static/js/787.c4e7f8f9.chunk.js.map"
|
||||||
},
|
},
|
||||||
"entrypoints": [
|
"entrypoints": [
|
||||||
"static/css/main.46cc12be.css",
|
"static/css/main.46cc12be.css",
|
||||||
"static/js/main.3ecb6fce.js"
|
"static/js/main.1eb25967.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.3ecb6fce.js"></script><link href="/static/css/main.46cc12be.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"><link rel="manifest" href="/manifest.json"/><title>Worldshine Transportation</title><script defer="defer" src="/static/js/main.1eb25967.js"></script><link href="/static/css/main.46cc12be.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -67,6 +67,7 @@ import EventsCalendar from "./components/events/EventsCalendar";
|
|||||||
|
|
||||||
import Medical from "./components/medical/Medical";
|
import Medical from "./components/medical/Medical";
|
||||||
import MedicalIndex from './components/medical/MedicalIndex';
|
import MedicalIndex from './components/medical/MedicalIndex';
|
||||||
|
import TemplateManager from "./components/medical/TemplateManager";
|
||||||
import CreateEventRequest from "./components/event-request/CreateEventRequest";
|
import CreateEventRequest from "./components/event-request/CreateEventRequest";
|
||||||
import EventRequestList from "./components/event-request/EventRequestList";
|
import EventRequestList from "./components/event-request/EventRequestList";
|
||||||
|
|
||||||
@@ -196,6 +197,7 @@ function App() {
|
|||||||
<Route path="events/create-from-request" element={<UpdateEvent /> } />
|
<Route path="events/create-from-request" element={<UpdateEvent /> } />
|
||||||
<Route path="event-request" element={<CreateEventRequest />} />
|
<Route path="event-request" element={<CreateEventRequest />} />
|
||||||
<Route path="event-request/list" element={<EventRequestList />} />
|
<Route path="event-request/list" element={<EventRequestList />} />
|
||||||
|
<Route path="template" element={<TemplateManager />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path="/info-screen" element={<InfoScreen />} />
|
<Route path="/info-screen" element={<InfoScreen />} />
|
||||||
|
|||||||
@@ -96,19 +96,12 @@ const EventsCalendar = () => {
|
|||||||
setToDate(new Date(endDate.getFullYear(), endDate.getMonth() + 1, 0));
|
setToDate(new Date(endDate.getFullYear(), endDate.getMonth() + 1, 0));
|
||||||
},
|
},
|
||||||
onClickDate(date) {
|
onClickDate(date) {
|
||||||
// Parse as local date to avoid UTC timezone offset shifting the day
|
// Disabled: prevent creating new event by tapping calendar date
|
||||||
const [y, m, d] = date.split('-').map(Number);
|
return;
|
||||||
const localDate = new Date(y, m - 1, d);
|
|
||||||
// Default to 10:00 AM
|
|
||||||
localDate.setHours(10, 0, 0, 0);
|
|
||||||
setNewEventStartDateTime(localDate);
|
|
||||||
setNewEventEndDateTime(localDate);
|
|
||||||
setShowCreationModal(true);
|
|
||||||
},
|
},
|
||||||
onClickDateTime(dateTime) {
|
onClickDateTime(dateTime) {
|
||||||
setNewEventStartDateTime(new Date(dateTime.replace(' ', 'T')));
|
// Disabled: prevent creating new event by tapping calendar time slot
|
||||||
setNewEventEndDateTime(new Date(dateTime.replace(' ', 'T')));
|
return;
|
||||||
setShowCreationModal(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -189,6 +189,12 @@ const SideMenu = () => {
|
|||||||
link: '/medical/events/multiple-list',
|
link: '/medical/events/multiple-list',
|
||||||
category: '/events/multiple-list',
|
category: '/events/multiple-list',
|
||||||
roleFunc: AuthService.canAccessLegacySystem
|
roleFunc: AuthService.canAccessLegacySystem
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Template',
|
||||||
|
link: '/medical/template',
|
||||||
|
category: '/medical/template',
|
||||||
|
roleFunc: AuthService.canAccessLegacySystem
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
147
client/src/components/medical/TemplateManager.js
Normal file
147
client/src/components/medical/TemplateManager.js
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Breadcrumb, Spinner, Tab, Tabs } from "react-bootstrap";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { AuthService, TemplateFileService } from "../../services";
|
||||||
|
|
||||||
|
const TemplateManager = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [templates, setTemplates] = useState([]);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [uploadingKey, setUploadingKey] = useState("");
|
||||||
|
|
||||||
|
const loadTemplates = () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
TemplateFileService.listTemplates()
|
||||||
|
.then((data) => {
|
||||||
|
setTemplates(data?.data?.data || []);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
window.alert("Failed to load templates.");
|
||||||
|
})
|
||||||
|
.finally(() => setIsLoading(false));
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!AuthService.canAccessLegacySystem()) {
|
||||||
|
window.alert("You haven't login yet OR this user does not have access to this page. Please change an admin account to login.");
|
||||||
|
AuthService.logout();
|
||||||
|
navigate("/login");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loadTemplates();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleView = (row) => {
|
||||||
|
if (!row?.file?.url) return;
|
||||||
|
window.open(TemplateFileService.getTemplateFileUrl(row.file.url), "_blank");
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDownload = (row) => {
|
||||||
|
if (!row?.file?.url) return;
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = TemplateFileService.getTemplateFileUrl(row.file.url);
|
||||||
|
link.download = row?.file?.originalName || row?.file?.name || `${row.label}.template`;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onUploadFile = (row, event) => {
|
||||||
|
const file = event?.target?.files?.[0];
|
||||||
|
event.target.value = "";
|
||||||
|
if (!file || !row?.key) return;
|
||||||
|
|
||||||
|
setUploadingKey(row.key);
|
||||||
|
TemplateFileService.uploadTemplate(row.key, file)
|
||||||
|
.then(() => {
|
||||||
|
window.alert("Template uploaded successfully.");
|
||||||
|
loadTemplates();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
window.alert("Template upload failed.");
|
||||||
|
})
|
||||||
|
.finally(() => setUploadingKey(""));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{isLoading && (
|
||||||
|
<div className="spinner-overlay">
|
||||||
|
<Spinner animation="border" role="status">
|
||||||
|
<span className="visually-hidden">Loading...</span>
|
||||||
|
</Spinner>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="list row mb-4">
|
||||||
|
<Breadcrumb>
|
||||||
|
<Breadcrumb.Item href="/medical/index">Medical</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item active>Template</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
|
<div className="col-md-12 text-primary">
|
||||||
|
<h4>Template</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="app-main-content-list-container form-page">
|
||||||
|
<div className="app-main-content-list-func-container">
|
||||||
|
<Tabs defaultActiveKey="template" id="medical-template-tab">
|
||||||
|
<Tab eventKey="template" title="Template">
|
||||||
|
<div className="list row mb-4 mt-3">
|
||||||
|
<div className="col-md-12" style={{ overflow: "auto" }}>
|
||||||
|
<table className="personnel-info-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="th-index">No.</th>
|
||||||
|
<th>Template</th>
|
||||||
|
<th>Current File</th>
|
||||||
|
<th>Site</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{templates.map((row, index) => (
|
||||||
|
<tr key={row.key}>
|
||||||
|
<td className="td-index">{index + 1}</td>
|
||||||
|
<td>{row.label}</td>
|
||||||
|
<td>{row?.file?.originalName || row?.file?.name || "No file uploaded"}</td>
|
||||||
|
<td>{row.site || "-"}</td>
|
||||||
|
<td>
|
||||||
|
<button className="btn btn-sm btn-outline-primary me-2" onClick={() => handleView(row)} disabled={!row?.file?.url}>
|
||||||
|
View
|
||||||
|
</button>
|
||||||
|
<button className="btn btn-sm btn-outline-secondary me-2" onClick={() => handleDownload(row)} disabled={!row?.file?.url}>
|
||||||
|
Download
|
||||||
|
</button>
|
||||||
|
<label className="btn btn-sm btn-primary mb-0">
|
||||||
|
{uploadingKey === row.key ? "Uploading..." : "Re-upload"}
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
style={{ display: "none" }}
|
||||||
|
onChange={(event) => onUploadFile(row, event)}
|
||||||
|
disabled={uploadingKey === row.key}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
{templates.length === 0 && (
|
||||||
|
<tr>
|
||||||
|
<td colSpan="5" style={{ textAlign: "center", color: "#999", padding: "20px" }}>
|
||||||
|
No templates found for this site.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TemplateManager;
|
||||||
@@ -2,7 +2,7 @@ import axios from "axios";
|
|||||||
export default axios.create({
|
export default axios.create({
|
||||||
// baseURL: (window.location.hostname.includes('worldshine.mayo.llc') || window.location.hostname.includes('site')) ? "https://worldshine.mayo.llc/api" : ((window.location.hostname.includes('worldshine3.mayo.llc') || window.location.hostname.includes('site3')) ? "https://worldshine3.mayo.llc/api" : "https://worldshine3.mayo.llc/api"),
|
// baseURL: (window.location.hostname.includes('worldshine.mayo.llc') || window.location.hostname.includes('site')) ? "https://worldshine.mayo.llc/api" : ((window.location.hostname.includes('worldshine3.mayo.llc') || window.location.hostname.includes('site3')) ? "https://worldshine3.mayo.llc/api" : "https://worldshine3.mayo.llc/api"),
|
||||||
// for Test site only:
|
// for Test site only:
|
||||||
baseURL: (window.location.hostname.includes('ws1') ||window.location.hostname.includes('localhost') || window.location.hostname.includes('site1')) ? "https://ws1-tspt.mayosolution.com/api" : ((window.location.hostname.includes('ws3') || window.location.hostname.includes('site3')) ? "https://ws3.mayosolution.com/api" : "https://ws2.mayosolution.com/api"),
|
baseURL: (window.location.hostname.includes('ws1') ||window.location.hostname.includes('localhost') || window.location.hostname.includes('site1')) ? "https://ws1-tspt.mayosolution.com/api" : ((window.location.hostname.includes('ws3') || window.location.hostname.includes('site3')) ? "https://ws3-tspt.mayosolution.com/api" : "https://ws2-tspt.mayosolution.com/api"),
|
||||||
// baseURL: "http://localhost:8080/api",
|
// baseURL: "http://localhost:8080/api",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-type": "application/json"
|
"Content-type": "application/json"
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ const transportationTypeOptions = [
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const baseUrl = (window.location.hostname.includes('ws1') ||window.location.hostname.includes('localhost') || window.location.hostname.includes('site1')) ? "https://ws1-tspt.mayosolution.com/api" : ((window.location.hostname.includes('ws3') || window.location.hostname.includes('site3')) ? "https://ws3.mayosolution.com/api" : "https://ws2.mayosolution.com/api")
|
const baseUrl = (window.location.hostname.includes('ws1') ||window.location.hostname.includes('localhost') || window.location.hostname.includes('site1')) ? "https://ws1-tspt.mayosolution.com/api" : ((window.location.hostname.includes('ws3') || window.location.hostname.includes('site3')) ? "https://ws3-tspt.mayosolution.com/api" : "https://ws2-tspt.mayosolution.com/api")
|
||||||
// const baseUrl = (window.location.hostname.includes('worldshine.mayo.llc') ||window.location.hostname.includes('worldshine1') || window.location.hostname.includes('site1')) ? "https://worldshine.mayo.llc/api" : ((window.location.hostname.includes('worldshine3') || window.location.hostname.includes('site3')) ? "https://worldshine3.mayo.llc/api" : "https://worldshine2.mayo.llc/api")
|
// const baseUrl = (window.location.hostname.includes('worldshine.mayo.llc') ||window.location.hostname.includes('worldshine1') || window.location.hostname.includes('site1')) ? "https://worldshine.mayo.llc/api" : ((window.location.hostname.includes('worldshine3') || window.location.hostname.includes('site3')) ? "https://worldshine3.mayo.llc/api" : "https://worldshine2.mayo.llc/api")
|
||||||
|
|
||||||
const site = (window.location.hostname.includes('ws1') ||window.location.hostname.includes('localhost') || window.location.hostname.includes('site1')) ? 1 : ((window.location.hostname.includes('ws3') || window.location.hostname.includes('site3')) ? 3 : 2)
|
const site = (window.location.hostname.includes('ws1') ||window.location.hostname.includes('localhost') || window.location.hostname.includes('site1')) ? 1 : ((window.location.hostname.includes('ws3') || window.location.hostname.includes('site3')) ? 3 : 2)
|
||||||
|
|||||||
30
client/src/services/TemplateFileService.js
Normal file
30
client/src/services/TemplateFileService.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import http from "../http-common";
|
||||||
|
|
||||||
|
const listTemplates = () => {
|
||||||
|
return http.get("/template-files");
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadTemplate = (key, file) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", file);
|
||||||
|
const currentUser = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null;
|
||||||
|
const userName = currentUser?.name || "system";
|
||||||
|
|
||||||
|
return http.post(`/template-files/${key}/upload`, formData, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "multipart/form-data",
|
||||||
|
"x-user-name": userName,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTemplateFileUrl = (fileUrl) => {
|
||||||
|
const baseUrl = http.defaults.baseURL || "";
|
||||||
|
return `${baseUrl.replace("/api", "")}${fileUrl}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TemplateFileService = {
|
||||||
|
listTemplates,
|
||||||
|
uploadTemplate,
|
||||||
|
getTemplateFileUrl,
|
||||||
|
};
|
||||||
@@ -20,6 +20,7 @@ export * from './SeatingService';
|
|||||||
export * from './AttendanceNoteService';
|
export * from './AttendanceNoteService';
|
||||||
export * from './CarouselService';
|
export * from './CarouselService';
|
||||||
export * from './DailyRoutesTemplateService';
|
export * from './DailyRoutesTemplateService';
|
||||||
|
export * from './TemplateFileService';
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
export const parseDateFromBackend = (dateString) => {
|
export const parseDateFromBackend = (dateString) => {
|
||||||
|
|||||||
@@ -195,6 +195,9 @@ app.get('/medical/resources/list', function (req,res) {
|
|||||||
app.get('/medical/events/calendar', function (req,res) {
|
app.get('/medical/events/calendar', function (req,res) {
|
||||||
res.sendFile(path + "index.html");
|
res.sendFile(path + "index.html");
|
||||||
});
|
});
|
||||||
|
app.get('/medical/template', function (req,res) {
|
||||||
|
res.sendFile(path + "index.html");
|
||||||
|
});
|
||||||
app.get('/medical/resources', function (req,res) {
|
app.get('/medical/resources', function (req,res) {
|
||||||
res.sendFile(path + "index.html");
|
res.sendFile(path + "index.html");
|
||||||
});
|
});
|
||||||
@@ -252,6 +255,7 @@ require("./app/routes/carousel.routes")(app);
|
|||||||
require("./app/routes/fingerprint-attendance.routes")(app);
|
require("./app/routes/fingerprint-attendance.routes")(app);
|
||||||
require("./app/routes/daily-routes-template.routes")(app);
|
require("./app/routes/daily-routes-template.routes")(app);
|
||||||
require("./app/routes/msg-custom-template.routes")(app);
|
require("./app/routes/msg-custom-template.routes")(app);
|
||||||
|
require("./app/routes/template-file.route")(app);
|
||||||
|
|
||||||
require("./app/scheduler/reminderScheduler");
|
require("./app/scheduler/reminderScheduler");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user