mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-23 16:19:49 +00:00
Merge branch 'develop' into add-mail-invoice-receipt-schema
This commit is contained in:
@@ -4,10 +4,10 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "lerna run dev",
|
"dev": "lerna run dev",
|
||||||
"build": "lerna run build",
|
"build": "lerna run build",
|
||||||
"dev:webapp": "lerna run dev --scope \"@bigcapital/webapp\" --scope \"@bigcapital/utils\"",
|
"dev:webapp": "lerna run dev --scope \"@bigcapital/webapp\" --scope \"@bigcapital/utils\" --scope \"@bigcapital/pdf-templates\"",
|
||||||
"build:webapp": "lerna run build --scope \"@bigcapital/webapp\" --scope \"@bigcapital/utils\"",
|
"build:webapp": "lerna run build --scope \"@bigcapital/webapp\" --scope \"@bigcapital/utils\" --scope \"@bigcapital/pdf-templates\"",
|
||||||
"dev:server": "lerna run dev --scope \"@bigcapital/server\" --scope \"@bigcapital/utils\"",
|
"dev:server": "lerna run dev --scope \"@bigcapital/server\" --scope \"@bigcapital/utils\" --scope \"@bigcapital/pdf-templates\" --scope \"@bigcapital/email-components\"",
|
||||||
"build:server": "lerna run build --scope \"@bigcapital/server\" --scope \"@bigcapital/utils\"",
|
"build:server": "lerna run build --scope \"@bigcapital/server\" --scope \"@bigcapital/utils\" --scope \"@bigcapital/pdf-templates\" --scope \"@bigcapital/email-components\"",
|
||||||
"serve:server": "lerna run serve --scope \"@bigcapital/server\" --scope \"@bigcapital/utils\"",
|
"serve:server": "lerna run serve --scope \"@bigcapital/server\" --scope \"@bigcapital/utils\"",
|
||||||
"test:e2e": "playwright test",
|
"test:e2e": "playwright test",
|
||||||
"prepare": "husky install"
|
"prepare": "husky install"
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ export interface CommonMailOptions {
|
|||||||
cc?: Array<string>;
|
cc?: Array<string>;
|
||||||
bcc?: Array<string>;
|
bcc?: Array<string>;
|
||||||
formatArgs?: Record<string, any>;
|
formatArgs?: Record<string, any>;
|
||||||
|
toOptions: Array<AddressItem>;
|
||||||
|
fromOptions: Array<AddressItem>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CommonMailOptionsDTO extends Partial<CommonMailOptions> {
|
export interface CommonMailOptionsDTO extends Partial<CommonMailOptions> {}
|
||||||
}
|
|
||||||
|
|||||||
@@ -338,21 +338,22 @@ export interface InvoicePdfTemplateAttributes {
|
|||||||
subtotalLabel: string;
|
subtotalLabel: string;
|
||||||
discountLabel: string;
|
discountLabel: string;
|
||||||
paymentMadeLabel: string;
|
paymentMadeLabel: string;
|
||||||
balanceDueLabel: string;
|
|
||||||
|
|
||||||
showTotal: boolean;
|
showTotal: boolean;
|
||||||
showSubtotal: boolean;
|
showSubtotal: boolean;
|
||||||
showDiscount: boolean;
|
showDiscount: boolean;
|
||||||
showTaxes: boolean;
|
showTaxes: boolean;
|
||||||
showPaymentMade: boolean;
|
showPaymentMade: boolean;
|
||||||
showDueAmount: boolean;
|
|
||||||
showBalanceDue: boolean;
|
|
||||||
|
|
||||||
total: string;
|
total: string;
|
||||||
subtotal: string;
|
subtotal: string;
|
||||||
discount: string;
|
discount: string;
|
||||||
paymentMade: string;
|
paymentMade: string;
|
||||||
balanceDue: string;
|
|
||||||
|
// Due Amount
|
||||||
|
dueAmount: string;
|
||||||
|
showDueAmount: boolean;
|
||||||
|
dueAmountLabel: string;
|
||||||
|
|
||||||
termsConditionsLabel: string;
|
termsConditionsLabel: string;
|
||||||
showTermsConditions: boolean;
|
showTermsConditions: boolean;
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export class PdfTemplate extends TenantModel {
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
get companyLogoUri() {
|
get companyLogoUri() {
|
||||||
return this.attributes.companyLogoKey
|
return this.attributes?.companyLogoKey
|
||||||
? getUploadedObjectUri(this.attributes.companyLogoKey)
|
? getUploadedObjectUri(this.attributes.companyLogoKey)
|
||||||
: '';
|
: '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,22 +23,24 @@ export class ContactMailNotification {
|
|||||||
public async getDefaultMailOptions(
|
public async getDefaultMailOptions(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
customerId: number
|
customerId: number
|
||||||
): Promise<Pick<CommonMailOptions, 'to' | 'from'>> {
|
): Promise<
|
||||||
|
Pick<CommonMailOptions, 'to' | 'from' | 'toOptions' | 'fromOptions'>
|
||||||
|
> {
|
||||||
const { Customer } = this.tenancy.models(tenantId);
|
const { Customer } = this.tenancy.models(tenantId);
|
||||||
const customer = await Customer.query()
|
const customer = await Customer.query()
|
||||||
.findById(customerId)
|
.findById(customerId)
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
const toAddresses = customer.contactAddresses;
|
const toOptions = customer.contactAddresses;
|
||||||
const fromAddresses = await this.mailTenancy.senders(tenantId);
|
const fromOptions = await this.mailTenancy.senders(tenantId);
|
||||||
|
|
||||||
const toAddress = toAddresses.find((a) => a.primary);
|
const toAddress = toOptions.find((a) => a.primary);
|
||||||
const fromAddress = fromAddresses.find((a) => a.primary);
|
const fromAddress = fromOptions.find((a) => a.primary);
|
||||||
|
|
||||||
const to = toAddress?.mail ? castArray(toAddress?.mail) : [];
|
const to = toAddress?.mail ? castArray(toAddress?.mail) : [];
|
||||||
const from = fromAddress?.mail ? castArray(fromAddress?.mail) : [];
|
const from = fromAddress?.mail ? castArray(fromAddress?.mail) : [];
|
||||||
|
|
||||||
return { to, from };
|
return { to, from, toOptions, fromOptions };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,9 +19,6 @@ export class SaleInvoicePdf {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private chromiumlyTenancy: ChromiumlyTenancy;
|
private chromiumlyTenancy: ChromiumlyTenancy;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
private templateInjectable: TemplateInjectable;
|
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
private getInvoiceService: GetSaleInvoice;
|
private getInvoiceService: GetSaleInvoice;
|
||||||
|
|
||||||
|
|||||||
@@ -129,8 +129,8 @@ export class SendSaleInvoiceMailCommon {
|
|||||||
...commonArgs,
|
...commonArgs,
|
||||||
'Customer Name': invoice.customer.displayName,
|
'Customer Name': invoice.customer.displayName,
|
||||||
'Invoice Number': invoice.invoiceNo,
|
'Invoice Number': invoice.invoiceNo,
|
||||||
'Invoice DueAmount': invoice.dueAmountFormatted,
|
'Invoice Due Amount': invoice.dueAmountFormatted,
|
||||||
'Invoice DueDate': invoice.dueDateFormatted,
|
'Invoice Due Date': invoice.dueDateFormatted,
|
||||||
'Invoice Date': invoice.invoiceDateFormatted,
|
'Invoice Date': invoice.invoiceDateFormatted,
|
||||||
'Invoice Amount': invoice.totalFormatted,
|
'Invoice Amount': invoice.totalFormatted,
|
||||||
'Overdue Days': invoice.overdueDays,
|
'Overdue Days': invoice.overdueDays,
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import Mail from '@/lib/Mail';
|
import Mail from '@/lib/Mail';
|
||||||
import { ISaleInvoiceMailSend, SendInvoiceMailDTO } from '@/interfaces';
|
import {
|
||||||
|
ISaleInvoiceMailSend,
|
||||||
|
SaleInvoiceMailOptions,
|
||||||
|
SendInvoiceMailDTO,
|
||||||
|
} from '@/interfaces';
|
||||||
import { SaleInvoicePdf } from './SaleInvoicePdf';
|
import { SaleInvoicePdf } from './SaleInvoicePdf';
|
||||||
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
|
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
|
||||||
import { mergeAndValidateMailOptions } from '@/services/MailNotification/utils';
|
import { mergeAndValidateMailOptions } from '@/services/MailNotification/utils';
|
||||||
@@ -47,6 +51,34 @@ export class SendSaleInvoiceMail {
|
|||||||
} as ISaleInvoiceMailSend);
|
} as ISaleInvoiceMailSend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the formatted mail options.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} saleInvoiceId
|
||||||
|
* @param {SendInvoiceMailDTO} messageOptions
|
||||||
|
* @returns {Promise<SaleInvoiceMailOptions>}
|
||||||
|
*/
|
||||||
|
async getFormattedMailOptions(
|
||||||
|
tenantId: number,
|
||||||
|
saleInvoiceId: number,
|
||||||
|
messageOptions: SendInvoiceMailDTO
|
||||||
|
): Promise<SaleInvoiceMailOptions> {
|
||||||
|
const defaultMessageOptions = await this.invoiceMail.getInvoiceMailOptions(
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceId
|
||||||
|
);
|
||||||
|
// Merges message options with default options and parses the options values.
|
||||||
|
const parsedMessageOptions = mergeAndValidateMailOptions(
|
||||||
|
defaultMessageOptions,
|
||||||
|
messageOptions
|
||||||
|
);
|
||||||
|
return this.invoiceMail.formatInvoiceMailOptions(
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceId,
|
||||||
|
parsedMessageOptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers the mail invoice.
|
* Triggers the mail invoice.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -59,20 +91,10 @@ export class SendSaleInvoiceMail {
|
|||||||
saleInvoiceId: number,
|
saleInvoiceId: number,
|
||||||
messageOptions: SendInvoiceMailDTO
|
messageOptions: SendInvoiceMailDTO
|
||||||
) {
|
) {
|
||||||
const defaultMessageOptions = await this.invoiceMail.getInvoiceMailOptions(
|
const formattedMessageOptions = await this.getFormattedMailOptions(
|
||||||
tenantId,
|
|
||||||
saleInvoiceId
|
|
||||||
);
|
|
||||||
// Merges message options with default options and parses the options values.
|
|
||||||
const parsedMessageOptions = mergeAndValidateMailOptions(
|
|
||||||
defaultMessageOptions,
|
|
||||||
messageOptions
|
|
||||||
);
|
|
||||||
const formattedMessageOptions =
|
|
||||||
await this.invoiceMail.formatInvoiceMailOptions(
|
|
||||||
tenantId,
|
tenantId,
|
||||||
saleInvoiceId,
|
saleInvoiceId,
|
||||||
parsedMessageOptions
|
messageOptions
|
||||||
);
|
);
|
||||||
const mail = new Mail()
|
const mail = new Mail()
|
||||||
.setSubject(formattedMessageOptions.subject)
|
.setSubject(formattedMessageOptions.subject)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export const transformInvoiceToPdfTemplate = (
|
|||||||
total: invoice.totalFormatted,
|
total: invoice.totalFormatted,
|
||||||
subtotal: invoice.subtotalFormatted,
|
subtotal: invoice.subtotalFormatted,
|
||||||
paymentMade: invoice.paymentAmountFormatted,
|
paymentMade: invoice.paymentAmountFormatted,
|
||||||
balanceDue: invoice.balanceAmountFormatted,
|
dueAmount: invoice.dueAmountFormatted,
|
||||||
|
|
||||||
termsConditions: invoice.termsConditions,
|
termsConditions: invoice.termsConditions,
|
||||||
statement: invoice.invoiceMessage,
|
statement: invoice.invoiceMessage,
|
||||||
|
|||||||
@@ -112,17 +112,20 @@ export class SendPaymentReceiveMailNotification {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers the mail invoice.
|
* Retrieves the formatted mail options of the given payment receive.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {number} saleInvoiceId
|
* @param {number} paymentReceiveId
|
||||||
* @param {SendInvoiceMailDTO} messageDTO
|
* @param {SendInvoiceMailDTO} messageDTO
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<PaymentReceiveMailOpts>}
|
||||||
*/
|
*/
|
||||||
public async sendMail(
|
public getFormattedMailOptions = async (
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
paymentReceiveId: number,
|
paymentReceiveId: number,
|
||||||
messageDTO: SendInvoiceMailDTO
|
messageDTO: SendInvoiceMailDTO
|
||||||
): Promise<void> {
|
) => {
|
||||||
|
const formatterArgs = await this.textFormatter(tenantId, paymentReceiveId);
|
||||||
|
|
||||||
|
// Default message options.
|
||||||
const defaultMessageOpts = await this.getMailOptions(
|
const defaultMessageOpts = await this.getMailOptions(
|
||||||
tenantId,
|
tenantId,
|
||||||
paymentReceiveId
|
paymentReceiveId
|
||||||
@@ -132,17 +135,43 @@ export class SendPaymentReceiveMailNotification {
|
|||||||
defaultMessageOpts,
|
defaultMessageOpts,
|
||||||
messageDTO
|
messageDTO
|
||||||
);
|
);
|
||||||
|
// Formats the message options.
|
||||||
|
return this.contactMailNotification.formatMailOptions(
|
||||||
|
tenantId,
|
||||||
|
parsedMessageOpts,
|
||||||
|
formatterArgs
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers the mail invoice.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} saleInvoiceId - Invoice id.
|
||||||
|
* @param {SendInvoiceMailDTO} messageDTO - Message options.
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
public async sendMail(
|
||||||
|
tenantId: number,
|
||||||
|
paymentReceiveId: number,
|
||||||
|
messageDTO: SendInvoiceMailDTO
|
||||||
|
): Promise<void> {
|
||||||
|
// Retrieves the formatted mail options.
|
||||||
|
const formattedMessageOptions = await this.getFormattedMailOptions(
|
||||||
|
tenantId,
|
||||||
|
paymentReceiveId,
|
||||||
|
messageDTO
|
||||||
|
);
|
||||||
const mail = new Mail()
|
const mail = new Mail()
|
||||||
.setSubject(parsedMessageOpts.subject)
|
.setSubject(formattedMessageOptions.subject)
|
||||||
.setTo(parsedMessageOpts.to)
|
.setTo(formattedMessageOptions.to)
|
||||||
.setCC(parsedMessageOpts.cc)
|
.setCC(formattedMessageOptions.cc)
|
||||||
.setBCC(parsedMessageOpts.bcc)
|
.setBCC(formattedMessageOptions.bcc)
|
||||||
.setContent(parsedMessageOpts.message);
|
.setContent(formattedMessageOptions.message);
|
||||||
|
|
||||||
const eventPayload = {
|
const eventPayload = {
|
||||||
tenantId,
|
tenantId,
|
||||||
paymentReceiveId,
|
paymentReceiveId,
|
||||||
messageOptions: parsedMessageOpts,
|
messageOptions: formattedMessageOptions,
|
||||||
};
|
};
|
||||||
// Triggers `onPaymentReceiveMailSend` event.
|
// Triggers `onPaymentReceiveMailSend` event.
|
||||||
await this.eventPublisher.emitAsync(
|
await this.eventPublisher.emitAsync(
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
export const DEFAULT_PAYMENT_MAIL_SUBJECT = 'Payment Received by {CompanyName}';
|
export const DEFAULT_PAYMENT_MAIL_SUBJECT =
|
||||||
|
'Payment Received for {Customer Name} from {Company Name}';
|
||||||
export const DEFAULT_PAYMENT_MAIL_CONTENT = `
|
export const DEFAULT_PAYMENT_MAIL_CONTENT = `
|
||||||
<p>Dear {CustomerName}</p>
|
<p>Dear {Customer Name}</p>
|
||||||
<p>Thank you for your payment. It was a pleasure doing business with you. We look forward to work together again!</p>
|
<p>Thank you for your payment. It was a pleasure doing business with you. We look forward to work together again!</p>
|
||||||
<p>
|
<p>
|
||||||
Payment Date : <strong>{PaymentDate}</strong><br />
|
Payment Date : <strong>{Payment Date}</strong><br />
|
||||||
Amount : <strong>{PaymentAmount}</strong></br />
|
Amount : <strong>{Payment Amount}</strong></br />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<i>Regards</i><br />
|
<i>Regards</i><br />
|
||||||
<i>{CompanyName}</i>
|
<i>{Company Name}</i>
|
||||||
</p>
|
</p>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,58 @@ export class SaleReceiptMailNotification {
|
|||||||
return transformReceiptToMailDataArgs(receipt);
|
return transformReceiptToMailDataArgs(receipt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the mail options of the given sale receipt.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} receiptId
|
||||||
|
* @param {SaleReceiptMailOpts} mailOptions
|
||||||
|
* @returns {Promise<SaleReceiptMailOpts>}
|
||||||
|
*/
|
||||||
|
public async formatEstimateMailOptions(
|
||||||
|
tenantId: number,
|
||||||
|
receiptId: number,
|
||||||
|
mailOptions: SaleReceiptMailOpts
|
||||||
|
): Promise<SaleReceiptMailOpts> {
|
||||||
|
const formatterArgs = await this.textFormatterArgs(tenantId, receiptId);
|
||||||
|
const formattedOptions =
|
||||||
|
(await this.contactMailNotification.formatMailOptions(
|
||||||
|
tenantId,
|
||||||
|
mailOptions,
|
||||||
|
formatterArgs
|
||||||
|
)) as SaleReceiptMailOpts;
|
||||||
|
return formattedOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the formatted mail options of the given sale receipt.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} saleReceiptId
|
||||||
|
* @param {SaleReceiptMailOptsDTO} messageOpts
|
||||||
|
* @returns {Promise<SaleReceiptMailOpts>}
|
||||||
|
*/
|
||||||
|
public getFormatMailOptions = async (
|
||||||
|
tenantId: number,
|
||||||
|
saleReceiptId: number,
|
||||||
|
messageOpts: SaleReceiptMailOptsDTO
|
||||||
|
): Promise<SaleReceiptMailOpts> => {
|
||||||
|
const defaultMessageOptions = await this.getMailOptions(
|
||||||
|
tenantId,
|
||||||
|
saleReceiptId
|
||||||
|
);
|
||||||
|
// Merges message opts with default options.
|
||||||
|
const parsedMessageOpts = mergeAndValidateMailOptions(
|
||||||
|
defaultMessageOptions,
|
||||||
|
messageOpts
|
||||||
|
) as SaleReceiptMailOpts;
|
||||||
|
|
||||||
|
// Formats the message options.
|
||||||
|
return this.formatEstimateMailOptions(
|
||||||
|
tenantId,
|
||||||
|
saleReceiptId,
|
||||||
|
parsedMessageOpts
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers the mail notification of the given sale receipt.
|
* Triggers the mail notification of the given sale receipt.
|
||||||
* @param {number} tenantId - Tenant id.
|
* @param {number} tenantId - Tenant id.
|
||||||
@@ -126,25 +178,21 @@ export class SaleReceiptMailNotification {
|
|||||||
saleReceiptId: number,
|
saleReceiptId: number,
|
||||||
messageOpts: SaleReceiptMailOptsDTO
|
messageOpts: SaleReceiptMailOptsDTO
|
||||||
) {
|
) {
|
||||||
const defaultMessageOptions = await this.getMailOptions(
|
// Formats the message options.
|
||||||
|
const formattedMessageOptions = await this.getFormatMailOptions(
|
||||||
tenantId,
|
tenantId,
|
||||||
saleReceiptId
|
saleReceiptId,
|
||||||
);
|
|
||||||
// Merges message opts with default options.
|
|
||||||
const parsedMessageOpts = mergeAndValidateMailOptions(
|
|
||||||
defaultMessageOptions,
|
|
||||||
messageOpts
|
messageOpts
|
||||||
) as SaleReceiptMailOpts;
|
);
|
||||||
|
|
||||||
const mail = new Mail()
|
const mail = new Mail()
|
||||||
.setSubject(parsedMessageOpts.subject)
|
.setSubject(formattedMessageOptions.subject)
|
||||||
.setTo(parsedMessageOpts.to)
|
.setTo(formattedMessageOptions.to)
|
||||||
.setCC(parsedMessageOpts.cc)
|
.setCC(formattedMessageOptions.cc)
|
||||||
.setBCC(parsedMessageOpts.bcc)
|
.setBCC(formattedMessageOptions.bcc)
|
||||||
.setContent(parsedMessageOpts.message);
|
.setContent(formattedMessageOptions.message);
|
||||||
|
|
||||||
// Attaches the receipt pdf document.
|
// Attaches the receipt pdf document.
|
||||||
if (parsedMessageOpts.attachReceipt) {
|
if (formattedMessageOptions.attachReceipt) {
|
||||||
// Retrieves document buffer of the receipt pdf document.
|
// Retrieves document buffer of the receipt pdf document.
|
||||||
const [receiptPdfBuffer, filename] =
|
const [receiptPdfBuffer, filename] =
|
||||||
await this.receiptPdfService.saleReceiptPdf(tenantId, saleReceiptId);
|
await this.receiptPdfService.saleReceiptPdf(tenantId, saleReceiptId);
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ function LoginFooterLinks() {
|
|||||||
)}
|
)}
|
||||||
<AuthFooterLink>
|
<AuthFooterLink>
|
||||||
<Link to={'/auth/send_reset_password'}>
|
<Link to={'/auth/send_reset_password'}>
|
||||||
<T id={'forget_my_password'} />
|
<T id={'forgot_my_password'} />
|
||||||
</Link>
|
</Link>
|
||||||
</AuthFooterLink>
|
</AuthFooterLink>
|
||||||
</AuthFooterLinks>
|
</AuthFooterLinks>
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ function RegisterFooterLinks() {
|
|||||||
|
|
||||||
<AuthFooterLink>
|
<AuthFooterLink>
|
||||||
<Link to={'/auth/send_reset_password'}>
|
<Link to={'/auth/send_reset_password'}>
|
||||||
<T id={'forget_my_password'} />
|
<T id={'forgot_my_password'} />
|
||||||
</Link>
|
</Link>
|
||||||
</AuthFooterLink>
|
</AuthFooterLink>
|
||||||
</AuthFooterLinks>
|
</AuthFooterLinks>
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export const useBrandingTemplateFormInitialValues = <
|
|||||||
|
|
||||||
const brandingAttributes = {
|
const brandingAttributes = {
|
||||||
templateName: pdfTemplate?.templateName,
|
templateName: pdfTemplate?.templateName,
|
||||||
|
companyLogoUri: pdfTemplate?.companyLogoUri,
|
||||||
...pdfTemplate?.attributes,
|
...pdfTemplate?.attributes,
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
@@ -56,14 +57,16 @@ export const useBrandingTemplateFormInitialValues = <
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useBrandingState = (state?: Partial<BrandingState>): BrandingState => {
|
export const useBrandingState = (
|
||||||
|
state?: Partial<BrandingState>,
|
||||||
|
): BrandingState => {
|
||||||
const { brandingTemplateState } = useBrandingTemplateBoot();
|
const { brandingTemplateState } = useBrandingTemplateBoot();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...brandingTemplateState,
|
...brandingTemplateState,
|
||||||
...state
|
...state,
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getCustomizeDrawerNameFromResource = (resource: string) => {
|
export const getCustomizeDrawerNameFromResource = (resource: string) => {
|
||||||
const pairs = {
|
const pairs = {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ function EstimateMailDialogFormRoot({
|
|||||||
closeDialog,
|
closeDialog,
|
||||||
}) {
|
}) {
|
||||||
const { mutateAsync: sendEstimateMail } = useSendSaleEstimateMail();
|
const { mutateAsync: sendEstimateMail } = useSendSaleEstimateMail();
|
||||||
const { mailOptions, saleEstimateId, redirectToEstimatesList } =
|
const { mailOptions, saleEstimateId, } =
|
||||||
useEstimateMailDialogBoot();
|
useEstimateMailDialogBoot();
|
||||||
|
|
||||||
const initialValues = transformMailFormToInitialValues(
|
const initialValues = transformMailFormToInitialValues(
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ export function EstimateMailDialogFormContent({
|
|||||||
<Form>
|
<Form>
|
||||||
<div className={Classes.DIALOG_BODY}>
|
<div className={Classes.DIALOG_BODY}>
|
||||||
<MailNotificationForm
|
<MailNotificationForm
|
||||||
fromAddresses={mailOptions.from_addresses}
|
fromAddresses={mailOptions.from_options}
|
||||||
toAddresses={mailOptions.to_addresses}
|
toAddresses={mailOptions.to_options}
|
||||||
/>
|
/>
|
||||||
<AttachFormGroup name={'attachEstimate'} inline>
|
<AttachFormGroup name={'attachEstimate'} inline>
|
||||||
<FSwitch name={'attachEstimate'} label={'Attach Estimate'} />
|
<FSwitch name={'attachEstimate'} label={'Attach Estimate'} />
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ interface PaymentMailDialogBootProps {
|
|||||||
*/
|
*/
|
||||||
function PaymentMailDialogBoot({
|
function PaymentMailDialogBoot({
|
||||||
paymentReceiveId,
|
paymentReceiveId,
|
||||||
|
redirectToPaymentsList,
|
||||||
...props
|
...props
|
||||||
}: PaymentMailDialogBootProps) {
|
}: PaymentMailDialogBootProps) {
|
||||||
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ export function PaymentMailDialogFormContent({
|
|||||||
<Form>
|
<Form>
|
||||||
<div className={Classes.DIALOG_BODY}>
|
<div className={Classes.DIALOG_BODY}>
|
||||||
<MailNotificationForm
|
<MailNotificationForm
|
||||||
fromAddresses={mailOptions.from_addresses}
|
fromAddresses={mailOptions.from_options}
|
||||||
toAddresses={mailOptions.to_addresses}
|
toAddresses={mailOptions.to_options}
|
||||||
/>
|
/>
|
||||||
<AttachFormGroup name={'attachPayment'} inline>
|
<AttachFormGroup name={'attachPayment'} inline>
|
||||||
<FSwitch name={'attachPayment'} label={'Attach Payment'} />
|
<FSwitch name={'attachPayment'} label={'Attach Payment'} />
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ export function ReceiptMailDialogFormContent({
|
|||||||
<Form>
|
<Form>
|
||||||
<div className={Classes.DIALOG_BODY}>
|
<div className={Classes.DIALOG_BODY}>
|
||||||
<MailNotificationForm
|
<MailNotificationForm
|
||||||
fromAddresses={mailOptions.from_addresses}
|
fromAddresses={mailOptions.from_options}
|
||||||
toAddresses={mailOptions.to_addresses}
|
toAddresses={mailOptions.to_options}
|
||||||
/>
|
/>
|
||||||
<AttachFormGroup name={'attachReceipt:'} inline>
|
<AttachFormGroup name={'attachReceipt:'} inline>
|
||||||
<FSwitch name={'attachReceipt:'} label={'Attach Receipt'} />
|
<FSwitch name={'attachReceipt:'} label={'Attach Receipt'} />
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export function MailNotificationForm({
|
|||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
</HeaderBox>
|
</HeaderBox>
|
||||||
|
|
||||||
<MailMessageEditor name={'body'} />
|
<MailMessageEditor name={'message'} />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export const initialMailNotificationValues = {
|
|||||||
from: [],
|
from: [],
|
||||||
to: [],
|
to: [],
|
||||||
subject: '',
|
subject: '',
|
||||||
body: '',
|
message: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface MailNotificationFormValues {
|
export interface MailNotificationFormValues {
|
||||||
@@ -26,7 +26,7 @@ export const transformMailFormToRequest = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transformes the mail options response values to form initial values.
|
* Transforms the mail options response values to form initial values.
|
||||||
* @param {any} mailOptions
|
* @param {any} mailOptions
|
||||||
* @param {MailNotificationFormValues} initialValues
|
* @param {MailNotificationFormValues} initialValues
|
||||||
* @returns {MailNotificationFormValues}
|
* @returns {MailNotificationFormValues}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export interface GetPdfTemplateValues {}
|
|||||||
|
|
||||||
export interface GetPdfTemplateResponse {
|
export interface GetPdfTemplateResponse {
|
||||||
templateName: string;
|
templateName: string;
|
||||||
|
companyLogoUri?: string | null;
|
||||||
attributes: Record<string, any>;
|
attributes: Record<string, any>;
|
||||||
predefined: boolean;
|
predefined: boolean;
|
||||||
default: boolean;
|
default: boolean;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
"to_date": "الى تاريخ",
|
"to_date": "الى تاريخ",
|
||||||
"report_date_range": "تقرير نطاق التاريخ",
|
"report_date_range": "تقرير نطاق التاريخ",
|
||||||
"log_in": "تسجيل الدخول",
|
"log_in": "تسجيل الدخول",
|
||||||
"forget_my_password": "نسيت كلمة المرور الخاصة بي",
|
"forgot_my_password": "نسيت كلمة المرور الخاصة بي",
|
||||||
"keep_me_logged_in": "تذكرني",
|
"keep_me_logged_in": "تذكرني",
|
||||||
"dont_have_an_account": "ليس لديك حساب؟",
|
"dont_have_an_account": "ليس لديك حساب؟",
|
||||||
"sign_up": "تسجيل",
|
"sign_up": "تسجيل",
|
||||||
@@ -1570,8 +1570,8 @@
|
|||||||
"refund": "استرجاع",
|
"refund": "استرجاع",
|
||||||
"landed_cost.dialog.label_select_transaction": "حدد المعاملة ",
|
"landed_cost.dialog.label_select_transaction": "حدد المعاملة ",
|
||||||
"landed_cost.dialog.label_select_transaction_entry": "حدد سطر المعاملة ",
|
"landed_cost.dialog.label_select_transaction_entry": "حدد سطر المعاملة ",
|
||||||
"landed_cost.dialog.label_unallocated_cost_amount":"قيمة التكلفة غير المحملة:",
|
"landed_cost.dialog.label_unallocated_cost_amount": "قيمة التكلفة غير المحملة:",
|
||||||
"landed_cost.error.the_total_located_cost_is_bigger_than_the_transaction_line":"إجمالي قيمة التكلفة المحملة أكبر من قيمة سطر المعاملة.",
|
"landed_cost.error.the_total_located_cost_is_bigger_than_the_transaction_line": "إجمالي قيمة التكلفة المحملة أكبر من قيمة سطر المعاملة.",
|
||||||
"landed_cost.once_your_delete_this_located_landed_cost": "بمجرد حذف معاملة تحميل التكلفة ، لن تتمكن من استعادتها لاحقًا ، هل أنت متأكد من أنك تريد حذف هذه المعاملة؟",
|
"landed_cost.once_your_delete_this_located_landed_cost": "بمجرد حذف معاملة تحميل التكلفة ، لن تتمكن من استعادتها لاحقًا ، هل أنت متأكد من أنك تريد حذف هذه المعاملة؟",
|
||||||
"refund_credit_note.dialog.label": "استرجاع اموال",
|
"refund_credit_note.dialog.label": "استرجاع اموال",
|
||||||
"refund_credit_note.dialog.success_message": "تم انشاء معاملة استرجاع الاموال لإشعار الدائن بنجاح.",
|
"refund_credit_note.dialog.success_message": "تم انشاء معاملة استرجاع الاموال لإشعار الدائن بنجاح.",
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
"to_date": "To date",
|
"to_date": "To date",
|
||||||
"report_date_range": "Report date range",
|
"report_date_range": "Report date range",
|
||||||
"log_in": "Log in",
|
"log_in": "Log in",
|
||||||
"forget_my_password": "Forget my password",
|
"forgot_my_password": "Forgot my password",
|
||||||
"keep_me_logged_in": "Keep me logged in",
|
"keep_me_logged_in": "Keep me logged in",
|
||||||
"dont_have_an_account": "Don't have an account?",
|
"dont_have_an_account": "Don't have an account?",
|
||||||
"sign_up": "Sign up",
|
"sign_up": "Sign up",
|
||||||
|
|||||||
6
packages/webapp/src/lang/es/authentication.tsx
Normal file
6
packages/webapp/src/lang/es/authentication.tsx
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"login": "Ingresar",
|
||||||
|
"reset_password": "Resetear contraseña",
|
||||||
|
};
|
||||||
2275
packages/webapp/src/lang/es/index.json
Normal file
2275
packages/webapp/src/lang/es/index.json
Normal file
File diff suppressed because it is too large
Load Diff
61
packages/webapp/src/lang/es/locale.tsx
Normal file
61
packages/webapp/src/lang/es/locale.tsx
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import printValue from '../printValue';
|
||||||
|
|
||||||
|
export const locale = {
|
||||||
|
mixed: {
|
||||||
|
default: '${path} es inválido',
|
||||||
|
required: '${path} es un campo requerido',
|
||||||
|
oneOf: '${path} debe ser uno de los siguientes valores: ${values}',
|
||||||
|
notOneOf: '${path} no debe ser uno de los siguientes valores: ${values}',
|
||||||
|
notType: ({ path, type, value, originalValue }) => {
|
||||||
|
let isCast = originalValue != null && originalValue !== value;
|
||||||
|
let msg =
|
||||||
|
`${path} debe ser de tipo \`${type}\`, ` +
|
||||||
|
`pero el valor final fue: \`${printValue(value, true)}\`` +
|
||||||
|
(isCast
|
||||||
|
? ` (convertido del valor \`${printValue(originalValue, true)}\`).`
|
||||||
|
: '.');
|
||||||
|
|
||||||
|
if (value === null) {
|
||||||
|
msg += `\n Si "null" se pretende como un valor vacío, asegúrate de marcar el esquema como \`.nullable()\``;
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
},
|
||||||
|
defined: '${path} debe estar definido',
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
length: '${path} debe tener exactamente ${length} caracteres',
|
||||||
|
min: '${path} debe tener al menos ${min} caracteres',
|
||||||
|
max: '${path} debe tener como máximo ${max} caracteres',
|
||||||
|
matches: '${path} debe coincidir con lo siguiente: "${regex}"',
|
||||||
|
email: '${path} debe ser un correo electrónico válido',
|
||||||
|
url: '${path} debe ser una URL válida',
|
||||||
|
trim: '${path} debe ser una cadena recortada',
|
||||||
|
lowercase: '${path} debe ser una cadena en minúsculas',
|
||||||
|
uppercase: '${path} debe ser una cadena en mayúsculas',
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
min: '${path} debe ser mayor o igual a ${min}',
|
||||||
|
max: '${path} debe ser menor o igual a ${max}',
|
||||||
|
lessThan: '${path} debe ser menor que ${less}',
|
||||||
|
moreThan: '${path} debe ser mayor que ${more}',
|
||||||
|
notEqual: '${path} no debe ser igual a ${notEqual}',
|
||||||
|
positive: '${path} debe ser un número positivo',
|
||||||
|
negative: '${path} debe ser un número negativo',
|
||||||
|
integer: '${path} debe ser un número entero',
|
||||||
|
},
|
||||||
|
date: {
|
||||||
|
min: '${path} debe ser posterior a ${min}',
|
||||||
|
max: '${path} debe ser anterior a ${max}',
|
||||||
|
},
|
||||||
|
boolean: {},
|
||||||
|
object: {
|
||||||
|
noUnknown:
|
||||||
|
'${path} no puede tener claves no especificadas en la forma del objeto',
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
min: '${path} debe tener al menos ${min} elementos',
|
||||||
|
max: '${path} debe tener como máximo ${max} elementos',
|
||||||
|
},
|
||||||
|
};
|
||||||
7
packages/webapp/src/lang/sv/authentication.tsx
Normal file
7
packages/webapp/src/lang/sv/authentication.tsx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
"login": "Logga in",
|
||||||
|
"reset_password": "Återställ lösenord",
|
||||||
|
};
|
||||||
2247
packages/webapp/src/lang/sv/index.json
Normal file
2247
packages/webapp/src/lang/sv/index.json
Normal file
File diff suppressed because it is too large
Load Diff
61
packages/webapp/src/lang/sv/locale.tsx
Normal file
61
packages/webapp/src/lang/sv/locale.tsx
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import printValue from '../printValue';
|
||||||
|
|
||||||
|
export const locale = {
|
||||||
|
mixed: {
|
||||||
|
default: '${path} är inkorrekt',
|
||||||
|
required: '${path} är ett obligatoriskt fält ',
|
||||||
|
oneOf: '${path} måste vara en av följande värden: ${values}',
|
||||||
|
notOneOf: '${path} kan inte vara en av följande värden: ${values}',
|
||||||
|
notType: ({ path, type, value, originalValue }) => {
|
||||||
|
let isCast = originalValue != null && originalValue !== value;
|
||||||
|
let msg =
|
||||||
|
`${path} måste ha typen \`${type}\`, ` +
|
||||||
|
`men det slutliga värdet var: \`${printValue(value, true)}\`` +
|
||||||
|
(isCast
|
||||||
|
? ` (gjord av värdet \`${printValue(originalValue, true)}\`).`
|
||||||
|
: '.');
|
||||||
|
|
||||||
|
if (value === null) {
|
||||||
|
msg += `\n Om ”null” är avsett som ett tomt värde ska du se till att markera schemat som \`.nullable()\``;
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
},
|
||||||
|
defined: '${path} måste vara definierad',
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
length: '${path} måste vara exakt ${length} tecken',
|
||||||
|
min: '${path} måste vara som minst ${min} tecken',
|
||||||
|
max: '${path} måste vara som mest ${max} tecken',
|
||||||
|
matches: '${path} måste matcha det följande: "${regex}"',
|
||||||
|
email: '${path} måste vara en giltig e-post',
|
||||||
|
url: '${path} måste vara en giltig URL',
|
||||||
|
trim: '${path} måste vara en trimmad sträng',
|
||||||
|
lowercase: '${path} måste vara en sträng med små bokstäver',
|
||||||
|
uppercase: '${path} måste vara en sträng med stora bokstäver',
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
min: '${path} måste vara större eller lika med ${min}',
|
||||||
|
max: '${path} måste vara mindre eller lika med ${max}',
|
||||||
|
lessThan: '${path} måste vara mindre än ${less}',
|
||||||
|
moreThan: '${path} måste vara större än ${more}',
|
||||||
|
notEqual: '${path} får inte vara lika med ${notEqual}',
|
||||||
|
positive: '${path} får inte vara ett positivt nummer',
|
||||||
|
negative: '${path} får inte vara ett negativt nummer',
|
||||||
|
integer: '${path} måste vara ett nummer',
|
||||||
|
},
|
||||||
|
date: {
|
||||||
|
min: '${path} fältet måste vara senare än ${min}',
|
||||||
|
max: '${path} fältet måste vara tidigare än ${max}',
|
||||||
|
},
|
||||||
|
boolean: {},
|
||||||
|
object: {
|
||||||
|
noUnknown:
|
||||||
|
'${path}-fältet kan inte ha nycklar som inte anges i objektform',
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
min: '${path}-fältet måste ha minst ${min} objekt',
|
||||||
|
max: '${path} fältet måste ha mindre än eller lika med ${max} objekt',
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
import { Meta } from '@storybook/react';
|
import { Meta } from '@storybook/react';
|
||||||
import { StoryFn } from '@storybook/react';
|
import { StoryFn } from '@storybook/react';
|
||||||
import {
|
import {
|
||||||
@@ -15,22 +16,3 @@ export default meta;
|
|||||||
const Template: StoryFn<typeof InvoicePaymentEmail> = (
|
const Template: StoryFn<typeof InvoicePaymentEmail> = (
|
||||||
args: InvoicePaymentEmailProps
|
args: InvoicePaymentEmailProps
|
||||||
) => <InvoicePaymentEmail {...args} />;
|
) => <InvoicePaymentEmail {...args} />;
|
||||||
|
|
||||||
export const PreviewInvoicePaymentMail = Template.bind({});
|
|
||||||
|
|
||||||
PreviewInvoicePaymentMail.args = {
|
|
||||||
preview: 'Preview text',
|
|
||||||
companyName: 'ABC Company',
|
|
||||||
companyLogoUri: 'https://example.com/logo.png',
|
|
||||||
invoiceAmount: '100.00',
|
|
||||||
dueDate: '2022-12-31',
|
|
||||||
invoiceMessage: 'Thank you for your purchase!',
|
|
||||||
invoiceNumber: 'INV-001',
|
|
||||||
dueAmount: '100.00',
|
|
||||||
total: '100.00',
|
|
||||||
viewInvoiceButtonUrl: 'https://example.com/invoice',
|
|
||||||
items: [
|
|
||||||
{ label: 'Item 1', quantity: '1', rate: '50.00' },
|
|
||||||
{ label: 'Item 2', quantity: '2', rate: '25.00' },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --config webpack.config.js",
|
"build": "webpack --config webpack.config.js",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"preview": "vite preview",
|
|
||||||
"storybook:dev": "storybook dev -p 6006",
|
"storybook:dev": "storybook dev -p 6006",
|
||||||
"storybook:build": "storybook build"
|
"storybook:build": "storybook build"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -71,10 +71,12 @@ export interface InvoicePaperTemplateProps extends PaperTemplateProps {
|
|||||||
totalLabel?: string;
|
totalLabel?: string;
|
||||||
total?: string;
|
total?: string;
|
||||||
|
|
||||||
|
// Discount
|
||||||
showDiscount?: boolean;
|
showDiscount?: boolean;
|
||||||
discountLabel?: string;
|
discountLabel?: string;
|
||||||
discount?: string;
|
discount?: string;
|
||||||
|
|
||||||
|
// Subtotal
|
||||||
showSubtotal?: boolean;
|
showSubtotal?: boolean;
|
||||||
subtotalLabel?: string;
|
subtotalLabel?: string;
|
||||||
subtotal?: string;
|
subtotal?: string;
|
||||||
@@ -85,10 +87,10 @@ export interface InvoicePaperTemplateProps extends PaperTemplateProps {
|
|||||||
|
|
||||||
showTaxes?: boolean;
|
showTaxes?: boolean;
|
||||||
|
|
||||||
|
// Due Amount
|
||||||
showDueAmount?: boolean;
|
showDueAmount?: boolean;
|
||||||
showBalanceDue?: boolean;
|
dueAmountLabel?: string;
|
||||||
balanceDueLabel?: string;
|
dueAmount?: string;
|
||||||
balanceDue?: string;
|
|
||||||
|
|
||||||
// Footer
|
// Footer
|
||||||
termsConditionsLabel?: string;
|
termsConditionsLabel?: string;
|
||||||
@@ -144,7 +146,7 @@ export function InvoicePaperTemplate({
|
|||||||
subtotalLabel = 'Subtotal',
|
subtotalLabel = 'Subtotal',
|
||||||
discountLabel = 'Discount',
|
discountLabel = 'Discount',
|
||||||
paymentMadeLabel = 'Payment Made',
|
paymentMadeLabel = 'Payment Made',
|
||||||
balanceDueLabel = 'Balance Due',
|
dueAmountLabel = 'Balance Due',
|
||||||
|
|
||||||
// Totals
|
// Totals
|
||||||
showTotal = true,
|
showTotal = true,
|
||||||
@@ -153,13 +155,12 @@ export function InvoicePaperTemplate({
|
|||||||
showTaxes = true,
|
showTaxes = true,
|
||||||
showPaymentMade = true,
|
showPaymentMade = true,
|
||||||
showDueAmount = true,
|
showDueAmount = true,
|
||||||
showBalanceDue = true,
|
|
||||||
|
|
||||||
total = '$662.75',
|
total = '$662.75',
|
||||||
subtotal = '630.00',
|
subtotal = '630.00',
|
||||||
discount = '0.00',
|
discount = '0.00',
|
||||||
paymentMade = '100.00',
|
paymentMade = '100.00',
|
||||||
balanceDue = '$562.75',
|
dueAmount = '$562.75',
|
||||||
|
|
||||||
// Footer paragraphs.
|
// Footer paragraphs.
|
||||||
termsConditionsLabel = 'Terms & Conditions',
|
termsConditionsLabel = 'Terms & Conditions',
|
||||||
@@ -297,10 +298,10 @@ export function InvoicePaperTemplate({
|
|||||||
amount={paymentMade}
|
amount={paymentMade}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showBalanceDue && (
|
{showDueAmount && (
|
||||||
<PaperTemplate.TotalLine
|
<PaperTemplate.TotalLine
|
||||||
label={balanceDueLabel}
|
label={dueAmountLabel}
|
||||||
amount={balanceDue}
|
amount={dueAmount}
|
||||||
border={PaperTemplateTotalBorder.Dark}
|
border={PaperTemplateTotalBorder.Dark}
|
||||||
style={{ fontWeight: 500 }}
|
style={{ fontWeight: 500 }}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"types": ["vitest/globals"],
|
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
import react from '@vitejs/plugin-react';
|
|
||||||
import path from 'node:path';
|
|
||||||
import { defineConfig } from 'vitest/config';
|
|
||||||
import dts from 'vite-plugin-dts';
|
|
||||||
import tailwindcss from 'tailwindcss';
|
|
||||||
import { UserConfigExport } from 'vite';
|
|
||||||
import { name } from './package.json';
|
|
||||||
|
|
||||||
const app = async (): Promise<UserConfigExport> => {
|
|
||||||
/**
|
|
||||||
* Removes everything before the last
|
|
||||||
* @octocat/library-repo -> library-repo
|
|
||||||
* vite-component-library-template -> vite-component-library-template
|
|
||||||
*/
|
|
||||||
const formattedName = name.match(/[^/]+$/)?.[0] ?? name;
|
|
||||||
|
|
||||||
return defineConfig({
|
|
||||||
define: {
|
|
||||||
isBrowser: 'false', // This will replace isBrowser with false in the bundled code
|
|
||||||
},
|
|
||||||
ssr: {
|
|
||||||
noExternal: true,
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
react(),
|
|
||||||
dts({
|
|
||||||
insertTypesEntry: true,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
css: {
|
|
||||||
postcss: {
|
|
||||||
plugins: [tailwindcss],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
build: {
|
|
||||||
lib: {
|
|
||||||
entry: path.resolve(__dirname, 'src/lib/main.ts'),
|
|
||||||
name: formattedName,
|
|
||||||
formats: ['es', 'umd'],
|
|
||||||
fileName: (format: string) => `${formattedName}.${format}.js`,
|
|
||||||
},
|
|
||||||
rollupOptions: {
|
|
||||||
// external: ['react', 'react/jsx-runtime', 'react-dom', 'tailwindcss'],
|
|
||||||
// output: {
|
|
||||||
// globals: {
|
|
||||||
// react: 'React',
|
|
||||||
// 'react/jsx-runtime': 'react/jsx-runtime',
|
|
||||||
// 'react-dom': 'ReactDOM',
|
|
||||||
// tailwindcss: 'tailwindcss',
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
test: {
|
|
||||||
globals: true,
|
|
||||||
environment: 'jsdom',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// https://vitejs.dev/config/
|
|
||||||
export default app;
|
|
||||||
Reference in New Issue
Block a user