diff --git a/changelog.md b/changelog.md index acf2323..8379841 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2024-12-02 - 1.3.0 - feat(translation) +Add multi-language support for document translations. + +- Implemented translation interface for document labels. +- Added Spanish translations alongside existing English and German. +- Updated content invoice, page header, and page footer elements to utilize language-specific translations. + ## 2024-12-01 - 1.2.0 - feat(core) Enhance document generation capabilities with improved modular structure and extended translation support. diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 8ba00ed..028f411 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@design.estate/dees-document', - version: '1.2.0', + version: '1.3.0', description: 'A comprehensive tool for dynamically generating and rendering business documents like invoices using modern web technologies.' } diff --git a/ts/interfaces/translation.ts b/ts/interfaces/translation.ts index b270b93..6ac746c 100644 --- a/ts/interfaces/translation.ts +++ b/ts/interfaces/translation.ts @@ -1,4 +1,19 @@ export interface IDeDocumentTranslations { - "invoice": string; - "quantity": string; + address: string; + bankConnection: string; + contactInfo: string; + description: string; + invoice: string; + itemPos: string; + quantity: string; + registrationInfo: string; + reverseVatNote: string; + totalNetPrice: string; + unitNetPrice: string; + unitType: string; + yourCustomerId: string; + yourVatId: string; + continuesOnPage: string; + finalPageStatement: string; + page: string; } \ No newline at end of file diff --git a/ts/shared/translation.ts b/ts/shared/translation.ts index b2a80e9..68de73c 100644 --- a/ts/shared/translation.ts +++ b/ts/shared/translation.ts @@ -5,18 +5,69 @@ type TTranslationImplementation = { } export const EN_translations: TTranslationImplementation = { + address: 'Address', + bankConnection: 'Bank Connection', + contactInfo: 'Contact Info', + description: 'Description', invoice: 'Invoice', + itemPos: 'Item Pos.', quantity: 'Quantity', + registrationInfo: 'Registration Info', + reverseVatNote: 'VAT arises on a reverse charge basis and is payable by the customer.', + totalNetPrice: 'Total Net Price', + unitNetPrice: 'Unit Net Price', + unitType: 'Unit Type', + yourCustomerId: 'Your Customer ID:', + yourVatId: 'Your vat id on file:', + continuesOnPage: 'Continues on page', + finalPageStatement: 'This is the final page of this document.', + page: 'Page', }; export const DE_translations: TTranslationImplementation = { + address: 'Adresse', + bankConnection: 'Bankverbindung', + contactInfo: 'Kontaktinformationen', + description: 'Beschreibung', invoice: 'Rechnung', + itemPos: 'Pos.', quantity: 'Anzahl', + registrationInfo: 'HRA/HRB Info', + reverseVatNote: 'Umkehr der Umsatzsteuerpflicht: Der Rechnungsempfänger ist für die korrekte Abrechnung der Umsatzsteuer zuständig.', + totalNetPrice: 'Nettopreis Summe', + unitNetPrice: 'Nettopreis', + unitType: 'Einheit', + yourCustomerId: 'Ihre Kundennummer:', + yourVatId: 'Ihre Umsatzsteuer-ID:', + continuesOnPage: 'Fortsetzung auf Seite', + finalPageStatement: 'Diese ist die letzte Seite einer Dokumente.', + page: 'Seite', +}; + +export const ES_translations: TTranslationImplementation = { + address: 'Dirección', + bankConnection: 'Conexión bancaria', + contactInfo: 'Información de contacto', + description: 'Descripción', + invoice: 'Factura', + itemPos: 'Pos.', + quantity: 'Cantidad', + registrationInfo: 'Información de registro', + reverseVatNote: 'La declaración de IVA se aplica en base a la factura de venta, y se paga por el cliente.', + totalNetPrice: 'Precio total neto', + unitNetPrice: 'Precio unitario neto', + unitType: 'Tipo de unidad', + yourCustomerId: 'Su número de cliente:', + yourVatId: 'Su ID de IVA:', + continuesOnPage: 'Continues on page', + finalPageStatement: 'This is the final page of this document.', + page: 'Page', }; export const languageCodeMap = { 'DE': DE_translations, 'EN': EN_translations, + 'ES': ES_translations, }; export type TLanguageCode = keyof typeof languageCodeMap; diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index 8ba00ed..028f411 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@design.estate/dees-document', - version: '1.2.0', + version: '1.3.0', description: 'A comprehensive tool for dynamically generating and rendering business documents like invoices using modern web technologies.' } diff --git a/ts_web/elements/contentinvoice.ts b/ts_web/elements/contentinvoice.ts index b3dcf47..f6dc709 100644 --- a/ts_web/elements/contentinvoice.ts +++ b/ts_web/elements/contentinvoice.ts @@ -16,7 +16,7 @@ import { } from '@design.estate/dees-element'; import * as plugins from '../plugins.js'; import * as shared from '../../ts/shared/index.js'; - +import * as interfaces from '../../ts/interfaces/index.js'; declare global { @@ -45,6 +45,12 @@ export class DeContentInvoice extends DeesElement { }) public letterData: plugins.tsclass.business.ILetter; + @property({ + type: Object, + reflect: true, + }) + public documentSettings: interfaces.IDocumentSettings; + constructor() { super(); domtools.DomTools.setupDomTools(); @@ -275,12 +281,12 @@ export class DeContentInvoice extends DeesElement {
We hereby invoice products and services provided to you by Lossless GmbH:
-
Item Pos.
-
${shared.translation.translate('DE', 'description', 'Description')}
-
${shared.translation.translate('DE', 'quantity', 'Quantity')}
-
Unit Type
-
Unit Net Price
-
Total Net Price
+
${shared.translation.translate(this.documentSettings.languageCode, 'itemPos', 'Item Pos.')}
+
${shared.translation.translate(this.documentSettings.languageCode, 'description', 'Description')}
+
${shared.translation.translate(this.documentSettings.languageCode, 'quantity', 'Quantity')}
+
${shared.translation.translate(this.documentSettings.languageCode, 'unitType', 'Unit Type')}
+
${shared.translation.translate(this.documentSettings.languageCode, 'unitNetPrice', 'Unit Net Price')}
+
${shared.translation.translate(this.documentSettings.languageCode, 'totalNetPrice', 'Total Net Price')}
${(() => { let counter = 1; @@ -329,7 +335,7 @@ export class DeContentInvoice extends DeesElement { ${this.letterData?.content.invoiceData.reverseCharge ? html`
- VAT arises on a reverse charge basis and is payable by the customer. + ${shared.translation.translate(this.documentSettings.languageCode, 'reverseVatNote', 'VAT arises on a reverse charge basis and is payable by the customer.')}
` : ``} diff --git a/ts_web/elements/document.ts b/ts_web/elements/document.ts index 3b032b6..87ae9f9 100644 --- a/ts_web/elements/document.ts +++ b/ts_web/elements/document.ts @@ -146,6 +146,7 @@ export class DeDocument extends DeesElement { // lets append the content const content: DeContentInvoice = new DeContentInvoice(); content.letterData = this.letterData; + content.documentSettings = this.documentSettings; document.body.appendChild(content); await domtools.convenience.smartdelay.delayFor(0); @@ -158,6 +159,7 @@ export class DeDocument extends DeesElement { const newPage = new DePage(); newPage.printMode = this.printMode; newPage.letterData = this.letterData; + newPage.documentSettings = this.documentSettings; pages.push(newPage); newPage.pageNumber = pageCounter; newPage.append(currentContent); diff --git a/ts_web/elements/page.ts b/ts_web/elements/page.ts index d8ef4ef..0cf2692 100644 --- a/ts_web/elements/page.ts +++ b/ts_web/elements/page.ts @@ -127,6 +127,7 @@ export class DePage extends DeesElement { ? html` @@ -137,20 +138,23 @@ export class DePage extends DeesElement { ` : html``} ${this.documentSettings.enableDefaultFooter ? html` diff --git a/ts_web/elements/pagefooter.ts b/ts_web/elements/pagefooter.ts index bfc4f31..20aa4c9 100644 --- a/ts_web/elements/pagefooter.ts +++ b/ts_web/elements/pagefooter.ts @@ -7,8 +7,10 @@ import { css, cssManager, unsafeCSS, + domtools, } from '@design.estate/dees-element'; -import * as domtools from '@design.estate/dees-domtools'; + +import * as interfaces from '../../ts/interfaces/index.js'; import * as shared from '../../ts/shared/index.js'; import * as tsclass from '@tsclass/tsclass'; @@ -30,6 +32,12 @@ export class DePageFooter extends DeesElement { }) letterData: tsclass.business.ILetter; + @property({ + type: Object, + reflect: true, + }) + documentSettings: interfaces.IDocumentSettings; + @property({ type: Number }) @@ -96,26 +104,26 @@ export class DePageFooter extends DeesElement { return html`
- Address:
+ ${shared.translation.translate(this.documentSettings.languageCode, 'address', 'Address')}:
${this.letterData.from.name}
${this.letterData.from.address.streetName} ${this.letterData.from.address.houseNumber}
${this.letterData.from.address.postalCode} ${this.letterData.from.address.city}
${this.letterData.from.address.country}
- Registration Info:
+ ${shared.translation.translate(this.documentSettings.languageCode, 'registrationInfo', 'Registration Info')}:
Amtsgericht Bremen
reg-#: HRB 35230 HB
vat-id: ${this.letterData.from.vatId}
- Contact Info:
+ ${shared.translation.translate(this.documentSettings.languageCode, 'contactInfo', 'Contact Info')}:
email: ${this.letterData.from.email}
phone: ${this.letterData.from.phone}
fax: ${this.letterData.from.fax}
- Bank Connection:
+ ${shared.translation.translate(this.documentSettings.languageCode, 'bankConnection', 'Bank Connection')}:
beneficiary: ${this.letterData?.from?.name}
institution: ${this.letterData?.from?.sepaConnection?.institution}
iban: ${this.letterData?.from?.sepaConnection?.iban}
diff --git a/ts_web/elements/pageheader.ts b/ts_web/elements/pageheader.ts index 0adebf0..b4ddba3 100644 --- a/ts_web/elements/pageheader.ts +++ b/ts_web/elements/pageheader.ts @@ -7,8 +7,10 @@ import { css, cssManager, unsafeCSS, + domtools } from '@design.estate/dees-element'; -import * as domtools from '@design.estate/dees-domtools'; + +import * as interfaces from '../../ts/interfaces/index.js'; import * as shared from '../../ts/shared/index.js'; import * as tsclass from '@tsclass/tsclass'; @@ -30,6 +32,12 @@ export class DePageHeader extends DeesElement { }) public letterData: tsclass.business.ILetter = null; + @property({ + type: Object, + reflect: true, + }) + documentSettings: interfaces.IDocumentSettings; + @property({ type: Number, }) diff --git a/ts_web/elements/viewer.ts b/ts_web/elements/viewer.ts index 10eb5c5..a5efef0 100644 --- a/ts_web/elements/viewer.ts +++ b/ts_web/elements/viewer.ts @@ -3,7 +3,6 @@ import * as interfaces from '../../ts/interfaces/index.js'; import { DeesElement, css, cssManager, customElement, html } from '@design.estate/dees-element'; import { demoFunc } from './viewer.demo.js'; -import { defaultDocumentSettings } from './document.js'; declare global { interface HTMLElementTagNameMap { @@ -19,7 +18,7 @@ export class DeDocumentViewer extends DeesElement { // INSTANCE public letterData: plugins.tsclass.business.ILetter = null; - public documentSettings: interfaces.IDocumentSettings = defaultDocumentSettings; + public documentSettings: interfaces.IDocumentSettings; public static styles = [ cssManager.defaultStyles,