diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 06531c46ba7..59a0c3ef0cc 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -8,6 +8,7 @@ > Users must be able to say: “Nice enhancement, I'm eager to test it” - [VM] Disks whose name contains the tag `[NOSNAP]` will be ignored when doing a manual snapshot similarly to disks ignored during backups with `[NOBAK]` (possibility to use both tags on the same disk) [Forum#79179](https://xcp-ng.org/forum/post/79179) +- [Plugin/backup-reports] Backup reports sent by email have a new, less rudimentary look (PR [#7747](https://github.com/vatesfr/xen-orchestra/pull/7747)) ### Bug fixes @@ -33,6 +34,7 @@ - @xen-orchestra/xapi major - xo-server minor +- xo-server-backup-reports minor - xo-server-sdn-controller patch diff --git a/packages/xo-server-backup-reports/package.json b/packages/xo-server-backup-reports/package.json index cffa104130b..f4766dd1123 100644 --- a/packages/xo-server-backup-reports/package.json +++ b/packages/xo-server-backup-reports/package.json @@ -37,6 +37,7 @@ "handlebars": "^4.7.8", "human-format": "^1.0.0", "lodash": "^4.13.1", + "mjml": "^4.15.3", "moment-timezone": "^0.5.13" }, "devDependencies": { diff --git a/packages/xo-server-backup-reports/src/helpers.js b/packages/xo-server-backup-reports/src/helpers.js index d91d2b512a2..95e9420be5f 100644 --- a/packages/xo-server-backup-reports/src/helpers.js +++ b/packages/xo-server-backup-reports/src/helpers.js @@ -1,4 +1,3 @@ -import Handlebars from 'handlebars' import humanFormat from 'human-format' import moment from 'moment-timezone' @@ -15,15 +14,15 @@ const STATUS_ICON = { } const TITLE_BY_STATUS = { - failure: n => `## ${n} Failure${n === 1 ? '' : 's'}`, - interrupted: n => `## ${n} Interrupted`, - skipped: n => `## ${n} Skipped`, - success: n => `## ${n} Success${n === 1 ? '' : 'es'}`, + failure: n => `${n} Failure${n === 1 ? '' : 's'}`, + interrupted: n => `${n} Interrupted`, + skipped: n => `${n} Skipped`, + success: n => `${n} Success${n === 1 ? '' : 'es'}`, } // =================================================================== -Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) { +export function ifCond(v1, operator, v2, options) { switch (operator) { case '===': return v1 === v2 ? options.fn(this) : options.inverse(this) @@ -44,36 +43,34 @@ Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) { default: return options.inverse(this) } -}) +} -Handlebars.registerHelper('formatDuration', milliseconds => moment.duration(milliseconds).humanize()) +export const formatDuration = milliseconds => moment.duration(milliseconds).humanize() -const formatSize = bytes => +export const formatSize = bytes => humanFormat(bytes, { scale: 'binary', unit: 'B', }) -Handlebars.registerHelper('formatSize', formatSize) -const formatSpeed = (bytes, milliseconds) => - milliseconds > 0 - ? humanFormat((bytes * 1e3) / milliseconds, { +export const formatSpeed = (bytes, start, end) => + end - start > 0 + ? humanFormat((bytes * 1e3) / (end - start), { scale: 'binary', unit: 'B/s', }) : 'N/A' -Handlebars.registerHelper('formatSpeed', (bytes, start, end) => formatSpeed(bytes, end - start)) -Handlebars.registerHelper('subtract', (a, b) => a - b) +export const subtract = (a, b) => a - b -Handlebars.registerHelper('executeFunction', (fct, arg) => fct(arg)) +export const executeFunction = (fct, arg) => fct(arg) // this could be a partial but it would be less clear -Handlebars.registerHelper('getIcon', status => STATUS_ICON[status]) +export const getIcon = status => STATUS_ICON[status] // this could be a partial but it would be less clear -Handlebars.registerHelper('titleByStatus', function (status) { - if (this && status in TITLE_BY_STATUS) { - return TITLE_BY_STATUS[status](this.length) +export function titleByStatus(status, tasks) { + if (tasks && status in TITLE_BY_STATUS) { + return TITLE_BY_STATUS[status](tasks.length) } -}) +} diff --git a/packages/xo-server-backup-reports/src/index.js b/packages/xo-server-backup-reports/src/index.js index 5ce859be6ec..f762a3f69f8 100644 --- a/packages/xo-server-backup-reports/src/index.js +++ b/packages/xo-server-backup-reports/src/index.js @@ -1,12 +1,14 @@ import Handlebars from 'handlebars' import moment from 'moment-timezone' import { createLogger } from '@xen-orchestra/log' -import { forEach, groupBy } from 'lodash' -import { get } from '@xen-orchestra/defined' import { extname, join, parse } from 'node:path' +import { get } from '@xen-orchestra/defined' +import { forEach, groupBy } from 'lodash' import { readdirSync, readFileSync } from 'node:fs' + import pkg from '../package' -import './helpers' + +import * as helpers from './helpers' const logger = createLogger('xo:xo-server-backup-reports') @@ -53,26 +55,49 @@ export const testSchema = { // =================================================================== -const handlebarsPartialFiles = readdirSync(join(__dirname, '../templates/partials/')).filter( - filename => extname(filename) === '.hbs' -) -for (const fileName of handlebarsPartialFiles) { - const partial = readFileSync(join(__dirname, `../templates/partials/${fileName}`)).toString() - Handlebars.registerPartial(parse(fileName).name, partial) +// Handlebars environments +const markdownHandlebars = Handlebars.create() +const mjmlHandlebars = Handlebars.create() + +// Handlebars common helpers +for (const [helperName, helper] of Object.entries(helpers)) { + markdownHandlebars.registerHelper(helperName, helper) + mjmlHandlebars.registerHelper(helperName, helper) +} + +// Handlebars partials +const registerPartials = (path, handlebarsEnvironment) => { + const handlebarsPartialFiles = readdirSync(join(__dirname, path)).filter(filename => extname(filename) === '.hbs') + for (const fileName of handlebarsPartialFiles) { + const partial = readFileSync(join(__dirname, `${path}${fileName}`)).toString() + handlebarsEnvironment.registerPartial(parse(fileName).name, partial) + } +} +registerPartials('../templates/markdown/partials/', markdownHandlebars) +registerPartials('../templates/mjml/partials/', mjmlHandlebars) + +// Handlebars templates +const readCompileHbs = (path, handlebarsEnvironment) => + handlebarsEnvironment.compile(readFileSync(join(__dirname, path)).toString().replace(/\n$/, '')) +const importTemplateFolder = (folder, handlebarsEnvironment) => ({ + metadata: readCompileHbs(`${folder}/metadata.hbs`, handlebarsEnvironment), + metadataSubject: readCompileHbs(`${folder}/metadataSubject.hbs`, handlebarsEnvironment), + vm: readCompileHbs(`${folder}/vm.hbs`, handlebarsEnvironment), + vmSubject: readCompileHbs(`${folder}/vmSubject.hbs`, handlebarsEnvironment), +}) + +const templates = { + markdown: importTemplateFolder('../templates/markdown', markdownHandlebars), + mjml: importTemplateFolder('../templates/mjml', mjmlHandlebars), } -const compiledMetadataSubject = Handlebars.compile( - readFileSync(join(__dirname, '../templates/metadataSubject.hbs')).toString().replace(/\n$/, '') -) -const compiledMetadataTemplate = Handlebars.compile( - readFileSync(join(__dirname, '../templates/metadata.hbs')).toString().replace(/\n$/, '') -) -const compiledVmSubject = Handlebars.compile( - readFileSync(join(__dirname, '../templates/vmSubject.hbs')).toString().replace(/\n$/, '') -) -const compiledVmTemplate = Handlebars.compile( - readFileSync(join(__dirname, '../templates/vm.hbs')).toString().replace(/\n$/, '') -) +// Templates transforms +const templatesTransform = {} +for (const name of ['markdown', 'mjml']) { + import(`../templates/${name}/transform.js`).then(module => { + templatesTransform[name] = module.transform + }) +} // =================================================================== @@ -88,7 +113,7 @@ const noop = Function.prototype const UNHEALTHY_VDI_CHAIN_ERROR = 'unhealthy VDI chain' const UNHEALTHY_VDI_CHAIN_MESSAGE = - '[(unhealthy VDI chain) Job canceled to protect the VDI chain](https://xen-orchestra.com/docs/backup_troubleshooting.html#vdi-chain-protection)' + '(unhealthy VDI chain) Job canceled to protect the VDI chain. See https://xen-orchestra.com/docs/backup_troubleshooting.html#vdi-chain-protection' const getAdditionnalData = async (task, props) => { if (task.data?.type === 'remote') { @@ -207,8 +232,9 @@ class BackupReportsXoPlugin { } return this._sendReport({ - subject: compiledMetadataSubject(context), - markdown: compiledMetadataTemplate(context), + ...(await templatesTransform.markdown(templates.markdown.metadata(context))), + ...(await templatesTransform.mjml(templates.mjml.metadata(context))), + subject: templates.mjml.metadataSubject(context), success: log.status === 'success', }) } @@ -384,14 +410,15 @@ class BackupReportsXoPlugin { } return this._sendReport({ + ...(await templatesTransform.markdown(templates.markdown.vm(context))), + ...(await templatesTransform.mjml(templates.mjml.vm(context))), mailReceivers, - markdown: compiledVmTemplate(context), - subject: compiledVmSubject(context), + subject: templates.mjml.vmSubject(context), success: log.status === 'success', }) } - async _sendReport({ mailReceivers, markdown, subject, success }) { + async _sendReport({ mailReceivers, markdown, html, subject, success }) { if (mailReceivers === undefined || mailReceivers.length === 0) { mailReceivers = this._mailsReceivers } @@ -404,7 +431,8 @@ class BackupReportsXoPlugin { : xo.sendEmail({ to: mailReceivers, subject, - markdown, + html, + text: markdown, })), this._xmppReceivers !== undefined && (xo.sendEmail === undefined diff --git a/packages/xo-server-backup-reports/templates/metadata.hbs b/packages/xo-server-backup-reports/templates/markdown/metadata.hbs similarity index 96% rename from packages/xo-server-backup-reports/templates/metadata.hbs rename to packages/xo-server-backup-reports/templates/markdown/metadata.hbs index ef6fddc2157..5d4deeb379f 100644 --- a/packages/xo-server-backup-reports/templates/metadata.hbs +++ b/packages/xo-server-backup-reports/templates/markdown/metadata.hbs @@ -12,7 +12,7 @@ {{#each tasksByStatus}} --- -{{titleByStatus @key}} +## {{titleByStatus @key .}} {{#each this}} diff --git a/packages/xo-server-backup-reports/templates/metadataSubject.hbs b/packages/xo-server-backup-reports/templates/markdown/metadataSubject.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/metadataSubject.hbs rename to packages/xo-server-backup-reports/templates/markdown/metadataSubject.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/metadataSubTask.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/metadataSubTask.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/metadataSubTask.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/metadataSubTask.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/reportError.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/reportError.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/reportError.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/reportError.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/reportTemporalData.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/reportTemporalData.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/reportTemporalData.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/reportTemporalData.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/reportWarnings.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/reportWarnings.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/reportWarnings.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/reportWarnings.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/taskBody.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/taskBody.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/taskBody.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/taskBody.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/taskTitle.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/taskTitle.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/taskTitle.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/taskTitle.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/vmFailure.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/vmFailure.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/vmFailure.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/vmFailure.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/vmInterrupted.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/vmInterrupted.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/vmInterrupted.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/vmInterrupted.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/vmSkipped.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/vmSkipped.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/vmSkipped.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/vmSkipped.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/vmSubTask.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/vmSubTask.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/vmSubTask.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/vmSubTask.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/vmSubText.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/vmSubText.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/vmSubText.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/vmSubText.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/vmSuccess.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/vmSuccess.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/vmSuccess.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/vmSuccess.hbs diff --git a/packages/xo-server-backup-reports/templates/partials/vmText.hbs b/packages/xo-server-backup-reports/templates/markdown/partials/vmText.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/partials/vmText.hbs rename to packages/xo-server-backup-reports/templates/markdown/partials/vmText.hbs diff --git a/packages/xo-server-backup-reports/templates/markdown/transform.js b/packages/xo-server-backup-reports/templates/markdown/transform.js new file mode 100644 index 00000000000..487d6547586 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/markdown/transform.js @@ -0,0 +1,5 @@ +'use strict' + +exports.transform = async function transform(source) { + return { markdown: source } +} diff --git a/packages/xo-server-backup-reports/templates/vm.hbs b/packages/xo-server-backup-reports/templates/markdown/vm.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/vm.hbs rename to packages/xo-server-backup-reports/templates/markdown/vm.hbs diff --git a/packages/xo-server-backup-reports/templates/vmSubject.hbs b/packages/xo-server-backup-reports/templates/markdown/vmSubject.hbs similarity index 100% rename from packages/xo-server-backup-reports/templates/vmSubject.hbs rename to packages/xo-server-backup-reports/templates/markdown/vmSubject.hbs diff --git a/packages/xo-server-backup-reports/templates/mjml/metadata.hbs b/packages/xo-server-backup-reports/templates/mjml/metadata.hbs new file mode 100644 index 00000000000..6ee3eaab69d --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/metadata.hbs @@ -0,0 +1,79 @@ + + {{>mjmlHeaders}} + + + + + + Metadata backup report + + + + + + + + + + +

Global status : {{log.status}} {{getIcon log.status}}

+
    +
  • Job ID: {{log.jobId}}
  • +
  • Job name: {{jobName}}
  • +
  • Run ID: {{log.id}}
  • + {{>reportTemporalData end=log.end start=log.start}} {{#if log.tasks.length}} +
  • + Successes: {{#if tasksByStatus.success.length ~}} + {{tasksByStatus.success.length}} {{~else~}} 0 {{~/if}} / {{log.tasks.length}} +
  • + {{/if}} {{>reportError task=log}} {{>reportWarnings task=log}} +
+
+
+
+ + {{#each tasksByStatus}} + + + + +

{{titleByStatus @key .}}

+
+
+
+ {{#each this}} + + + +

{{>taskTitle task=. jobName=../../log.jobName}}

+
    + {{>taskBody task=.}} {{>reportTemporalData formatDate=../../formatDate}} {{>reportError task=.}} + {{>reportWarnings task=this}} +
+
+
+
+ {{#each this.tasks}} + + + + {{>taskTitle task=. jobName=''}} {{getIcon status}} +
    + {{>taskBody task=.}} + {{>reportTemporalData formatDate=../../../formatDate}} + {{>reportError task=.}} + {{>reportWarnings task =.}} +
+
+
+
+ {{/each}} + {{/each}} + {{/each}} + + {{>mjmlFooter}} +
+
+
diff --git a/packages/xo-server-backup-reports/templates/mjml/metadataSubject.hbs b/packages/xo-server-backup-reports/templates/mjml/metadataSubject.hbs new file mode 100644 index 00000000000..90f103c6b2b --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/metadataSubject.hbs @@ -0,0 +1 @@ +[Xen Orchestra] {{{log.status}}} − Metadata backup report for {{{log.jobName}}} {{{getIcon log.status}}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/mjmlFooter.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/mjmlFooter.hbs new file mode 100644 index 00000000000..5892551c658 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/mjmlFooter.hbs @@ -0,0 +1,14 @@ + + + + {{pkg.name}} v{{pkg.version}} + + + + + + + + diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/mjmlHeaders.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/mjmlHeaders.hbs new file mode 100644 index 00000000000..077640f0259 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/mjmlHeaders.hbs @@ -0,0 +1,16 @@ + + Backup report + + + + + + + + + a { color: #fffce4; } a:hover { color: #be1621; } p { color: #fffce4; font-weight: 200; line-height:22px; } h2 { + margin-top: 10px; margin-bottom: 0px; } h3 { font-weight: 500; margin-top: 0; margin-bottom: 13px; font-size: + 20px; } h3 a { color: #fffce4; text-decoration: none; } h3 a:hover { color: #be1621; border-bottom: + 1px solid #be1621; } ul { margin:0px; } + + diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/reportError.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/reportError.hbs new file mode 100644 index 00000000000..b6d69904ee1 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/reportError.hbs @@ -0,0 +1,7 @@ +{{#ifCond task.status '!==' 'success'}} +{{#if task.result.message}} +
  • {{#ifCond task.status '===' 'skipped'~}} Reason {{~^~}} Error {{~/ifCond}}: {{task.result.message}}
  • +{{else if task.result.code}} +
  • {{#ifCond task.status '===' 'skipped'~}} Reason {{~^~}} Error {{~/ifCond}}: {{task.result.code}}
  • +{{/if}} +{{/ifCond}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/reportTemporalData.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/reportTemporalData.hbs new file mode 100644 index 00000000000..21a3b6afd61 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/reportTemporalData.hbs @@ -0,0 +1,7 @@ +
  • Start time: {{executeFunction formatDate start}}
  • +{{#if end}} +
  • End time: {{executeFunction formatDate end}}
  • +{{#ifCond (subtract end start) '>=' 1}} +
  • Duration: {{formatDuration (subtract end start)}}
  • +{{/ifCond}} +{{/if}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/reportWarnings.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/reportWarnings.hbs new file mode 100644 index 00000000000..44d25b48c8b --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/reportWarnings.hbs @@ -0,0 +1,3 @@ +{{#each task.warnings}} +
  • ⚠️ {{message}}
  • +{{/each}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/taskBody.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/taskBody.hbs new file mode 100644 index 00000000000..6edf9c4967e --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/taskBody.hbs @@ -0,0 +1,10 @@ +{{#ifCond task.data.type '===' 'remote'}} +
  • ID: {{task.data.id}}
  • +{{/ifCond}} +{{#ifCond task.data.type '===' 'pool'}} +{{#if task.data.pool.uuid}} +
  • UUID: {{task.data.pool.uuid}}
  • +{{else}} +
  • ID: {{task.data.id}}
  • +{{/if}} +{{/ifCond}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/taskTitle.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/taskTitle.hbs new file mode 100644 index 00000000000..cb83ec457e0 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/taskTitle.hbs @@ -0,0 +1,9 @@ +{{#ifCond task.data.type '===' 'xo'}} +[XO] {{{jobName}}} +{{~/ifCond}} +{{#ifCond task.data.type '===' 'remote'}} +[remote] {{{task.additionnalData.name}}} +{{~/ifCond}} +{{#ifCond task.data.type '===' 'pool'}} +[pool] {{#if task.data.pool.name_label ~}} {{{task.data.pool.name_label}}} {{~else if task.data.poolMaster.name_label ~}} {{{task.data.poolMaster.name_label}}} {{~else~}} Unknown {{~/if}} +{{~/ifCond}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/vmFailure.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/vmFailure.hbs new file mode 100644 index 00000000000..98487492172 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/vmFailure.hbs @@ -0,0 +1,36 @@ + + + + +

    {{titleByStatus 'failure' tasksByStatus.failure.tasks}}

    +
    +
    +
    + +{{#each tasksByStatus.failure.tasks}} + + + + {{#if uuid}} +

    {{name}}

    +
      +
    • UUID: {{uuid}}
    • +
    • Type: {{taskLog.data.type}}
    • + {{>reportTemporalData end=taskLog.end start=taskLog.start}} + {{>reportWarnings task=taskLog}} +
    • Error: {{taskLog.result.message}}
    • +
    + {{else}} + {{>vmText formatDate=../formatDate}} + {{#if taskLog.result}} +
  • Error: {{taskLog.result.message}}
  • + + {{else}} + + {{>vmSubText formatDate=../formatDate}} + {{/if}} + {{/if}} +
    +
    +
    +{{/each}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/vmInterrupted.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/vmInterrupted.hbs new file mode 100644 index 00000000000..6c446e80d3b --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/vmInterrupted.hbs @@ -0,0 +1,20 @@ + + + + +

    {{titleByStatus 'interrupted' tasksByStatus.interrupted.tasks}}

    +
    +
    +
    + +{{#each tasksByStatus.interrupted.tasks}} + + + + {{>vmText formatDate=../formatDate}} + + + + + {{>vmSubText formatDate=../formatDate}} +{{/each}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/vmSkipped.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/vmSkipped.hbs new file mode 100644 index 00000000000..6760c1c1c07 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/vmSkipped.hbs @@ -0,0 +1,20 @@ + + + + +

    {{titleByStatus 'skipped' tasksByStatus.skipped.tasks}}

    +
    +
    +
    + +{{#each tasksByStatus.skipped.tasks}} + + + + {{>vmText formatDate=../formatDate}} +
  • Reason: {{message}}
  • + +
    +
    +
    +{{/each}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/vmSubTask.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/vmSubTask.hbs new file mode 100644 index 00000000000..25367d9d262 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/vmSubTask.hbs @@ -0,0 +1,31 @@ +{{#if subTaskLog}} + + + + {{title}} ({{id}}) {{getIcon subTaskLog.status}} +
      + {{>reportTemporalData end=subTaskLog.end start=subTaskLog.start}} + {{>reportWarnings task=subTaskLog}} + {{>reportError task=subTaskLog}} +
    +
    +
    +
    +{{else}} + + + + {{operationLog.message}} {{getIcon operationLog.status}} +
      + {{>reportTemporalData end=operationLog.end start=operationLog.start}} + {{#if operationLog.result.size}} +
    • Size: {{formatSize operationLog.result.size}}
    • +
    • Speed: {{formatSpeed operationLog.result.size operationLog.start operationLog.end}}
    • + {{/if}} + {{>reportWarnings task=operationLog}} + {{>reportError task=operationLog}} +
    +
    +
    +
    +{{/if}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/vmSubText.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/vmSubText.hbs new file mode 100644 index 00000000000..d4a04fc4440 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/vmSubText.hbs @@ -0,0 +1,48 @@ +{{#each snapshotSubtasks}} + + + + ➤ Snapshot {{getIcon subTaskLog.status}} + + + + + + + +
      + {{>reportTemporalData end=subTaskLog.end start=subTaskLog.start formatDate=../formatDate}} +
    +
    +
    +
    +{{/each}} + +{{#if srsSubTasks}} + + + + + ➤ SRs + + + + + {{#each srsSubTasks}} + {{>vmSubTask formatDate=../formatDate}} + {{/each}} +{{/if}} + +{{#if remotesSubTasks}} + + + + ➤ Remotes + + + + + {{#each remotesSubTasks}} + {{>vmSubTask formatDate=../formatDate}} + {{/each}} +{{/if}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/vmSuccess.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/vmSuccess.hbs new file mode 100644 index 00000000000..05ad6eb1f81 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/vmSuccess.hbs @@ -0,0 +1,20 @@ + + + + +

    {{titleByStatus 'success' tasksByStatus.success.tasks}}

    +
    +
    +
    + +{{#each tasksByStatus.success.tasks}} + + + + {{>vmText formatDate=../formatDate}} + + + + + {{>vmSubText formatDate=../formatDate}} +{{/each}} diff --git a/packages/xo-server-backup-reports/templates/mjml/partials/vmText.hbs b/packages/xo-server-backup-reports/templates/mjml/partials/vmText.hbs new file mode 100644 index 00000000000..3b3a43a51c8 --- /dev/null +++ b/packages/xo-server-backup-reports/templates/mjml/partials/vmText.hbs @@ -0,0 +1,12 @@ + +{{#if vm}} +

    {{vm.name_label}}

    +