@flusys/ng-email 1.0.0-rc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flusys-ng-email-template-form.component-u40UX6yY.mjs","sources":["../../../projects/ng-email/pages/template/template-form.component.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n signal,\n} from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { APP_CONFIG, DEFAULT_APP_NAME } from '@flusys/ng-core';\nimport { LAYOUT_AUTH_STATE } from '@flusys/ng-layout';\nimport { AngularModule, PrimeModule } from '@flusys/ng-shared';\nimport { MessageService } from 'primeng/api';\nimport { EmailTemplateApiService } from '../../services/email-template-api.service';\nimport { EmailBuilderStateService } from '../../services/email-builder-state.service';\nimport { IEmailTemplate } from '../../interfaces/email-template.interface';\n\n/** Form model interface for email template */\ninterface IEmailTemplateFormModel {\n id: string;\n name: string;\n slug: string;\n description: string;\n subject: string;\n htmlContent: string;\n textContent: string;\n isActive: boolean;\n isHtml: boolean;\n}\n\n/**\n * Email template form component (create/edit)\n * Uses Angular Signal Forms for reactive form handling\n */\n@Component({\n selector: 'lib-template-form',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [AngularModule, PrimeModule, FormField],\n providers: [MessageService, EmailBuilderStateService],\n template: `\n <div class=\"card mb-4\">\n <!-- Header -->\n <div class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 mb-4\">\n <div>\n <h3 class=\"text-lg sm:text-xl font-semibold m-0\">\n {{ isEditMode() ? 'Edit Template' : 'New Template' }}\n </h3>\n @if (showCompanyInfo()) {\n <p class=\"text-sm text-muted-color mt-1\">\n Company: {{ currentCompanyName() }}\n </p>\n }\n </div>\n </div>\n\n <!-- Form Fields -->\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div class=\"field\">\n <label for=\"name\" class=\"block font-medium mb-2\">Template Name *</label>\n <input\n pInputText\n id=\"name\"\n [formField]=\"templateForm.name\"\n class=\"w-full\"\n placeholder=\"e.g., Welcome Email\"\n />\n </div>\n\n <div class=\"field\">\n <label for=\"slug\" class=\"block font-medium mb-2\">Slug *</label>\n <input\n pInputText\n id=\"slug\"\n [formField]=\"templateForm.slug\"\n class=\"w-full\"\n placeholder=\"e.g., welcome-email\"\n />\n </div>\n\n <div class=\"field md:col-span-2\">\n <label for=\"subject\" class=\"block font-medium mb-2\">Subject *</label>\n <input\n pInputText\n id=\"subject\"\n [formField]=\"templateForm.subject\"\n class=\"w-full\"\n [placeholder]=\"'e.g., Welcome to ' + '{{' + 'appName' + '}}' + '!'\"\n />\n <small class=\"text-muted-color\">Use {{ '{{variableName}}' }} for dynamic content</small>\n </div>\n\n <div class=\"field\">\n <label for=\"description\" class=\"block font-medium mb-2\">Description</label>\n <input\n pInputText\n id=\"description\"\n [formField]=\"templateForm.description\"\n class=\"w-full\"\n placeholder=\"Brief description of the template\"\n />\n </div>\n\n <div class=\"field flex items-center gap-2\">\n <p-toggleswitch [formField]=\"templateForm.isActive\" />\n <label>Active</label>\n </div>\n </div>\n\n <!-- Content Editor & Preview -->\n <div class=\"grid grid-cols-1 gap-4\" [class.lg:grid-cols-2]=\"editorMode() === 'html'\">\n <!-- Editor Panel -->\n <div class=\"card\">\n <div class=\"flex justify-between items-center mb-3\">\n <h3 class=\"font-semibold\">Content</h3>\n <div class=\"flex gap-1\">\n <p-button\n label=\"HTML\"\n [outlined]=\"editorMode() !== 'html'\"\n [severity]=\"editorMode() === 'html' ? 'primary' : 'secondary'\"\n size=\"small\"\n (onClick)=\"setEditorMode('html')\"\n />\n <p-button\n label=\"Plain Text\"\n [outlined]=\"editorMode() !== 'text'\"\n [severity]=\"editorMode() === 'text' ? 'primary' : 'secondary'\"\n size=\"small\"\n (onClick)=\"setEditorMode('text')\"\n />\n </div>\n </div>\n\n <div class=\"h-[400px] overflow-auto\">\n @if (editorMode() === 'html') {\n <textarea\n pTextarea\n [formField]=\"templateForm.htmlContent\"\n class=\"w-full h-full font-mono text-sm resize-none !overflow-x-auto\"\n placeholder=\"<html>...</html>\"\n wrap=\"off\"\n ></textarea>\n } @else {\n <textarea\n pTextarea\n [formField]=\"templateForm.textContent\"\n class=\"w-full h-full font-mono text-sm resize-none !overflow-x-auto\"\n placeholder=\"Enter plain text content for email clients that don't support HTML\"\n wrap=\"off\"\n ></textarea>\n }\n </div>\n @if (editorMode() === 'text') {\n <small class=\"text-muted-color mt-2 block\">\n <i class=\"pi pi-info-circle mr-1\"></i>\n Plain text version sent to email clients without HTML support\n </small>\n }\n </div>\n\n <!-- Preview Panel (HTML mode only) -->\n @if (editorMode() === 'html') {\n <div class=\"card\">\n <div class=\"flex flex-wrap justify-between items-center gap-2 mb-3\">\n <h3 class=\"font-semibold m-0\">Preview</h3>\n <p-tag value=\"Live Preview\" severity=\"info\" />\n </div>\n <div class=\"border border-surface rounded bg-surface-0 dark:bg-surface-900 h-[400px] overflow-auto\">\n @if (formModel().htmlContent) {\n <iframe\n [srcdoc]=\"getPreviewHtml()\"\n class=\"w-full h-full border-0\"\n sandbox=\"allow-same-origin\"\n ></iframe>\n } @else {\n <div class=\"flex items-center justify-center h-full text-muted-color\">\n <div class=\"text-center p-4\">\n <i class=\"pi pi-eye text-4xl mb-2\"></i>\n <p class=\"m-0\">Enter HTML content to see preview</p>\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Form Actions -->\n <div class=\"flex justify-end gap-2 mt-6 pt-4 border-t border-surface\">\n <p-button\n label=\"Cancel\"\n severity=\"secondary\"\n [outlined]=\"true\"\n routerLink=\"../\"\n />\n <p-button\n [label]=\"isEditMode() ? 'Update' : 'Create'\"\n icon=\"pi pi-save\"\n [loading]=\"isLoading()\"\n [disabled]=\"!isFormValid()\"\n (onClick)=\"onSave()\"\n />\n </div>\n </div>\n\n <p-toast />\n `,\n})\nexport class TemplateFormComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly templateService = inject(EmailTemplateApiService);\n private readonly messageService = inject(MessageService);\n private readonly appConfig = inject(APP_CONFIG);\n private readonly companyContext = inject(LAYOUT_AUTH_STATE, { optional: true });\n readonly state = inject(EmailBuilderStateService);\n\n // Route params as signal\n private readonly routeParams = toSignal(this.route.paramMap);\n\n readonly isLoading = signal(false);\n readonly existingTemplate = signal<IEmailTemplate | null>(null);\n readonly isEditMode = computed(() => !!this.existingTemplate());\n readonly editorMode = signal<'html' | 'text'>('html');\n\n readonly showCompanyInfo = computed(\n () => this.appConfig.enableCompanyFeature && !!this.companyContext,\n );\n readonly currentCompanyName = computed(\n () => this.companyContext?.currentCompanyInfo()?.name ?? DEFAULT_APP_NAME,\n );\n\n /** Form model using signal */\n readonly formModel = signal<IEmailTemplateFormModel>({\n id: '',\n name: '',\n slug: '',\n description: '',\n subject: '',\n htmlContent: '',\n textContent: '',\n isActive: true,\n isHtml: true,\n });\n\n /** Form with validation using Angular Signal Forms */\n readonly templateForm = form(this.formModel, (f) => {\n required(f.name, { message: 'Template name is required' });\n required(f.slug, { message: 'Slug is required' });\n required(f.subject, { message: 'Subject is required' });\n });\n\n /** Check if form is valid */\n readonly isFormValid = computed(() => {\n const model = this.formModel();\n return (\n model.name.trim().length > 0 &&\n model.slug.trim().length > 0 &&\n model.subject.trim().length > 0\n );\n });\n\n constructor() {\n // Effect to handle route-based initialization\n effect(() => {\n const params = this.routeParams();\n if (!params) return;\n\n const id = params.get('id');\n if (id) {\n this.loadTemplate(id);\n }\n });\n }\n\n async loadTemplate(id: string): Promise<void> {\n this.isLoading.set(true);\n try {\n const response = await this.templateService.findByIdAsync(id);\n if (response.success && response.data) {\n const template = response.data;\n this.existingTemplate.set(template);\n this.formModel.set({\n id: template.id,\n name: template.name,\n slug: template.slug,\n description: template.description || '',\n subject: template.subject,\n htmlContent: template.htmlContent,\n textContent: template.textContent || '',\n isActive: template.isActive,\n isHtml: template.isHtml ?? true,\n });\n // Set editor mode based on saved template type\n this.editorMode.set(template.isHtml ? 'html' : 'text');\n this.state.loadSchema(template.schema);\n }\n } finally {\n this.isLoading.set(false);\n }\n }\n\n setEditorMode(mode: 'html' | 'text'): void {\n const currentMode = this.editorMode();\n const model = this.formModel();\n\n // Sync content when switching modes\n if (currentMode === 'text' && mode === 'html') {\n // Switching from text to html - convert text to basic HTML if htmlContent is empty\n if (!model.htmlContent && model.textContent) {\n this.formModel.update((m) => ({ ...m, htmlContent: this.textToHtml(m.textContent) }));\n }\n } else if (currentMode === 'html' && mode === 'text') {\n // Switching from html to text - generate text from HTML if textContent is empty\n if (!model.textContent && model.htmlContent) {\n this.formModel.update((m) => ({ ...m, textContent: this.htmlToPlainText(m.htmlContent) }));\n }\n }\n\n this.editorMode.set(mode);\n this.formModel.update((m) => ({ ...m, isHtml: mode === 'html' }));\n }\n\n /** Convert plain text to basic HTML */\n private textToHtml(text: string): string {\n if (!text) return '';\n // Convert line breaks to paragraphs\n return text\n .split(/\\n\\n+/)\n .map((p) => `<p>${p.replace(/\\n/g, '<br>')}</p>`)\n .join('\\n');\n }\n\n /** Convert HTML to plain text (using DOMParser for safe parsing) */\n private htmlToPlainText(html: string): string {\n if (!html) return '';\n // Use DOMParser for safe HTML parsing (prevents XSS)\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n // Get text content and clean up whitespace\n return (doc.body.textContent || '').replace(/\\s+/g, ' ').trim();\n }\n\n /** Get HTML for preview iframe */\n getPreviewHtml(): string {\n const baseStyles = `\n <style>\n body {\n font-family: Arial, sans-serif;\n margin: 16px;\n background-color: #ffffff;\n color: #333333;\n }\n img { max-width: 100%; height: auto; }\n </style>\n `;\n return baseStyles + (this.formModel().htmlContent || '');\n }\n\n async onSave(): Promise<void> {\n if (!this.isFormValid()) {\n this.messageService.add({\n severity: 'warn',\n summary: 'Validation',\n detail: 'Please fill in all required fields.',\n });\n return;\n }\n\n this.isLoading.set(true);\n try {\n const model = this.formModel();\n const schema = this.state.schema();\n // Use user-provided plain text, or auto-generate from HTML if empty\n const textContent = model.textContent || this.htmlToPlainText(model.htmlContent);\n\n const data = {\n name: model.name,\n slug: model.slug,\n description: model.description || undefined,\n subject: model.subject,\n schema: {\n ...schema,\n name: model.name,\n subject: model.subject,\n },\n htmlContent: model.htmlContent || '<p>Email content</p>',\n textContent: textContent || undefined,\n isActive: model.isActive,\n isHtml: model.isHtml,\n };\n\n if (this.isEditMode()) {\n await this.templateService.updateAsync({ id: model.id, ...data });\n } else {\n await this.templateService.createTemplateAsync(data);\n }\n\n this.messageService.add({\n severity: 'success',\n summary: 'Success',\n detail: `Template ${this.isEditMode() ? 'updated' : 'created'} successfully.`,\n });\n\n this.router.navigate(['../'], { relativeTo: this.route });\n } catch {\n // Error toast handled by global interceptor\n } finally {\n this.isLoading.set(false);\n }\n }\n}\n"],"names":["i3","i4","i5","i6"],"mappings":"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"}