Compare commits

..

15 Commits

Author SHA1 Message Date
9517687902 1.5.3 2024-12-02 17:05:03 +01:00
b5d3a72733 fix(elements): Update viewer attributes and fix font integration 2024-12-02 17:05:03 +01:00
08baae7b9c 1.5.2 2024-12-02 16:13:37 +01:00
c949f1b968 fix(workflow): Corrected Docker image references and package scope in YAML workflows for compatibility. 2024-12-02 16:13:37 +01:00
249d44d5fc 1.5.1 2024-12-02 16:05:44 +01:00
de02e015e8 fix(package): Fix duplicate node export in package.json 2024-12-02 16:05:44 +01:00
3e50547d91 1.5.0 2024-12-02 16:04:58 +01:00
c9ad18538b feat(core): Refactor project structure for better modularity and code organization 2024-12-02 16:04:58 +01:00
bab1ffc4b4 1.4.0 2024-12-02 15:20:58 +01:00
8986ec2543 feat(translation): Add French and Italian translations for document interface 2024-12-02 15:20:57 +01:00
49c15a98e4 1.3.2 2024-12-02 15:05:07 +01:00
840de119ad fix(core): Minor updates and optimizations in the output PDF formatting process. 2024-12-02 15:05:07 +01:00
3919956c57 Merge remote-tracking branch 'origin/master' 2024-12-02 15:04:22 +01:00
bc4f018b06 Merge pull request 'fix: use type import to avoid ts dependency in js files' (#1) from fix/use-type-import into master
Reviewed-on: #1
2024-12-02 13:37:59 +00:00
8f7677ab82 fix: use type import to avoid ts dependency in js files 2024-12-02 12:59:19 +00:00
42 changed files with 292 additions and 160 deletions

View File

@ -6,8 +6,8 @@ on:
- '**' - '**'
env: env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci IMAGE: code.foss.global/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}} NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}} NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}} NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
@ -26,7 +26,7 @@ jobs:
- name: Install pnpm and npmci - name: Install pnpm and npmci
run: | run: |
pnpm install -g pnpm pnpm install -g pnpm
pnpm install -g @shipzone/npmci pnpm install -g @ship.zone/npmci
- name: Run npm prepare - name: Run npm prepare
run: npmci npm prepare run: npmci npm prepare

View File

@ -6,8 +6,8 @@ on:
- '*' - '*'
env: env:
IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci IMAGE: code.foss.global/hosttoday/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@gitea.lossless.digital/${{gitea.repository}}.git NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}} NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}} NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}} NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
@ -26,7 +26,7 @@ jobs:
- name: Prepare - name: Prepare
run: | run: |
pnpm install -g pnpm pnpm install -g pnpm
pnpm install -g @shipzone/npmci pnpm install -g @ship.zone/npmci
npmci npm prepare npmci npm prepare
- name: Audit production dependencies - name: Audit production dependencies
@ -54,7 +54,7 @@ jobs:
- name: Prepare - name: Prepare
run: | run: |
pnpm install -g pnpm pnpm install -g pnpm
pnpm install -g @shipzone/npmci pnpm install -g @ship.zone/npmci
npmci npm prepare npmci npm prepare
- name: Test stable - name: Test stable
@ -82,7 +82,7 @@ jobs:
- name: Prepare - name: Prepare
run: | run: |
pnpm install -g pnpm pnpm install -g pnpm
pnpm install -g @shipzone/npmci pnpm install -g @ship.zone/npmci
npmci npm prepare npmci npm prepare
- name: Release - name: Release
@ -104,7 +104,7 @@ jobs:
- name: Prepare - name: Prepare
run: | run: |
pnpm install -g pnpm pnpm install -g pnpm
pnpm install -g @shipzone/npmci pnpm install -g @ship.zone/npmci
npmci npm prepare npmci npm prepare
- name: Code quality - name: Code quality

1
.gitignore vendored
View File

@ -3,7 +3,6 @@
# artifacts # artifacts
coverage/ coverage/
public/ public/
pages/
# installs # installs
node_modules/ node_modules/

View File

@ -1,5 +1,44 @@
# Changelog # Changelog
## 2024-12-02 - 1.5.3 - fix(elements)
Update viewer attributes and fix font integration
- Updated viewer.ts to add missing property decorators for letterData and documentSettings.
- Fixed font loading by correcting URLs in index.html.
- Set demoDocumentSettings default header and footer to false.
## 2024-12-02 - 1.5.2 - fix(workflow)
Corrected Docker image references and package scope in YAML workflows for compatibility.
- Updated Docker image reference from GitLab to code.foss.global for npmci UI workflows.
- Fixed npm package scope for `@shipzone/npmci` in YAML workflows.
- Minor formatting corrections for better code readability.
## 2024-12-02 - 1.5.1 - fix(package)
Fix duplicate node export in package.json
- Resolved a duplication issue with the './node' export in package.json exports field.
## 2024-12-02 - 1.5.0 - feat(core)
Refactor project structure for better modularity and code organization
- Moved shared components to a dedicated 'dist_ts_shared' directory for better separation of concerns.
- Updated import statements across the codebase to align with the new file structure.
- Introduced translations directly under 'ts_shared' for language-specific string management.
## 2024-12-02 - 1.4.0 - feat(translation)
Add French and Italian translations for document interface
- Expanded translation support by adding French and Italian language translations
- Fixed duplicated text in German final page statement
- Improved Spanish translation of reverse VAT note and final page statement
## 2024-12-02 - 1.3.2 - fix(core)
Minor updates and optimizations in the output PDF formatting process.
- Improved handling of page content overflow in PDF generation.
- Refined default document settings for consistent rendering.
## 2024-12-02 - 1.3.1 - fix(documentation) ## 2024-12-02 - 1.3.1 - fix(documentation)
Updated project description and enhanced documentation in package.json and README Updated project description and enhanced documentation in package.json and README

View File

@ -1,6 +1,3 @@
<!--gitzone element-->
<!-- made by Task Venture Capital GmbH -->
<!-- checkout https://maintainedby.lossless.com for awesome OpenSource projects -->
<html lang="en"> <html lang="en">
<head> <head>
<!--Lets set some basic meta tags--> <!--Lets set some basic meta tags-->

View File

@ -1,13 +1,16 @@
{ {
"name": "@design.estate/dees-document", "name": "@design.estate/dees-document",
"version": "1.3.1", "version": "1.5.3",
"private": false, "private": false,
"description": "A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.", "description": "A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.",
"main": "dist_ts_web/index.js", "main": "dist_ts_web/index.js",
"typings": "dist_ts_web/index.d.ts", "typings": "dist_ts_web/index.d.ts",
"exports": { "exports": {
"./ts": "./dist_ts/index.js", ".": "./dist_ts/index.js",
"./ts_web": "./dist_ts_web/index.js" "./node": "./dist_ts/index.js",
"./web": "./dist_ts_web/index.js",
"./shared": "./dist_ts_shared/index.js",
"./interfaces": "./dist_ts_shared/interfaces/index.js"
}, },
"scripts": { "scripts": {
"test": "npm run build && tstest test/", "test": "npm run build && tstest test/",
@ -58,12 +61,12 @@
"type": "module", "type": "module",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://gitlab.com/designestate/private/dedocument-catalog.git" "url": "git+https://code.foss.global/designestate/private/dedocument-catalog.git"
}, },
"bugs": { "bugs": {
"url": "https://gitlab.com/designestate/private/dedocument-catalog/issues" "url": "https://code.foss.global/designestate/private/dedocument-catalog/issues"
}, },
"homepage": "https://gitlab.com/designestate/private/dedocument-catalog#readme", "homepage": "https://code.foss.global/designestate/private/dedocument-catalog#readme",
"keywords": [ "keywords": [
"document generation", "document generation",
"invoice automation", "invoice automation",

View File

@ -47,48 +47,48 @@ import { ILetter } from '@design.estate/dees-document';
const invoiceTemplate: ILetter = { const invoiceTemplate: ILetter = {
from: { from: {
name: "Your Company Name", name: 'Your Company Name',
address: { address: {
streetName: "Your Street", streetName: 'Your Street',
houseNumber: "123", houseNumber: '123',
city: "Your City", city: 'Your City',
country: "Your Country", country: 'Your Country',
postalCode: "12345", postalCode: '12345',
}, },
email: "your-email@example.com", email: 'your-email@example.com',
phone: "123-456-7890", phone: '123-456-7890',
}, },
to: { to: {
name: "Recipient Company Name", name: 'Recipient Company Name',
address: { address: {
streetName: "Recipient Street", streetName: 'Recipient Street',
houseNumber: "456", houseNumber: '456',
city: "Recipient City", city: 'Recipient City',
country: "Recipient Country", country: 'Recipient Country',
postalCode: "67890", postalCode: '67890',
}, },
email: "recipient-email@example.com", email: 'recipient-email@example.com',
phone: "098-765-4321", phone: '098-765-4321',
}, },
content: { content: {
invoiceData: { invoiceData: {
items: [ items: [
{ {
name: "Service or Product Name", name: 'Service or Product Name',
unitQuantity: 2, unitQuantity: 2,
unitNetPrice: 100.00, unitNetPrice: 100.0,
unitType: 'service', unitType: 'service',
vatPercentage: 19, vatPercentage: 19,
currency: 'EUR', currency: 'EUR',
}
]
}
}, },
subject: "Invoice for Services Rendered", ],
},
},
subject: 'Invoice for Services Rendered',
date: new Date().getTime(), date: new Date().getTime(),
versionInfo: { versionInfo: {
type: "final", type: 'final',
version: "1.0.0" version: '1.0.0',
}, },
}; };
``` ```
@ -133,22 +133,28 @@ This script encompasses initializing services and generating a PDF in a streamli
`@design.estate/dees-document` provides several advanced functionalities, enabling rich document creation: `@design.estate/dees-document` provides several advanced functionalities, enabling rich document creation:
1. **Custom Templates & Styling** 1. **Custom Templates & Styling**
- Customize the styling through CSS or using inline styles in TypeScript. - Customize the styling through CSS or using inline styles in TypeScript.
- Templates can be adjusted to present different document types (e.g., contracts, reports). - Templates can be adjusted to present different document types (e.g., contracts, reports).
2. **Modular Components and Reuse** 2. **Modular Components and Reuse**
- Utilize modular components to create reusable parts across different documents, enhancing maintainability and reducing redundancy. - Utilize modular components to create reusable parts across different documents, enhancing maintainability and reducing redundancy.
3. **Interactive Documents** 3. **Interactive Documents**
- Integrate interactivities like forms, buttons, and interactive charts within your documents. - Integrate interactivities like forms, buttons, and interactive charts within your documents.
4. **Localization Support** 4. **Localization Support**
- Documents can be localized to support multiple languages, enhancing accessibility and usability. - Documents can be localized to support multiple languages, enhancing accessibility and usability.
5. **Responsive and Adaptive Designs** 5. **Responsive and Adaptive Designs**
- Create documents that adjust layout dynamically depending on print or digital medium, maintaining consistency across platforms. - Create documents that adjust layout dynamically depending on print or digital medium, maintaining consistency across platforms.
6. **Security Features** 6. **Security Features**
- Apply digital signatures and encrypt sensitive documents to ensure secure and authentic document distribution. - Apply digital signatures and encrypt sensitive documents to ensure secure and authentic document distribution.
7. **Complex Business Logic** 7. **Complex Business Logic**

View File

@ -2,8 +2,4 @@ import * as tsclass from '@tsclass/tsclass';
import * as smartfile from '@push.rocks/smartfile'; import * as smartfile from '@push.rocks/smartfile';
import * as path from 'path'; import * as path from 'path';
export { export { tsclass, smartfile, path };
tsclass,
smartfile,
path,
}

View File

@ -1,6 +1,6 @@
import * as plugins from './plugins.js'; import * as plugins from './plugins.js';
import * as paths from './paths.js'; import * as paths from './paths.js';
import * as interfaces from '../ts/interfaces/index.js'; import * as interfaces from '../ts_shared/interfaces/index.js';
import { expect, tap } from '@push.rocks/tapbundle'; import { expect, tap } from '@push.rocks/tapbundle';
import * as deesDocumentServer from '../ts/index.js'; import * as deesDocumentServer from '../ts/index.js';
@ -113,7 +113,7 @@ tap.test('should create an invoice', async () => {
const pdfResult = await testPdfServiceInstance.createPdfFromLetterObject(optionsArg); const pdfResult = await testPdfServiceInstance.createPdfFromLetterObject(optionsArg);
await plugins.smartfile.memory.toFs( await plugins.smartfile.memory.toFs(
Buffer.from(pdfResult.buffer), Buffer.from(pdfResult.buffer),
plugins.path.join(paths.nogitDir, `test-${counter++}.pdf`) plugins.path.join(paths.nogitDir, `test-${counter++}.pdf`),
); );
}; };
await saveResult({ await saveResult({

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@design.estate/dees-document', name: '@design.estate/dees-document',
version: '1.3.1', version: '1.5.3',
description: 'A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.' description: 'A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.'
} }

View File

@ -1,11 +1,7 @@
import * as plugins from './plugins.js'; import * as plugins from './plugins.js';
import * as paths from './paths.js';
import * as helpers from './helpers.js'; import * as helpers from './helpers.js';
import * as interfaces from '../ts/interfaces/index.js';
export interface IPdfServiceConstructorOptions { export interface IPdfServiceConstructorOptions {}
}
/** /**
* a pdf service for generating pdfs * a pdf service for generating pdfs
@ -46,8 +42,8 @@ export class PdfService {
* creates an letter * creates an letter
*/ */
public async createPdfFromLetterObject(optionsArg: { public async createPdfFromLetterObject(optionsArg: {
letterData: plugins.tsclass.business.ILetter, letterData: plugins.tsclass.business.ILetter;
documentSettings: interfaces.IDocumentSettings documentSettings: plugins.shared.interfaces.IDocumentSettings;
}) { }) {
const html = ` const html = `
<script type="module"> <script type="module">

View File

@ -3,4 +3,4 @@ import * as paths from './paths.js';
export const getBundleAsString = async () => { export const getBundleAsString = async () => {
return plugins.smartfile.fs.toStringSync(paths.bundleFile); return plugins.smartfile.fs.toStringSync(paths.bundleFile);
} };

View File

@ -1,6 +1,9 @@
import * as plugins from './plugins.js'; import * as plugins from './plugins.js';
export const packageDir = plugins.path.join(plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url), '../'); export const packageDir = plugins.path.join(
plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
'../',
);
export const nogitDir = plugins.path.join(packageDir, '.nogit/'); export const nogitDir = plugins.path.join(packageDir, '.nogit/');
plugins.smartfile.fs.ensureDirSync(nogitDir); plugins.smartfile.fs.ensureDirSync(nogitDir);

View File

@ -1,9 +1,12 @@
// node native // node native
import * as path from 'path'; import * as path from 'path';
export { export { path };
path
} // dees-document scope
import * as shared from '../dist_ts_shared/index.js';
export { shared };
// @push.rocks/scope // @push.rocks/scope
import * as smartfile from '@push.rocks/smartfile'; import * as smartfile from '@push.rocks/smartfile';
@ -11,16 +14,9 @@ import * as smartjson from '@push.rocks/smartjson';
import * as smartpath from '@push.rocks/smartpath'; import * as smartpath from '@push.rocks/smartpath';
import * as smartpdf from '@push.rocks/smartpdf'; import * as smartpdf from '@push.rocks/smartpdf';
export { export { smartfile, smartpath, smartjson, smartpdf };
smartfile,
smartpath,
smartjson,
smartpdf,
}
// @tsclass scope // @tsclass scope
import * as tsclass from '@tsclass/tsclass'; import * as tsclass from '@tsclass/tsclass';
export { export { tsclass };
tsclass,
}

3
ts/tspublish.json Normal file
View File

@ -0,0 +1,3 @@
{
"order": 2
}

View File

@ -1,7 +1,7 @@
import * as tsclass from '@tsclass/tsclass'; import * as plugins from './plugins.js';
import * as interfaces from '../interfaces/index.js'; import * as interfaces from './interfaces/index.js';
const fromContact: tsclass.business.IContact = { const fromContact: plugins.tsclass.business.IContact = {
name: 'Awesome From Company', name: 'Awesome From Company',
type: 'company', type: 'company',
description: 'a company that does stuff', description: 'a company that does stuff',
@ -23,7 +23,7 @@ const fromContact: tsclass.business.IContact = {
}; };
const toContact: tsclass.business.IContact = { const toContact: plugins.tsclass.business.IContact = {
name: 'Awesome To GmbH', name: 'Awesome To GmbH',
type: 'company', type: 'company',
customerNumber: 'LL-CLIENT-123', customerNumber: 'LL-CLIENT-123',
@ -38,7 +38,7 @@ const toContact: tsclass.business.IContact = {
vatId: 'BE12345678', vatId: 'BE12345678',
} }
export const demoLetter: tsclass.business.ILetter = { export const demoLetter: plugins.tsclass.business.ILetter = {
versionInfo: { versionInfo: {
type: 'draft', type: 'draft',
version: '1.0.0', version: '1.0.0',
@ -213,7 +213,7 @@ export const demoLetter: tsclass.business.ILetter = {
export const demoDocumentSettings: interfaces.IDocumentSettings = { export const demoDocumentSettings: interfaces.IDocumentSettings = {
enableTopDraftText: true, enableTopDraftText: true,
enableDefaultHeader: true, enableDefaultHeader: false,
enableDefaultFooter: true, enableDefaultFooter: false,
languageCode: 'DE', languageCode: 'DE',
}; };

View File

@ -3,6 +3,9 @@ export const a4Width = 794;
export const rightMargin = 70; export const rightMargin = 70;
export const leftMargin = 90; export const leftMargin = 90;
import * as interfaces from './interfaces/index.js';
export { interfaces };
import * as translation from './translation.js'; import * as translation from './translation.js';
export { translation }; export { translation };

View File

@ -1,8 +1,8 @@
import * as shared from '../shared/index.js'; import * as translation from '../translation.js';
export interface IDocumentSettings { export interface IDocumentSettings {
enableTopDraftText?: boolean; enableTopDraftText?: boolean;
enableDefaultHeader?: boolean; enableDefaultHeader?: boolean;
enableDefaultFooter?: boolean; enableDefaultFooter?: boolean;
languageCode?: shared.translation.TLanguageCode; languageCode?: translation.TLanguageCode;
} }

4
ts_shared/plugins.ts Normal file
View File

@ -0,0 +1,4 @@
// tsclass scope
import * as tsclass from '@tsclass/tsclass';
export { tsclass };

View File

@ -1,4 +1,4 @@
import * as interfaces from '../interfaces/index.js'; import * as interfaces from './interfaces/index.js';
type TTranslationImplementation = { type TTranslationImplementation = {
[key in keyof interfaces.IDeDocumentTranslations]: string; [key in keyof interfaces.IDeDocumentTranslations]: string;
@ -40,7 +40,7 @@ export const DE_translations: TTranslationImplementation = {
yourCustomerId: 'Ihre Kundennummer:', yourCustomerId: 'Ihre Kundennummer:',
yourVatId: 'Ihre Umsatzsteuer-ID:', yourVatId: 'Ihre Umsatzsteuer-ID:',
continuesOnPage: 'Fortsetzung auf Seite', continuesOnPage: 'Fortsetzung auf Seite',
finalPageStatement: 'Diese ist die letzte Seite einer Dokumente.', finalPageStatement: 'Dies ist die letzte Seite dieses Dokuments.',
page: 'Seite', page: 'Seite',
}; };
@ -53,21 +53,63 @@ export const ES_translations: TTranslationImplementation = {
itemPos: 'Pos.', itemPos: 'Pos.',
quantity: 'Cantidad', quantity: 'Cantidad',
registrationInfo: 'Información de registro', 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.', reverseVatNote: 'El IVA se aplica por inversión del sujeto pasivo y debe ser pagado por el cliente.',
totalNetPrice: 'Precio total neto', totalNetPrice: 'Precio total neto',
unitNetPrice: 'Precio unitario neto', unitNetPrice: 'Precio unitario neto',
unitType: 'Tipo de unidad', unitType: 'Tipo de unidad',
yourCustomerId: 'Su número de cliente:', yourCustomerId: 'Su número de cliente:',
yourVatId: 'Su ID de IVA:', yourVatId: 'Su ID de IVA:',
continuesOnPage: 'Continues on page', continuesOnPage: 'Continúa en la página',
finalPageStatement: 'This is the final page of this document.', finalPageStatement: 'Esta es la última página de este documento.',
page: 'Página',
};
export const FR_translations: TTranslationImplementation = {
address: 'Adresse',
bankConnection: 'Coordonnées bancaires',
contactInfo: 'Informations de contact',
description: 'Description',
invoice: 'Facture',
itemPos: 'Position',
quantity: 'Quantité',
registrationInfo: 'Informations d\'enregistrement',
reverseVatNote: 'La TVA s\'applique selon le mécanisme d\'autoliquidation et est à payer par le client.',
totalNetPrice: 'Prix net total',
unitNetPrice: 'Prix unitaire net',
unitType: 'Type d\'unité',
yourCustomerId: 'Votre numéro de client :',
yourVatId: 'Votre numéro de TVA :',
continuesOnPage: 'Continue sur la page',
finalPageStatement: 'Ceci est la dernière page de ce document.',
page: 'Page', page: 'Page',
}; };
export const IT_translations: TTranslationImplementation = {
address: 'Indirizzo',
bankConnection: 'Coordinate bancarie',
contactInfo: 'Informazioni di contatto',
description: 'Descrizione',
invoice: 'Fattura',
itemPos: 'Pos.',
quantity: 'Quantità',
registrationInfo: 'Informazioni di registrazione',
reverseVatNote: 'L\'IVA è applicata con inversione contabile ed è a carico del cliente.',
totalNetPrice: 'Prezzo netto totale',
unitNetPrice: 'Prezzo netto unitario',
unitType: 'Tipo di unità',
yourCustomerId: 'Il tuo numero cliente:',
yourVatId: 'Il tuo numero di partita IVA:',
continuesOnPage: 'Continua alla pagina',
finalPageStatement: 'Questa è l\'ultima pagina di questo documento.',
page: 'Pagina',
};
export const languageCodeMap = { export const languageCodeMap = {
'DE': DE_translations, 'DE': DE_translations,
'EN': EN_translations, 'EN': EN_translations,
'ES': ES_translations, 'ES': ES_translations,
'FR': FR_translations,
'IT': IT_translations,
}; };
export type TLanguageCode = keyof typeof languageCodeMap; export type TLanguageCode = keyof typeof languageCodeMap;

3
ts_shared/tspublish.json Normal file
View File

@ -0,0 +1,3 @@
{
"order": 1
}

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@design.estate/dees-document', name: '@design.estate/dees-document',
version: '1.3.1', version: '1.5.3',
description: 'A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.' description: 'A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.'
} }

View File

@ -15,8 +15,6 @@ import {
domtools, domtools,
} 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 interfaces from '../../ts/interfaces/index.js';
declare global { declare global {
@ -49,7 +47,7 @@ export class DeContentInvoice extends DeesElement {
type: Object, type: Object,
reflect: true, reflect: true,
}) })
public documentSettings: interfaces.IDocumentSettings; public documentSettings: plugins.shared.interfaces.IDocumentSettings;
constructor() { constructor() {
super(); super();
@ -281,12 +279,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">${shared.translation.translate(this.documentSettings.languageCode, 'itemPos', 'Item Pos.')}</div> <div class="lineItem">${plugins.shared.translation.translate(this.documentSettings.languageCode, 'itemPos', 'Item Pos.')}</div>
<div class="lineItem">${shared.translation.translate(this.documentSettings.languageCode, 'description', 'Description')}</div> <div class="lineItem">${plugins.shared.translation.translate(this.documentSettings.languageCode, 'description', 'Description')}</div>
<div class="lineItem">${shared.translation.translate(this.documentSettings.languageCode, 'quantity', 'Quantity')}</div> <div class="lineItem">${plugins.shared.translation.translate(this.documentSettings.languageCode, 'quantity', 'Quantity')}</div>
<div class="lineItem">${shared.translation.translate(this.documentSettings.languageCode, 'unitType', 'Unit Type')}</div> <div class="lineItem">${plugins.shared.translation.translate(this.documentSettings.languageCode, 'unitType', 'Unit Type')}</div>
<div class="lineItem">${shared.translation.translate(this.documentSettings.languageCode, 'unitNetPrice', 'Unit Net Price')}</div> <div class="lineItem">${plugins.shared.translation.translate(this.documentSettings.languageCode, 'unitNetPrice', 'Unit Net Price')}</div>
<div class="lineItem">${shared.translation.translate(this.documentSettings.languageCode, 'totalNetPrice', 'Total Net Price')}</div> <div class="lineItem">${plugins.shared.translation.translate(this.documentSettings.languageCode, 'totalNetPrice', 'Total Net Price')}</div>
</div> </div>
${(() => { ${(() => {
let counter = 1; let counter = 1;
@ -335,7 +333,7 @@ export class DeContentInvoice extends DeesElement {
${this.letterData?.content.invoiceData.reverseCharge ${this.letterData?.content.invoiceData.reverseCharge
? html` ? html`
<div class="taxNote"> <div class="taxNote">
${shared.translation.translate(this.documentSettings.languageCode, 'reverseVatNote', 'VAT arises on a reverse charge basis and is payable by the customer.')} ${plugins.shared.translation.translate(this.documentSettings.languageCode, 'reverseVatNote', 'VAT arises on a reverse charge basis and is payable by the customer.')}
</div> </div>
` `
: ``} : ``}

View File

@ -1,6 +1,7 @@
import * as shared from '../../ts/shared/index.js'; import * as plugins from '../plugins.js';
import { html } from '@design.estate/dees-element'; import { html } from '@design.estate/dees-element';
export const demoFunc = () => html` export const demoFunc = () => html`
<dedocument-dedocument .format="${'a4'}" .letterData=${shared.demoLetter}></dedocument-dedocument> <dedocument-dedocument .format="${'a4'}" .letterData=${plugins.shared.demoLetter}></dedocument-dedocument>
`; `;

View File

@ -10,11 +10,9 @@ import {
unsafeCSS, unsafeCSS,
domtools, domtools,
} from '@design.estate/dees-element'; } from '@design.estate/dees-element';
import * as interfaces from '../../ts/interfaces/index.js';
import * as plugins from '../plugins.js'; import * as plugins from '../plugins.js';
export const defaultDocumentSettings: interfaces.IDocumentSettings = { export const defaultDocumentSettings: plugins.shared.interfaces.IDocumentSettings = {
enableTopDraftText: true, enableTopDraftText: true,
enableDefaultHeader: true, enableDefaultHeader: true,
enableDefaultFooter: true, enableDefaultFooter: true,
@ -24,7 +22,6 @@ export const defaultDocumentSettings: interfaces.IDocumentSettings = {
import { DePage } from './page.js'; import { DePage } from './page.js';
import { DeContentInvoice } from './contentinvoice.js'; import { DeContentInvoice } from './contentinvoice.js';
import * as shared from '../../ts/shared/index.js';
import { demoFunc } from './document.demo.js'; import { demoFunc } from './document.demo.js';
declare global { declare global {
@ -85,7 +82,7 @@ export class DeDocument extends DeesElement {
} }
}, },
}) })
public documentSettings: interfaces.IDocumentSettings = defaultDocumentSettings; public documentSettings: plugins.shared.interfaces.IDocumentSettings = defaultDocumentSettings;
constructor() { constructor() {
super(); super();

View File

@ -7,5 +7,3 @@ export * from './pagecontent.js';
export * from './pagefooter.js'; export * from './pagefooter.js';
export * from './pageheader.js'; export * from './pageheader.js';
export * from './viewer.js'; export * from './viewer.js';
export * from '../../ts/shared/index.js';

View File

@ -7,11 +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 shared from '../../ts/shared/index.js'; import * as plugins from '../plugins.js';
import * as tsclass from '@tsclass/tsclass';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -22,14 +21,14 @@ declare global {
@customElement('dedocument-letterheader') @customElement('dedocument-letterheader')
export class DeLetterHeader extends DeesElement { export class DeLetterHeader extends DeesElement {
public static demo = () => html` public static demo = () => html`
<dedocument-letterheader .format="${'a4'}" .letterData=${shared.demoLetter}></dedocument-letterheader> <dedocument-letterheader .format="${'a4'}" .letterData=${plugins.shared.demoLetter}></dedocument-letterheader>
`; `;
@property({ @property({
type: Object, type: Object,
reflect: true reflect: true
}) })
public letterData: tsclass.business.ILetter; public letterData: plugins.tsclass.business.ILetter;
@property({ @property({
type: Number, type: Number,
@ -60,7 +59,7 @@ export class DeLetterHeader extends DeesElement {
display: block; display: block;
overflow: hidden; overflow: hidden;
top: 200px; top: 200px;
right: ${unsafeCSS(shared.rightMargin + 'px')}; right: ${unsafeCSS(plugins.shared.rightMargin + 'px')};
width: 200px; width: 200px;
text-align: right; text-align: right;
} }
@ -74,14 +73,14 @@ export class DeLetterHeader extends DeesElement {
.date { .date {
position: absolute; position: absolute;
top: 180px; top: 180px;
right: ${unsafeCSS(shared.rightMargin + 'px')}; right: ${unsafeCSS(plugins.shared.rightMargin + 'px')};
text-align: right; text-align: right;
} }
.address { .address {
position: absolute; position: absolute;
top: 180px; top: 180px;
left: ${unsafeCSS(shared.leftMargin + 'px')}; left: ${unsafeCSS(plugins.shared.leftMargin + 'px')};
} }
.address .from { .address .from {

View File

@ -11,12 +11,10 @@ import {
domtools, domtools,
} from '@design.estate/dees-element'; } from '@design.estate/dees-element';
import * as interfaces from '../../ts/interfaces/index.js'; import * as plugins from '../plugins.js';
import { defaultDocumentSettings } from './document.js'; import { defaultDocumentSettings } from './document.js';
import * as shared from '../../ts/shared/index.js';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
'dedocument-page': DePage; 'dedocument-page': DePage;
@ -67,7 +65,7 @@ export class DePage extends DeesElement {
type: Object, type: Object,
reflect: true, reflect: true,
}) })
public documentSettings: interfaces.IDocumentSettings = defaultDocumentSettings; public documentSettings: plugins.shared.interfaces.IDocumentSettings = defaultDocumentSettings;
constructor() { constructor() {
super(); super();
@ -204,9 +202,9 @@ export class DePage extends DeesElement {
let scale = 1; let scale = 1;
if (this.viewHeight) { if (this.viewHeight) {
scale = this.viewHeight / shared.a4Height; scale = this.viewHeight / plugins.shared.a4Height;
} else if (this.viewWidth) { } else if (this.viewWidth) {
scale = this.viewWidth / shared.a4Width; scale = this.viewWidth / plugins.shared.a4Width;
} }
console.log(`new scale is ${scale}`); console.log(`new scale is ${scale}`);
scaleWrapper.style.transform = `scale(${scale})`; scaleWrapper.style.transform = `scale(${scale})`;
@ -214,6 +212,6 @@ export class DePage extends DeesElement {
// Adjust the outer dimensions so they match the scaled content // Adjust the outer dimensions so they match the scaled content
// this.style.width = `${shared.a4Width * scale}px`; // this.style.width = `${shared.a4Width * scale}px`;
this.style.height = `${shared.a4Height * scale}px`; this.style.height = `${plugins.shared.a4Height * scale}px`;
} }
} }

View File

@ -10,7 +10,7 @@ import {
} from '@design.estate/dees-element'; } from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools'; import * as domtools from '@design.estate/dees-domtools';
import * as shared from '../../ts/shared/index.js'; import * as plugins from '../plugins.js';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -47,8 +47,8 @@ export class DePageContainer extends DeesElement {
background: white; background: white;
color: #333; color: #333;
padding: 0px; padding: 0px;
width: ${unsafeCSS(shared.a4Width + 'px')}; width: ${unsafeCSS(plugins.shared.a4Width + 'px')};
height: ${unsafeCSS(shared.a4Height + 'px')}; height: ${unsafeCSS(plugins.shared.a4Height + 'px')};
position: relative; position: relative;
border-radius: 3px; border-radius: 3px;
overflow: hidden; overflow: hidden;

View File

@ -7,11 +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 shared from '../../ts/shared/index.js'; import * as plugins from '../plugins.js';
import * as tsclass from '@tsclass/tsclass';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -28,7 +27,7 @@ export class DePageContent extends DeesElement {
@property({ @property({
type: Number, type: Number,
}) })
public letterData: tsclass.business.ILetter; public letterData: plugins.tsclass.business.ILetter;
@property({ @property({
type: Number, type: Number,
@ -55,8 +54,8 @@ export class DePageContent extends DeesElement {
.content { .content {
position: absolute; position: absolute;
left: ${unsafeCSS(shared.leftMargin + 'px')}; left: ${unsafeCSS(plugins.shared.leftMargin + 'px')};
right: ${unsafeCSS(shared.rightMargin + 'px')}; right: ${unsafeCSS(plugins.shared.rightMargin + 'px')};
bottom: 170px; bottom: 170px;
overflow: visible; overflow: visible;
} }

View File

@ -10,10 +10,7 @@ import {
domtools, domtools,
} from '@design.estate/dees-element'; } from '@design.estate/dees-element';
import * as interfaces from '../../ts/interfaces/index.js'; import * as plugins from '../plugins.js';
import * as shared from '../../ts/shared/index.js';
import * as tsclass from '@tsclass/tsclass';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -30,13 +27,13 @@ export class DePageFooter extends DeesElement {
@property({ @property({
type: Object, type: Object,
}) })
letterData: tsclass.business.ILetter; letterData: plugins.tsclass.business.ILetter;
@property({ @property({
type: Object, type: Object,
reflect: true, reflect: true,
}) })
documentSettings: interfaces.IDocumentSettings; documentSettings: plugins.shared.interfaces.IDocumentSettings;
@property({ @property({
type: Number type: Number
@ -69,7 +66,7 @@ export class DePageFooter extends DeesElement {
right: 0px; right: 0px;
height: 130px; height: 130px;
content: ''; content: '';
padding: 30px ${unsafeCSS(shared.rightMargin + 'px')} 10px ${unsafeCSS(shared.leftMargin + 'px')}; padding: 30px ${unsafeCSS(plugins.shared.rightMargin + 'px')} 10px ${unsafeCSS(plugins.shared.leftMargin + 'px')};
grid-template-columns: calc(100% / 4) calc(100% / 4) calc(100% / 4) calc(100% / 4); grid-template-columns: calc(100% / 4) calc(100% / 4) calc(100% / 4) calc(100% / 4);
grid-gap: 5px; grid-gap: 5px;
border-top: 2px solid #e4002b; border-top: 2px solid #e4002b;
@ -78,7 +75,7 @@ export class DePageFooter extends DeesElement {
.bottomstripe .pageNumber { .bottomstripe .pageNumber {
position: absolute; position: absolute;
top: 0px; top: 0px;
right: ${unsafeCSS(shared.rightMargin + 'px')}; right: ${unsafeCSS(plugins.shared.rightMargin + 'px')};
background: #e4002b; background: #e4002b;
padding: 3px; padding: 3px;
font-size: 9px; font-size: 9px;
@ -89,7 +86,7 @@ export class DePageFooter extends DeesElement {
.bottomstripe .documentTitle { .bottomstripe .documentTitle {
position: absolute; position: absolute;
top: -18px; top: -18px;
right: ${unsafeCSS(shared.rightMargin + 'px')}; right: ${unsafeCSS(plugins.shared.rightMargin + 'px')};
background: #dddddd; background: #dddddd;
padding: 3px; padding: 3px;
font-size: 9px; font-size: 9px;
@ -104,26 +101,26 @@ export class DePageFooter extends DeesElement {
return html` return html`
<div class="bottomstripe"> <div class="bottomstripe">
<div> <div>
<strong>${shared.translation.translate(this.documentSettings.languageCode, 'address', 'Address')}:</strong><br /> <strong>${plugins.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>${shared.translation.translate(this.documentSettings.languageCode, 'registrationInfo', 'Registration Info')}:</strong><br /> <strong>${plugins.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>${shared.translation.translate(this.documentSettings.languageCode, 'contactInfo', 'Contact Info')}:</strong><br /> <strong>${plugins.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>${shared.translation.translate(this.documentSettings.languageCode, 'bankConnection', 'Bank Connection')}:</strong><br /> <strong>${plugins.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 />

View File

@ -10,10 +10,7 @@ import {
domtools domtools
} from '@design.estate/dees-element'; } from '@design.estate/dees-element';
import * as interfaces from '../../ts/interfaces/index.js'; import * as plugins from '../plugins.js';
import * as shared from '../../ts/shared/index.js';
import * as tsclass from '@tsclass/tsclass';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -30,13 +27,13 @@ export class DePageHeader extends DeesElement {
@property({ @property({
type: Object, type: Object,
}) })
public letterData: tsclass.business.ILetter = null; public letterData: plugins.tsclass.business.ILetter = null;
@property({ @property({
type: Object, type: Object,
reflect: true, reflect: true,
}) })
documentSettings: interfaces.IDocumentSettings; documentSettings: plugins.shared.interfaces.IDocumentSettings;
@property({ @property({
type: Number, type: Number,
@ -76,7 +73,7 @@ export class DePageHeader extends DeesElement {
overflow: hidden; overflow: hidden;
top: 130px; top: 130px;
left: auto; left: auto;
right: ${unsafeCSS(shared.rightMargin + 'px')}; right: ${unsafeCSS(plugins.shared.rightMargin + 'px')};
height: 20px; height: 20px;
line-height: 20px; line-height: 20px;
color: #333; color: #333;
@ -87,7 +84,7 @@ export class DePageHeader extends DeesElement {
bottom: 10px; bottom: 10px;
height: 25px; height: 25px;
left: auto; left: auto;
right: ${unsafeCSS(shared.rightMargin + 'px')}; right: ${unsafeCSS(plugins.shared.rightMargin + 'px')};
font-family: 'Courier New', Courier, monospace; font-family: 'Courier New', Courier, monospace;
} }
.topstripe .logo img { .topstripe .logo img {

View File

@ -1,6 +1,6 @@
import { html } from '@design.estate/dees-element'; import { html } from '@design.estate/dees-element';
import * as shared from '../../ts/shared/index.js'; import * as plugins from '../plugins.js';
export const demoFunc = () => html` export const demoFunc = () => html`
<dedocument-viewer .letterData=${shared.demoLetter} .documentSettings=${shared.demoDocumentSettings}></dedocument-viewer> <dedocument-viewer .letterData=${plugins.shared.demoLetter} .documentSettings=${plugins.shared.demoDocumentSettings}></dedocument-viewer>
`; `;

View File

@ -1,7 +1,6 @@
import * as plugins from '../plugins.js'; import * as plugins from '../plugins.js';
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, property } from '@design.estate/dees-element';
import { demoFunc } from './viewer.demo.js'; import { demoFunc } from './viewer.demo.js';
declare global { declare global {
@ -16,9 +15,17 @@ export class DeDocumentViewer extends DeesElement {
public static demo = demoFunc; public static demo = demoFunc;
// INSTANCE // INSTANCE
@property({
type: Object,
reflect: true,
})
public letterData: plugins.tsclass.business.ILetter = null; public letterData: plugins.tsclass.business.ILetter = null;
public documentSettings: interfaces.IDocumentSettings; @property({
type: Object,
reflect: true,
})
public documentSettings: plugins.shared.interfaces.IDocumentSettings;
public static styles = [ public static styles = [
cssManager.defaultStyles, cssManager.defaultStyles,

2
ts_web/pages/index.ts Normal file
View File

@ -0,0 +1,2 @@
export * from './page1.js';
export * from './page2.js';

17
ts_web/pages/page1.ts Normal file
View File

@ -0,0 +1,17 @@
import * as plugins from '../plugins.js';
import { html } from '@design.estate/dees-element';
export const page1 = () => html`
<style>
dedocument-dedocument {
margin: 16px;
}
</style>
<dedocument-dedocument .printMode=${false} letterData=${plugins.smartjson.stringifyBase64({
...plugins.shared.demoLetter,
from: {
...plugins.shared.demoLetter.from,
description: 'a string set via stringified JSON'
}
} as plugins.tsclass.business.ILetter)}> </dedocument-dedocument>
`;

18
ts_web/pages/page2.ts Normal file
View File

@ -0,0 +1,18 @@
import { html } from "@design.estate/dees-element";
export const page2 = () => html`
<style>
.demoPort {
margin: auto;
width: 400px;
}
dedocument-page {
margin-top: 16px;
margin-bottom: 16px;
}
</style>
<div class="demoPort">
<dedocument-page .format="${"a4"}" .viewWidth=${400}></dedocument-page>
<dedocument-page .format="${"a4"}" .viewWidth=${400}></dedocument-page>
</div>
`;

View File

@ -1,3 +1,8 @@
// dees-document scope
import * as shared from '../dist_ts_shared/index.js';
export { shared };
// tsclass scope // tsclass scope
import * as tsclass from '@tsclass/tsclass'; import * as tsclass from '@tsclass/tsclass';

3
ts_web/tspublish.json Normal file
View File

@ -0,0 +1,3 @@
{
"order": 3
}

View File

@ -6,7 +6,13 @@
"module": "NodeNext", "module": "NodeNext",
"moduleResolution": "NodeNext", "moduleResolution": "NodeNext",
"esModuleInterop": true, "esModuleInterop": true,
"verbatimModuleSyntax": true "verbatimModuleSyntax": true,
"baseUrl": ".",
"paths": {
"undefined": [
"./ts_web/index.js"
]
}
}, },
"exclude": [ "exclude": [
"dist_*/**/*.d.ts" "dist_*/**/*.d.ts"