feat(translation): Add multi-language support for document translations.
This commit is contained in:
parent
c8b102e798
commit
d59734fb7c
@ -1,5 +1,12 @@
|
|||||||
# Changelog
|
# 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)
|
## 2024-12-01 - 1.2.0 - feat(core)
|
||||||
Enhance document generation capabilities with improved modular structure and extended translation support.
|
Enhance document generation capabilities with improved modular structure and extended translation support.
|
||||||
|
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@design.estate/dees-document',
|
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.'
|
description: 'A comprehensive tool for dynamically generating and rendering business documents like invoices using modern web technologies.'
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,19 @@
|
|||||||
export interface IDeDocumentTranslations {
|
export interface IDeDocumentTranslations {
|
||||||
"invoice": string;
|
address: string;
|
||||||
"quantity": 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;
|
||||||
}
|
}
|
@ -5,18 +5,69 @@ type TTranslationImplementation = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const EN_translations: TTranslationImplementation = {
|
export const EN_translations: TTranslationImplementation = {
|
||||||
|
address: 'Address',
|
||||||
|
bankConnection: 'Bank Connection',
|
||||||
|
contactInfo: 'Contact Info',
|
||||||
|
description: 'Description',
|
||||||
invoice: 'Invoice',
|
invoice: 'Invoice',
|
||||||
|
itemPos: 'Item Pos.',
|
||||||
quantity: 'Quantity',
|
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 = {
|
export const DE_translations: TTranslationImplementation = {
|
||||||
|
address: 'Adresse',
|
||||||
|
bankConnection: 'Bankverbindung',
|
||||||
|
contactInfo: 'Kontaktinformationen',
|
||||||
|
description: 'Beschreibung',
|
||||||
invoice: 'Rechnung',
|
invoice: 'Rechnung',
|
||||||
|
itemPos: 'Pos.',
|
||||||
quantity: 'Anzahl',
|
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 = {
|
export const languageCodeMap = {
|
||||||
'DE': DE_translations,
|
'DE': DE_translations,
|
||||||
'EN': EN_translations,
|
'EN': EN_translations,
|
||||||
|
'ES': ES_translations,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TLanguageCode = keyof typeof languageCodeMap;
|
export type TLanguageCode = keyof typeof languageCodeMap;
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@design.estate/dees-document',
|
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.'
|
description: 'A comprehensive tool for dynamically generating and rendering business documents like invoices using modern web technologies.'
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import {
|
|||||||
} from '@design.estate/dees-element';
|
} from '@design.estate/dees-element';
|
||||||
import * as plugins from '../plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import * as shared from '../../ts/shared/index.js';
|
import * as shared from '../../ts/shared/index.js';
|
||||||
|
import * as interfaces from '../../ts/interfaces/index.js';
|
||||||
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@ -45,6 +45,12 @@ export class DeContentInvoice extends DeesElement {
|
|||||||
})
|
})
|
||||||
public letterData: plugins.tsclass.business.ILetter;
|
public letterData: plugins.tsclass.business.ILetter;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Object,
|
||||||
|
reflect: true,
|
||||||
|
})
|
||||||
|
public documentSettings: interfaces.IDocumentSettings;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
domtools.DomTools.setupDomTools();
|
domtools.DomTools.setupDomTools();
|
||||||
@ -275,12 +281,12 @@ export class DeContentInvoice extends DeesElement {
|
|||||||
</style>
|
</style>
|
||||||
<div>We hereby invoice products and services provided to you by Lossless GmbH:</div>
|
<div>We hereby invoice products and services provided to you by Lossless GmbH:</div>
|
||||||
<div class="grid topLine dataHeader">
|
<div class="grid topLine dataHeader">
|
||||||
<div class="lineItem">Item Pos.</div>
|
<div class="lineItem">${shared.translation.translate(this.documentSettings.languageCode, 'itemPos', 'Item Pos.')}</div>
|
||||||
<div class="lineItem">${shared.translation.translate('DE', 'description', 'Description')}</div>
|
<div class="lineItem">${shared.translation.translate(this.documentSettings.languageCode, 'description', 'Description')}</div>
|
||||||
<div class="lineItem">${shared.translation.translate('DE', 'quantity', 'Quantity')}</div>
|
<div class="lineItem">${shared.translation.translate(this.documentSettings.languageCode, 'quantity', 'Quantity')}</div>
|
||||||
<div class="lineItem">Unit Type</div>
|
<div class="lineItem">${shared.translation.translate(this.documentSettings.languageCode, 'unitType', 'Unit Type')}</div>
|
||||||
<div class="lineItem">Unit Net Price</div>
|
<div class="lineItem">${shared.translation.translate(this.documentSettings.languageCode, 'unitNetPrice', 'Unit Net Price')}</div>
|
||||||
<div class="lineItem">Total Net Price</div>
|
<div class="lineItem">${shared.translation.translate(this.documentSettings.languageCode, 'totalNetPrice', 'Total Net Price')}</div>
|
||||||
</div>
|
</div>
|
||||||
${(() => {
|
${(() => {
|
||||||
let counter = 1;
|
let counter = 1;
|
||||||
@ -329,7 +335,7 @@ export class DeContentInvoice extends DeesElement {
|
|||||||
${this.letterData?.content.invoiceData.reverseCharge
|
${this.letterData?.content.invoiceData.reverseCharge
|
||||||
? html`
|
? html`
|
||||||
<div class="taxNote">
|
<div class="taxNote">
|
||||||
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.')}
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ``}
|
: ``}
|
||||||
|
@ -146,6 +146,7 @@ export class DeDocument extends DeesElement {
|
|||||||
// lets append the content
|
// lets append the content
|
||||||
const content: DeContentInvoice = new DeContentInvoice();
|
const content: DeContentInvoice = new DeContentInvoice();
|
||||||
content.letterData = this.letterData;
|
content.letterData = this.letterData;
|
||||||
|
content.documentSettings = this.documentSettings;
|
||||||
document.body.appendChild(content);
|
document.body.appendChild(content);
|
||||||
|
|
||||||
await domtools.convenience.smartdelay.delayFor(0);
|
await domtools.convenience.smartdelay.delayFor(0);
|
||||||
@ -158,6 +159,7 @@ export class DeDocument extends DeesElement {
|
|||||||
const newPage = new DePage();
|
const newPage = new DePage();
|
||||||
newPage.printMode = this.printMode;
|
newPage.printMode = this.printMode;
|
||||||
newPage.letterData = this.letterData;
|
newPage.letterData = this.letterData;
|
||||||
|
newPage.documentSettings = this.documentSettings;
|
||||||
pages.push(newPage);
|
pages.push(newPage);
|
||||||
newPage.pageNumber = pageCounter;
|
newPage.pageNumber = pageCounter;
|
||||||
newPage.append(currentContent);
|
newPage.append(currentContent);
|
||||||
|
@ -127,6 +127,7 @@ export class DePage extends DeesElement {
|
|||||||
? html`
|
? html`
|
||||||
<dedocument-pageheader
|
<dedocument-pageheader
|
||||||
.letterData=${this.letterData}
|
.letterData=${this.letterData}
|
||||||
|
.documentSettings=${this.documentSettings}
|
||||||
.pageNumber="${this.pageNumber}"
|
.pageNumber="${this.pageNumber}"
|
||||||
.pageTotalNumber="${this.pageTotalNumber}"
|
.pageTotalNumber="${this.pageTotalNumber}"
|
||||||
></dedocument-pageheader>
|
></dedocument-pageheader>
|
||||||
@ -137,20 +138,23 @@ export class DePage extends DeesElement {
|
|||||||
<dedocument-letterheader
|
<dedocument-letterheader
|
||||||
.pageNumber="${this.pageNumber}"
|
.pageNumber="${this.pageNumber}"
|
||||||
.letterData=${this.letterData}
|
.letterData=${this.letterData}
|
||||||
|
.documentSettings=${this.documentSettings}
|
||||||
.pageTotalNumber="${this.pageTotalNumber}"
|
.pageTotalNumber="${this.pageTotalNumber}"
|
||||||
></dedocument-letterheader>
|
></dedocument-letterheader>
|
||||||
`
|
`
|
||||||
: html``}
|
: html``}
|
||||||
<dedocument-pagecontent
|
<dedocument-pagecontent
|
||||||
|
.letterData=${this.letterData}
|
||||||
|
.documentSettings=${this.documentSettings}
|
||||||
.pageNumber="${this.pageNumber}"
|
.pageNumber="${this.pageNumber}"
|
||||||
.pageTotalNumber="${this.pageTotalNumber}"
|
.pageTotalNumber="${this.pageTotalNumber}"
|
||||||
.letterData=${this.letterData}
|
|
||||||
><slot></slot
|
><slot></slot
|
||||||
></dedocument-pagecontent>
|
></dedocument-pagecontent>
|
||||||
${this.documentSettings.enableDefaultFooter
|
${this.documentSettings.enableDefaultFooter
|
||||||
? html`
|
? html`
|
||||||
<dedocument-pagefooter
|
<dedocument-pagefooter
|
||||||
.letterData=${this.letterData}
|
.letterData=${this.letterData}
|
||||||
|
.documentSettings=${this.documentSettings}
|
||||||
.pageNumber="${this.pageNumber}"
|
.pageNumber="${this.pageNumber}"
|
||||||
.pageTotalNumber="${this.pageTotalNumber}"
|
.pageTotalNumber="${this.pageTotalNumber}"
|
||||||
></dedocument-pagefooter>
|
></dedocument-pagefooter>
|
||||||
|
@ -7,8 +7,10 @@ import {
|
|||||||
css,
|
css,
|
||||||
cssManager,
|
cssManager,
|
||||||
unsafeCSS,
|
unsafeCSS,
|
||||||
|
domtools,
|
||||||
} from '@design.estate/dees-element';
|
} 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 shared from '../../ts/shared/index.js';
|
||||||
import * as tsclass from '@tsclass/tsclass';
|
import * as tsclass from '@tsclass/tsclass';
|
||||||
@ -30,6 +32,12 @@ export class DePageFooter extends DeesElement {
|
|||||||
})
|
})
|
||||||
letterData: tsclass.business.ILetter;
|
letterData: tsclass.business.ILetter;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Object,
|
||||||
|
reflect: true,
|
||||||
|
})
|
||||||
|
documentSettings: interfaces.IDocumentSettings;
|
||||||
|
|
||||||
@property({
|
@property({
|
||||||
type: Number
|
type: Number
|
||||||
})
|
})
|
||||||
@ -96,26 +104,26 @@ export class DePageFooter extends DeesElement {
|
|||||||
return html`
|
return html`
|
||||||
<div class="bottomstripe">
|
<div class="bottomstripe">
|
||||||
<div>
|
<div>
|
||||||
<strong>Address:</strong><br />
|
<strong>${shared.translation.translate(this.documentSettings.languageCode, 'address', 'Address')}:</strong><br />
|
||||||
${this.letterData.from.name}<br />
|
${this.letterData.from.name}<br />
|
||||||
${this.letterData.from.address.streetName} ${this.letterData.from.address.houseNumber}<br />
|
${this.letterData.from.address.streetName} ${this.letterData.from.address.houseNumber}<br />
|
||||||
${this.letterData.from.address.postalCode} ${this.letterData.from.address.city}<br />
|
${this.letterData.from.address.postalCode} ${this.letterData.from.address.city}<br />
|
||||||
${this.letterData.from.address.country}
|
${this.letterData.from.address.country}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<strong>Registration Info:</strong><br />
|
<strong>${shared.translation.translate(this.documentSettings.languageCode, 'registrationInfo', 'Registration Info')}:</strong><br />
|
||||||
Amtsgericht Bremen<br />
|
Amtsgericht Bremen<br />
|
||||||
<i>reg-#:</i> HRB 35230 HB<br />
|
<i>reg-#:</i> HRB 35230 HB<br />
|
||||||
<i>vat-id:</i> ${this.letterData.from.vatId}
|
<i>vat-id:</i> ${this.letterData.from.vatId}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<strong>Contact Info:</strong><br />
|
<strong>${shared.translation.translate(this.documentSettings.languageCode, 'contactInfo', 'Contact Info')}:</strong><br />
|
||||||
<i>email:</i> ${this.letterData.from.email}<br />
|
<i>email:</i> ${this.letterData.from.email}<br />
|
||||||
<i>phone:</i> ${this.letterData.from.phone}<br />
|
<i>phone:</i> ${this.letterData.from.phone}<br />
|
||||||
<i>fax:</i> ${this.letterData.from.fax}
|
<i>fax:</i> ${this.letterData.from.fax}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<strong>Bank Connection:</strong><br />
|
<strong>${shared.translation.translate(this.documentSettings.languageCode, 'bankConnection', 'Bank Connection')}:</strong><br />
|
||||||
<i>beneficiary:</i> ${this.letterData?.from?.name}<br />
|
<i>beneficiary:</i> ${this.letterData?.from?.name}<br />
|
||||||
<i>institution:</i> ${this.letterData?.from?.sepaConnection?.institution}<br />
|
<i>institution:</i> ${this.letterData?.from?.sepaConnection?.institution}<br />
|
||||||
<i>iban:</i> ${this.letterData?.from?.sepaConnection?.iban}<br />
|
<i>iban:</i> ${this.letterData?.from?.sepaConnection?.iban}<br />
|
||||||
|
@ -7,8 +7,10 @@ import {
|
|||||||
css,
|
css,
|
||||||
cssManager,
|
cssManager,
|
||||||
unsafeCSS,
|
unsafeCSS,
|
||||||
|
domtools
|
||||||
} from '@design.estate/dees-element';
|
} 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 shared from '../../ts/shared/index.js';
|
||||||
import * as tsclass from '@tsclass/tsclass';
|
import * as tsclass from '@tsclass/tsclass';
|
||||||
@ -30,6 +32,12 @@ export class DePageHeader extends DeesElement {
|
|||||||
})
|
})
|
||||||
public letterData: tsclass.business.ILetter = null;
|
public letterData: tsclass.business.ILetter = null;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Object,
|
||||||
|
reflect: true,
|
||||||
|
})
|
||||||
|
documentSettings: interfaces.IDocumentSettings;
|
||||||
|
|
||||||
@property({
|
@property({
|
||||||
type: Number,
|
type: Number,
|
||||||
})
|
})
|
||||||
|
@ -3,7 +3,6 @@ import * as interfaces from '../../ts/interfaces/index.js';
|
|||||||
|
|
||||||
import { DeesElement, css, cssManager, customElement, html } from '@design.estate/dees-element';
|
import { DeesElement, css, cssManager, customElement, html } from '@design.estate/dees-element';
|
||||||
import { demoFunc } from './viewer.demo.js';
|
import { demoFunc } from './viewer.demo.js';
|
||||||
import { defaultDocumentSettings } from './document.js';
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
@ -19,7 +18,7 @@ export class DeDocumentViewer extends DeesElement {
|
|||||||
// INSTANCE
|
// INSTANCE
|
||||||
public letterData: plugins.tsclass.business.ILetter = null;
|
public letterData: plugins.tsclass.business.ILetter = null;
|
||||||
|
|
||||||
public documentSettings: interfaces.IDocumentSettings = defaultDocumentSettings;
|
public documentSettings: interfaces.IDocumentSettings;
|
||||||
|
|
||||||
public static styles = [
|
public static styles = [
|
||||||
cssManager.defaultStyles,
|
cssManager.defaultStyles,
|
||||||
|
Loading…
Reference in New Issue
Block a user