feat(export): add branding footer to all 5 export formats and PDF spinner
- Add "Generated with ResolutionFlow — https://resolutionflow.com" footer to markdown, text, HTML, PSA formats (both troubleshooting and procedural variants — 8 generators total) - Fix PDF @page CSS: "Powered by ResolutionFlow" now appears on every PDF, not just for users with a custom logo (removed the has_custom_logo conditional) - Add Loader2 spinner icon to PDF download button in ExportPreviewModal when pdfLoading is true, replacing the static Download icon Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -299,6 +299,10 @@ def generate_markdown_export(session: Session, options: SessionExport, supportin
|
||||
lines.append(next_steps.strip())
|
||||
lines.append("")
|
||||
|
||||
# Branding footer
|
||||
lines.append("---")
|
||||
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@@ -408,6 +412,11 @@ def generate_text_export(session: Session, options: SessionExport, supporting_da
|
||||
lines.append("-" * 20)
|
||||
lines.append(next_steps.strip())
|
||||
|
||||
# Branding footer
|
||||
lines.append("")
|
||||
lines.append("---")
|
||||
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@@ -524,6 +533,10 @@ def generate_html_export(session: Session, options: SessionExport, supporting_da
|
||||
html_parts.append('<h2>Next Steps</h2>')
|
||||
html_parts.append(f'<div style="white-space: pre-wrap; margin-bottom: 20px;">{html.escape(next_steps.strip())}</div>')
|
||||
|
||||
# Branding footer
|
||||
html_parts.append('<hr style="margin-top: 32px; border: none; border-top: 1px solid #ddd;">')
|
||||
html_parts.append('<p style="margin-top: 12px; font-size: 0.8em; color: #999; text-align: center;">Generated with <a href="https://resolutionflow.com" style="color: #06b6d4; text-decoration: none;">ResolutionFlow</a> — https://resolutionflow.com</p>')
|
||||
|
||||
html_parts.extend(['</body>', '</html>'])
|
||||
return "\n".join(html_parts)
|
||||
|
||||
@@ -648,6 +661,11 @@ def generate_psa_export(session: Session, options: SessionExport, supporting_dat
|
||||
scratchpad = getattr(session, 'scratchpad', '') or ''
|
||||
lines.append(scratchpad.strip() if scratchpad.strip() else "None")
|
||||
|
||||
# Branding footer
|
||||
lines.append("")
|
||||
lines.append("---")
|
||||
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@@ -737,6 +755,10 @@ def _generate_procedural_markdown(session: Session, options: SessionExport) -> s
|
||||
lines.append(outcome_notes.strip())
|
||||
lines.append("")
|
||||
|
||||
# Branding footer
|
||||
lines.append("---")
|
||||
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@@ -802,6 +824,11 @@ def _generate_procedural_text(session: Session, options: SessionExport) -> str:
|
||||
lines.append("-" * 20)
|
||||
lines.append(outcome_notes.strip())
|
||||
|
||||
# Branding footer
|
||||
lines.append("")
|
||||
lines.append("---")
|
||||
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@@ -887,6 +914,10 @@ def _generate_procedural_html(session: Session, options: SessionExport) -> str:
|
||||
html_parts.append('<h2>Notes</h2>')
|
||||
html_parts.append(f'<div style="white-space: pre-wrap;">{html.escape(outcome_notes.strip())}</div>')
|
||||
|
||||
# Branding footer
|
||||
html_parts.append('<hr style="margin-top: 32px; border: none; border-top: 1px solid #ddd;">')
|
||||
html_parts.append('<p style="margin-top: 12px; font-size: 0.8em; color: #999; text-align: center;">Generated with <a href="https://resolutionflow.com" style="color: #06b6d4; text-decoration: none;">ResolutionFlow</a> — https://resolutionflow.com</p>')
|
||||
|
||||
html_parts.extend(['</body>', '</html>'])
|
||||
return "\n".join(html_parts)
|
||||
|
||||
@@ -956,6 +987,11 @@ def _generate_procedural_psa(session: Session, options: SessionExport) -> str:
|
||||
lines.append("--- TIME SPENT ---")
|
||||
lines.append(f"Duration: {_format_duration(session.started_at, session.completed_at)}")
|
||||
|
||||
# Branding footer
|
||||
lines.append("")
|
||||
lines.append("---")
|
||||
lines.append("Generated with ResolutionFlow — https://resolutionflow.com")
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
{% if has_custom_logo %}
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 2cm;
|
||||
@@ -18,17 +17,6 @@
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
{% else %}
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 2cm;
|
||||
@bottom-left {
|
||||
content: "Generated {{ generated_at }}";
|
||||
font-size: 8pt;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Copy, Download, Check, RotateCcw, FileDown } from 'lucide-react'
|
||||
import { Copy, Download, Check, RotateCcw, FileDown, Loader2 } from 'lucide-react'
|
||||
import { Modal } from '@/components/common/Modal'
|
||||
import { cn } from '@/lib/utils'
|
||||
import type { RedactionSummary } from '@/types'
|
||||
@@ -149,7 +149,11 @@ export function ExportPreviewModal({
|
||||
'disabled:opacity-60 disabled:cursor-not-allowed'
|
||||
)}
|
||||
>
|
||||
<Download className="h-4 w-4" />
|
||||
{pdfLoading ? (
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
) : (
|
||||
<Download className="h-4 w-4" />
|
||||
)}
|
||||
{pdfLoading ? 'Generating PDF...' : 'Download PDF'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user