Files
P42_UI/app/models/comms/templates/TemplatesModel.js
T
2025-08-27 07:03:09 +00:00

316 lines
11 KiB
JavaScript

class TemplatesModel extends EICModel {
current = null;
constructor(privileges) {
super('/templates', privileges)
this.ffs = new FakeFileSystem()
this.tokenCache = {}
}
getLatestStatus(templateInfo, status=null){
if(!templateInfo.statusHistory || (templateInfo.statusHistory.length<1)) return('')
return(
templateInfo.statusHistory.reduce((max, obj) =>
(obj.dateTime > max.dateTime) && ((!status) || (status==obj.value)) ? obj : max
)
)
}
getTokens(templateInfo){
if((!templateInfo) || (!templateInfo.id)) return
if(templateInfo.id in this.tokenCache) return(this.tokenCache[templateInfo.id])
const re = new RegExp(/\{\{([\w\-\.\^\#\/]+)\}\}/,'gm')
let txt = atob(templateInfo.html)
let allTokens = [...txt.matchAll(re)].map(item=>item[1])
if(templateInfo.meta.altText){
txt = atob(templateInfo.meta.altText)
for(let m of txt.matchAll(re)){
if(!allTokens.includes(m[1])) allTokens.push(m[1])
}
}
if(templateInfo.meta.subject){
txt = templateInfo.meta.subject
for(let m of txt.matchAll(re)){
if(!allTokens.includes(m[1])) allTokens.push(m[1])
}
}
this.tokenCache[templateInfo.id] = allTokens
return(allTokens)
}
countTokens(templateInfo){
return(this.getTokens(templateInfo).length)
}
async getTechDDTokens() {
this.tokenList = Promise.resolve([
{ name: 'personEmail' },
{ name: 'personEuLogin' },
{ name: 'personFirstName' },
{ name: 'personLastName' },
{ name: 'personFullName' },
{ name: 'organisationFullName' },
{ name: 'organisationShortName' },
{ name: 'organisationPIC' },
{ name: 'proposalId' },
{ name: 'proposalAcronym' },
{ name: 'proposalType' },
{ name: 'expertFirstName' },
{ name: 'expertLastName' },
{ name: 'expertFullName' },
{ name: 'FIOFirstName' },
{ name: 'FIOLastName' },
{ name: 'FIOFullName' },
{ name: 'POFirstName' },
{ name: 'POLastName' },
{ name: 'POFullName' },
{ name: 'TechDDFirstName' },
{ name: 'TechDDLastName' },
{ name: 'TechDDFullName' },
{ name: 'reportURL' },
{ name: 'unsubscribeURL' }
]);
return this.tokenList;
}
/************************/
/**
* Get a template by its ID.
* @param {string} tid - The ID of the templitor.
* @returns {Promise<any>}
*/
async get(tid) {
let endpoint = this.getApiEndpoint('read')
endpoint.uri = endpoint.uri.replace('{tid}', tid)
return (
this.request(endpoint.uri, endpoint.method)
.then( async serverData => serverData.payload)
)
}
/**
* List all templates.
* @returns {Promise<any[]>}
*/
async search(query, status=[]) {
if(!this.hasPrivilege('search')) return( new Promise((resolve, reject) => reject()))
let endpoint = this.getApiEndpoint('search')
let payload = {
query: query,
status: status,
}
return (
this.request(endpoint.uri, endpoint.method, payload)
.then( async serverData => serverData.payload)
.then( data => {
this.ffs.loadStructure(
data.ffs,
data.templates.map(item=>(
{
fullPath: (item.path+'/'+item.name).replace(/\/+/g, '/'),
object : item
}
))
)
return(data.templates)
})
)
}
async save(data) {
let endpoint = this.getApiEndpoint('save')
console.log("Saving template with data:", data);
return this.request(endpoint.uri, endpoint.method, data)
}
async delete(tid) {
if(!this.hasPrivilege('delete')) return( new Promise((reject) => reject('Insufficient privileges to perform delete templates')))
let endpoint = this.getApiEndpoint('delete')
endpoint.uri = endpoint.uri.replace('{tid}', tid)
return this.request(endpoint.uri, endpoint.method)
}
/*
* list of predefined images can be used in template
*/
async getImages() {
if(!this.hasPrivilege('read')) return( new Promise((reject) => reject('Insufficient privileges to perform get images'))) // if can read templates => can search list
let endpoint = this.getApiEndpoint('getImages');
return this.request(endpoint.uri, endpoint.method)
.then(serverData => serverData.payload)
.then(data => {
return data.map(item => ({
fullPath: (item.path + '/' + item.name).replace(/\/+/g, '/'),
object: item,
}));
});
}
/**
* Delete image
* @param {*} pid - picture id
* @param {*} deleteUrl - aws image url
* @returns {Promise<any[]>}
*/
async deleteImage(pid, deleteUrl) {
if (!this.hasPrivilege('delete')) {
return new Promise((reject) => reject('Insufficient privileges to perform delete images'));
}
let endpoint = this.getApiEndpoint('deleteImage');
endpoint.uri = endpoint.uri.replace('{pid}', pid);
const requestBody = { deleteUrl: deleteUrl };
return this.request(endpoint.uri, endpoint.method, requestBody)
.then(response => {
console.log('Image deleted successfully:', response);
return response;
})
.catch(error => {
console.error('Error deleting image:', error);
throw error;
});
}
getStatusLabel() {
return({
created : 'Created',
draft : 'Draft',
submitted : app.User.roles.includes('TEMPLATE_Reviewer') ? 'To review' : 'Being reviewed',
prod : 'Approved',
archived : 'Archived',
})
}
async readDir(path = '/', withFiles=true ){
if(!this.hasPrivilege('read')) return( new Promise((reject) => reject()))
let endpoint = this.getApiEndpoint('list', '/templitor/folders')
let uri = endpoint.uri
return (
this.request(uri, endpoint.method, { "path":path, withFiles: true })
.then( async serverData => {
if(!withFiles){
this.ffs.changeDir('/')
this.ffs.loadStructure(serverData.payload, this.ffs.getFiles())
} else {
const ffsData = serverData.payload.ffs || serverData.payload
this.ffs.loadStructure(ffsData, serverData.payload.files || [])
}
return(serverData.payload)
})
)
}
async getReadableFolders() {
try {
const endpoint = this.getApiEndpoint('list', '/templitor/folders')
const payload = { path: '/', withFiles: true }
const serverData = await this.request(endpoint.uri, endpoint.method, payload)
return serverData.payload || {}
} catch (err) {
console.error("Error in getReadableFolders", err)
return null
}
}
async makeDir(path=null, dirName){
let ffs = this.ffs //here not first param of method
if(path && (!ffs.pathExists(path))) return(Promise.resolve(null))
if(!path) path=ffs.currentPath
dirName = dirName.replace(/\//g,'').replace(/"/g,'').replace('\\','').replace(/\./g,'')
let endpoint = this.getApiEndpoint('add', '/templitor/folders');
let uri = endpoint.uri
return (
this.request(uri, endpoint.method, {
appId: 1,
path: path,
newFolder: dirName
})
.then( async serverData => {
return(serverData.payload)
})
)
}
async removeDir(appId, path = null) {
let ffs = this.ffs
if (!path) return Promise.resolve(null)
path = ffs.normalizePath(path)
let endpoint = this.getApiEndpoint('delete', '/templitor/folders')
let uri = endpoint.uri
return this.request(uri, endpoint.method, {
appId: appId,
path: path
}).then(async serverData => {
return serverData.payload
})
}
async testMail(templateId, recipientEmail) {
if(!this.hasPrivilege('edit')) return( new Promise((reject) => reject()))
let endpoint = this.getApiEndpoint('testTemplateMail')
endpoint.uri = endpoint.uri.replace('{tid}',templateId)
return (
this.request(endpoint.uri, endpoint.method, {
templateId: templateId,
recipientEmail: recipientEmail
})
.then( async serverData => serverData.payload)
)
}
async saveImage(data) {
let endpoint = this.getApiEndpoint('addImage');
return this.request(endpoint.uri, endpoint.method, data);
}
async requestPub(templateId, recipientEmail) {
if(!this.hasPrivilege('edit')) return( new Promise((reject) => reject()))
let endpoint = this.getApiEndpoint('requestPubTemplate')
return (
this.request(endpoint.uri, endpoint.method, {
templateId: templateId,
recipientEmail: recipientEmail
})
.then( async serverData => serverData.payload)
)
}
async approvePub(templateId, recipientEmail) {
if((!this.hasPrivilege('edit')) && (!this.hasPrivilege('approve')) && (!this.hasPrivilege('reject'))) return( new Promise((reject) => reject()))
let endpoint = this.getApiEndpoint('approvePub')
return (
this.request(endpoint.uri, endpoint.method, {
templateId: templateId,
recipientEmail: recipientEmail
})
.then( async serverData => serverData.payload)
)
}
async rejectPub(templateId, recipientEmail) {
if((!this.hasPrivilege('edit')) && (!this.hasPrivilege('approve')) && (!this.hasPrivilege('reject'))) return( new Promise((reject) => reject()))
let endpoint = this.getApiEndpoint('rejectPub')
return (
this.request(endpoint.uri, endpoint.method, {
templateId: templateId,
recipientEmail: recipientEmail
})
.then( async serverData => serverData.payload)
)
}
}
app.registerClass('TemplatesModel', TemplatesModel);