Merge branch 'feature/i18n-arabic'

This commit is contained in:
a.bouhuolia
2021-07-11 21:55:01 +02:00
576 changed files with 11309 additions and 3054 deletions

View File

@@ -27,6 +27,8 @@ const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
const CompressionPlugin = require("compression-webpack-plugin"); const CompressionPlugin = require("compression-webpack-plugin");
const postcssNormalize = require('postcss-normalize'); const postcssNormalize = require('postcss-normalize');
const { postcssRTLCSS} = require('postcss-rtlcss');
const appPackageJson = require(paths.appPackageJson); const appPackageJson = require(paths.appPackageJson);
@@ -92,6 +94,14 @@ module.exports = function(webpackEnv) {
// https://github.com/facebook/create-react-app/issues/2677 // https://github.com/facebook/create-react-app/issues/2677
ident: 'postcss', ident: 'postcss',
plugins: () => [ plugins: () => [
// Postcss rtlcss plugin.
// require( 'postcss-rtl' )({
// // options here.
// removeComments: false,
// }),
postcssRTLCSS({
}),
require('postcss-flexbugs-fixes'), require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({ require('postcss-preset-env')({
autoprefixer: { autoprefixer: {
@@ -120,6 +130,10 @@ module.exports = function(webpackEnv) {
loader: require.resolve(preProcessor), loader: require.resolve(preProcessor),
options: { options: {
sourceMap: true, sourceMap: true,
sassOptions: {
sourceComments: true,
outputStyle: 'expanded'
}
}, },
} }
); );

View File

@@ -61,7 +61,9 @@
"postcss-loader": "3.0.0", "postcss-loader": "3.0.0",
"postcss-normalize": "8.0.1", "postcss-normalize": "8.0.1",
"postcss-preset-env": "6.7.0", "postcss-preset-env": "6.7.0",
"postcss-rtl": "^1.7.3",
"postcss-safe-parser": "4.0.1", "postcss-safe-parser": "4.0.1",
"ramda": "^0.27.1",
"react": "^16.12.0", "react": "^16.12.0",
"react-app-polyfill": "^1.0.6", "react-app-polyfill": "^1.0.6",
"react-body-classname": "^1.3.1", "react-body-classname": "^1.3.1",
@@ -71,7 +73,7 @@
"react-dropzone": "^11.0.1", "react-dropzone": "^11.0.1",
"react-error-boundary": "^3.0.2", "react-error-boundary": "^3.0.2",
"react-hotkeys-hook": "^3.0.3", "react-hotkeys-hook": "^3.0.3",
"react-intl": "^3.12.0", "react-intl-universal": "^2.4.7",
"react-loadable": "^5.5.0", "react-loadable": "^5.5.0",
"react-query": "^3.6.0", "react-query": "^3.6.0",
"react-redux": "^7.1.3", "react-redux": "^7.1.3",
@@ -92,6 +94,7 @@
"redux-thunk": "^2.3.0", "redux-thunk": "^2.3.0",
"resolve": "1.15.0", "resolve": "1.15.0",
"resolve-url-loader": "3.1.1", "resolve-url-loader": "3.1.1",
"rtl-detect": "^1.0.3",
"sass-loader": "8.0.2", "sass-loader": "8.0.2",
"semver": "6.3.0", "semver": "6.3.0",
"style-loader": "0.23.1", "style-loader": "0.23.1",
@@ -135,6 +138,7 @@
"@welldone-software/why-did-you-render": "^6.0.0-rc.1", "@welldone-software/why-did-you-render": "^6.0.0-rc.1",
"compression-webpack-plugin": "^6.1.0", "compression-webpack-plugin": "^6.1.0",
"http-proxy-middleware": "^1.0.0", "http-proxy-middleware": "^1.0.0",
"postcss-rtlcss": "^1.7.2",
"react-query-devtools": "^2.1.1", "react-query-devtools": "^2.1.1",
"redux-devtools": "^3.5.0", "redux-devtools": "^3.5.0",
"typescript": "^4.1.2" "typescript": "^4.1.2"

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html dir="ltr" lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicons/favicon-32.ico" sizes="32x32"> <link rel="icon" href="%PUBLIC_URL%/favicons/favicon-32.ico" sizes="32x32">

View File

@@ -1,4 +1,6 @@
import intl from 'react-intl-universal';
export default [ export default [
{ name: 'Decrement', value: 'decrement' }, { name: intl.get('decrement'), value: 'decrement' },
{ name: 'Increment', value: 'increment' }, { name: intl.get('increment'), value: 'increment' },
] ]

View File

@@ -1,4 +1,7 @@
import React from 'react';
import intl from 'react-intl-universal';
export default [ export default [
{ name: 'Customer', path: 'customers' }, { name: intl.get('customer'), path: 'customers' },
{ name: 'Vendor', path: 'vendors' }, { name: intl.get('vendor'), path: 'vendors' },
]; ];

View File

@@ -1,5 +1,3 @@
import intl from 'react-intl-universal';
export default [{ name: intl.get('libya'), value: 'libya' }];
export default [
{ name: 'Libya', value: 'libya' },
]

View File

@@ -1,5 +1,7 @@
import intl from 'react-intl-universal';
export default [ export default [
{ name: 'US Dollar', code: 'USD' }, { name: intl.get('us_dollar'), code: 'USD' },
{ name: 'Euro', code: 'EUR' }, { name: intl.get('euro'), code: 'EUR' },
{ name: 'Libyan Dinar ', code: 'LYD' }, { name: intl.get('libyan_diner'), code: 'LYD' },
] ];

View File

@@ -1,40 +1,41 @@
import moment from 'moment'; import moment from 'moment';
import intl from 'react-intl-universal';
export default [ export default [
{ {
id: 1, id: 1,
name: 'MM/DD/YY', name: intl.get('mm_dd_yy'),
label: `${moment().format('MM/DD/YYYY')}`, label: `${moment().format('MM/DD/YYYY')}`,
value: 'mm/dd/yy', value: 'mm/dd/yy',
}, },
{ {
id: 2, id: 2,
name: 'DD/MM/YY', name: intl.get('dd_mm_yy'),
label: `${moment().format('DD/MM/YYYY')}`, label: `${moment().format('DD/MM/YYYY')}`,
value: 'dd/mm/yy', value: 'dd/mm/yy',
}, },
{ {
id: 3, id: 3,
name: 'YY/MM/DD', name: intl.get('yy_mm_dd'),
label: `${moment().format('YYYY/MM/DD')}`, label: `${moment().format('YYYY/MM/DD')}`,
value: 'yy/mm/dd', value: 'yy/mm/dd',
}, },
{ {
id: 4, id: 4,
name: 'MM-DD-YY', name: intl.get('mm_dd_yy'),
label: `${moment().format('MM-DD-YYYY')}`, label: `${moment().format('MM-DD-YYYY')}`,
value: 'mm-dd-yy', value: 'mm-dd-yy',
}, },
{ {
id: 5, id: 5,
name: 'DD-MM-YY', name: intl.get('dd_mm_yy_'),
label: `${moment().format('DD-MM-YYYY')}`, label: `${moment().format('DD-MM-YYYY')}`,
value: 'dd-mm-yy', value: 'dd-mm-yy',
}, },
{ {
id: 6, id: 6,
name: 'YY-MM-DD', name: intl.get('yy_mm_dd_'),
label: `${moment().format('YYYY-MM-DD')}`, label: `${moment().format('YYYY-MM-DD')}`,
value: 'yy-mm-dd', value: 'yy-mm-dd',
}, },
] ];

View File

@@ -1,88 +1,64 @@
import { formatMessage } from 'services/intl'; import intl from 'react-intl-universal';
export default [ export const getFiscalYearOptions = () => [
{ {
id: 0, id: 0,
name: `${formatMessage({ id: 'january' })} - ${formatMessage({ name: `${intl.get('january')} - ${intl.get('december')}`,
id: 'december',
})}`,
value: 'january', value: 'january',
}, },
{ {
id: 1, id: 1,
name: `${formatMessage({ id: 'february' })} - ${formatMessage({ name: `${intl.get('february')} - ${intl.get('january')}`,
id: 'january',
})}`,
value: 'february', value: 'february',
}, },
{ {
id: 2, id: 2,
name: `${formatMessage({ id: 'march' })} - ${formatMessage({ name: `${intl.get('march')} - ${intl.get('february')}`,
id: 'february',
})}`,
value: 'March', value: 'March',
}, },
{ {
id: 3, id: 3,
name: `${formatMessage({ id: 'april' })} - ${formatMessage({ name: `${intl.get('april')} - ${intl.get('march')}`,
id: 'march',
})}`,
value: 'april', value: 'april',
}, },
{ {
id: 4, id: 4,
name: `${formatMessage({ id: 'may' })} - ${formatMessage({ name: `${intl.get('may')} - ${intl.get('april')}`,
id: 'april',
})}`,
value: 'may', value: 'may',
}, },
{ {
id: 5, id: 5,
name: `${formatMessage({ id: 'june' })} - ${formatMessage({ name: `${intl.get('june')} - ${intl.get('may')}`,
id: 'may',
})}`,
value: 'june', value: 'june',
}, },
{ {
id: 6, id: 6,
name: `${formatMessage({ id: 'july' })} - ${formatMessage({ name: `${intl.get('july')} - ${intl.get('june')}`,
id: 'june',
})}`,
value: 'july', value: 'july',
}, },
{ {
id: 7, id: 7,
name: `${formatMessage({ id: 'august' })} - ${formatMessage({ name: `${intl.get('august')} - ${intl.get('july')}`,
id: 'july',
})}`,
value: 'August', value: 'August',
}, },
{ {
id: 8, id: 8,
name: `${formatMessage({ id: 'september' })} - ${formatMessage({ name: `${intl.get('september')} - ${intl.get('august')}`,
id: 'august',
})}`,
value: 'september', value: 'september',
}, },
{ {
id: 9, id: 9,
name: `${formatMessage({ id: 'october' })} - ${formatMessage({ name: `${intl.get('october')} - ${intl.get('november')}`,
id: 'november',
})}`,
value: 'october', value: 'october',
}, },
{ {
id: 10, id: 10,
name: `${formatMessage({ id: 'november' })} - ${formatMessage({ name: `${intl.get('november')} - ${intl.get('october')}`,
id: 'october',
})}`,
value: 'november', value: 'november',
}, },
{ {
id: 11, id: 11,
name: `${formatMessage({ id: 'december' })} - ${formatMessage({ name: `${intl.get('december')} - ${intl.get('november')}`,
id: 'november',
})}`,
value: 'december', value: 'december',
}, },
] ]

View File

@@ -1,38 +1,35 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
export const accountsReceivable = [ export const accountsReceivable = [
{ {
sectionTitle: <T id={'accounts_receivable_a_r'} />, sectionTitle: <T id={'accounts_receivable_a_r'} />,
shortcuts: [ shortcuts: [
{ {
title: 'Sales invoices', title: <T id={'sales_invoices'} />,
description: 'Tracking sales invoices with your customers with payment due date.', description: <T id={'tracking_sales_invoices_with_your_customers'} />,
link: '/invoices', link: '/invoices',
}, },
{ {
title: 'Sales estimates', title: <T id={'sales_estimates'} />,
description: description: <T id={'manage_your_sales_estimates_to_create_quotes'} />,
'Manage your sales estimates to create quotes that can later be turned to a sale invoice.',
link: '/estimates', link: '/estimates',
}, },
{ {
title: 'Sales receipts', title: <T id={'sales_receipts'} />,
description: description: <T id={'manage_sales_receipts_for_sales_that_get_paid'} />,
'Manage sales receipts for sales that get paid immediately from the customer.',
link: '/receipts', link: '/receipts',
}, },
{ {
title: 'Customers', title: <T id={'customers'} />,
description: 'Manage the customers relations with customer receivable and credit balances.', description: <T id={'manage_the_customers_relations_with_customer'} />,
link: '/customers', link: '/customers',
}, },
{ {
title: 'Customers payment', title: <T id={'customers_payments'} />,
description: description: (
'Manage payment transactions from your customers with sale invoices.', <T id={'manage_payment_transactions_from_your_customers'} />
),
link: '/payment-receives', link: '/payment-receives',
}, },
], ],
@@ -44,20 +41,22 @@ export const accountsPayable = [
sectionTitle: <T id={'accounts_payable_a_p'} />, sectionTitle: <T id={'accounts_payable_a_p'} />,
shortcuts: [ shortcuts: [
{ {
title: 'Purchase invoices', title: <T id={'purchase_invoices'} />,
description: 'Manage the purchase invoices with your vendors with payment due date.', description: (
<T id={'manage_the_purchase_invoices_with_your_vendors'} />
),
link: '/bills', link: '/bills',
}, },
{ {
title: 'Vendors', title: <T id={'vendors'} />,
description: 'Manage the vendors relations with vendor payable and debit balances.', description: (
<T id={'manage_the_vendors_relations_with_vendor_relations'} />
),
link: '/vendors', link: '/vendors',
}, },
{ {
title: 'Vendors payments', title: <T id={'vendors_payments'} />,
description: description: <T id={'manage_payments_transactions_to_your_vendors'} />,
'Manage payments transactions to your vendors with purchase invoices.',
link: '/payment-mades', link: '/payment-mades',
}, },
], ],
@@ -69,26 +68,29 @@ export const financialAccounting = [
sectionTitle: <T id={'financial_accounting'} />, sectionTitle: <T id={'financial_accounting'} />,
shortcuts: [ shortcuts: [
{ {
title: 'Chart of accounts', title: <T id={'chart_of_accounts'} />,
description: description: (
'Manage your accounts chart to record your transactions and categorise your transactions in parent accounts.', <T
id={
'manage_your_accounts_chart_to_record_your_transactions_and_categories'
}
/>
),
link: '/accounts', link: '/accounts',
}, },
{ {
title: 'Manual journal', title: <T id={'manual_journal'}/>,
description: 'Manage manual journal transactions on accounts, cost centra and projects.', description:<T id={'manage_manual_journal_transactions_on_accounts'}/>,
link: '/manual-journals', link: '/manual-journals',
}, },
{ {
title: 'Expenses', title: <T id={'expenses'}/>,
description: description:<T id={'track_your_indirect_expenses_under_specific_categories'}/>,
'Track your indirect expenses under specific categories such as payroll, rent.',
link: '/expenses', link: '/expenses',
}, },
{ {
title: 'Financial statements', title: <T id={'financial_statements'}/>,
description: description:<T id={'show_financial_reports_about_your_organization'}/>,
'Show financial reports about your organization to summarize your businesss financial performance.',
link: '/financial-reports', link: '/financial-reports',
}, },
], ],
@@ -100,20 +102,18 @@ export const productsServices = [
sectionTitle: <T id={'products_services_inventory'} />, sectionTitle: <T id={'products_services_inventory'} />,
shortcuts: [ shortcuts: [
{ {
title: 'Products & Services', title: <T id={'products_services'}/>,
description: description:<T id={'manage_your_products_inventory_or_non_inventory'}/>,
'Manage your products (inventory or non-inventory) and services and place them into categories.',
link: '/items', link: '/items',
}, },
{ {
title: 'Products & Services Categories', title: <T id={'products_services_categories'}/>,
description: description:<T id={'group_your_products_and_service'}/>,
'Group your products and service into different categories.',
link: 'items/categories', link: 'items/categories',
}, },
{ {
title: 'Inventory Adjustments', title: <T id={'inventory_adjustments'}/>,
description: 'Manage your inventory adjustment of inventory items.', description: <T id={'manage_your_inventory_adjustment_of_inventory_items'}/>,
link: '/inventory-adjustments', link: '/inventory-adjustments',
}, },
], ],

View File

@@ -1,102 +1,105 @@
import React from 'react';
import intl from 'react-intl-universal';
export default [ export default [
{ {
shortcut_key: 'Shift + I', shortcut_key: 'Shift + I',
description: 'Jump to the invoices.', description: intl.get('jump_to_the_invoices'),
}, },
{ {
shortcut_key: 'Shift + E', shortcut_key: 'Shift + E',
description: 'Jump to the estimates.', description: intl.get('jump_to_the_estimates'),
}, },
{ {
shortcut_key: 'Shift + R', shortcut_key: 'Shift + R',
description: 'Jump to the receipts.', description: intl.get('jump_to_the_receipts'),
}, },
{ {
shortcut_key: 'Shift + X', shortcut_key: 'Shift + X',
description: 'Jump to the expenses.', description: intl.get('jump_to_the_expenses'),
}, },
{ {
shortcut_key: 'Shift + C', shortcut_key: 'Shift + C',
description: 'Jump to the customers.', description: intl.get('jump_to_the_customers'),
}, },
{ {
shortcut_key: 'Shift + V', shortcut_key: 'Shift + V',
description: 'Jump to the vendors.', description: intl.get('jump_to_the_vendors'),
}, },
{ {
shortcut_key: 'Shift + A', shortcut_key: 'Shift + A',
description: 'Jump to the Chart of Accounts.', description: intl.get('jump_to_the_chart_of_accounts'),
}, },
{ {
shortcut_key: 'Shift + B', shortcut_key: 'Shift + B',
description: 'Jump to the bills.', description: intl.get('jump_to_the_bills'),
}, },
{ {
shortcut_key: 'Shift + M', shortcut_key: 'Shift + M',
description: 'Jump to the Manual Journals.', description: intl.get('jump_to_the_manual_journals'),
}, },
{ {
shortcut_key: 'Shift + W', shortcut_key: 'Shift + W',
description: 'Jump to the items.', description: intl.get('jump_to_the_items'),
}, },
{ {
shortcut_key: 'Shift + 1', shortcut_key: 'Shift + 1',
description: 'Jump to the Balance Sheet.', description: intl.get('jump_to_the_balance_sheet'),
}, },
{ {
shortcut_key: 'Shift + 2', shortcut_key: 'Shift + 2',
description: 'Jump to the Profit Loss Sheet.', description: intl.get('jump_to_the_profit_loss_sheet'),
}, },
{ {
shortcut_key: 'Shift + 3', shortcut_key: 'Shift + 3',
description: 'Jump to the Journal Sheet.', description: intl.get('jump_to_the_journal_sheet'),
}, },
{ {
shortcut_key: 'Shift + 4', shortcut_key: 'Shift + 4',
description: 'Jump to the General Ledger Sheet.', description: intl.get('jump_to_the_general_ledger_sheet'),
}, },
{ {
shortcut_key: 'Shift + 5', shortcut_key: 'Shift + 5',
description: 'Jump to the Trial Balance Sheet.', description: intl.get('jump_to_the_trial_balance_sheet'),
}, },
{ {
shortcut_key: 'Ctrl + Shift + I ', shortcut_key: 'Ctrl + Shift + I ',
description: 'Create a new invoice .', description: intl.get('create_a_new_invoice'),
}, },
{ {
shortcut_key: 'Ctrl + Shift + E ', shortcut_key: 'Ctrl + Shift + E ',
description: 'Create a new estimate .', description: intl.get('create_a_new_estimate'),
}, },
{ {
shortcut_key: 'Ctrl + Shift + R ', shortcut_key: 'Ctrl + Shift + R ',
description: 'Create a new receipt .', description: intl.get('create_a_new_receipt'),
}, },
{ {
shortcut_key: 'Ctrl + Shift + X ', shortcut_key: 'Ctrl + Shift + X ',
description: 'Create a new expense.', description: intl.get('create_a_new_expense'),
}, },
{ {
shortcut_key: 'Ctrl + Shift + C ', shortcut_key: 'Ctrl + Shift + C ',
description: 'Create a new customer.', description: intl.get('create_a_new_customer'),
}, },
{ {
shortcut_key: 'Ctrl + Shift + V ', shortcut_key: 'Ctrl + Shift + V ',
description: 'Create a new vendor.', description: intl.get('create_a_new_vendor'),
}, },
{ {
shortcut_key: 'Ctrl + Shift + B ', shortcut_key: 'Ctrl + Shift + B ',
description: 'Create a new bill.', description: intl.get('create_a_new_bill'),
}, },
{ {
shortcut_key: 'Ctrl + Shift + M ', shortcut_key: 'Ctrl + Shift + M ',
description: 'Create a new Make Journal.', description: intl.get('create_a_new_journal'),
}, },
{ {
shortcut_key: 'Ctrl + Shift + W ', shortcut_key: 'Ctrl + Shift + W ',
description: 'Create a new item.', description: intl.get('create_a_new_item'),
}, },
{ {
shortcut_key: 'Ctrl + / ', shortcut_key: 'Ctrl + / ',
description: 'Close and open sidebar .', description: intl.get('close_and_open_sidebar'),
}, },
]; ];

View File

@@ -1,6 +1,6 @@
import intl from 'react-intl-universal';
export default [ export default [
{ name: 'English', value: 'en' }, { name: intl.get('english'), value: 'en' },
{ name: 'Arabic', value: 'ar' }, { name: intl.get('arabic'), value: 'ar' },
]; ];

View File

@@ -1,7 +1,9 @@
import intl from 'react-intl-universal';
export const moneyFormat = [ export const moneyFormat = [
{ key: 'total', text: 'Total rows' }, { key: 'total', text: intl.get('total_rows') },
{ key: 'always', text: 'Always' }, { key: 'always', text: intl.get('always') },
{ key: 'none', text: 'None' }, { key: 'none', text: intl.get('none') },
]; ];
export const negativeFormat = [ export const negativeFormat = [

View File

@@ -1,8 +1,10 @@
export default [ import intl from 'react-intl-universal';
{ path: 'invoices/new', name: 'Sale invoice' },
{ path: 'bills//new', name: 'Purchase invoice' }, export const getQuickNewActions = () => [
{ path: 'make-journal-entry', name: 'Manual journal' }, { path: 'invoices/new', name: intl.get('sale_invoice') },
{ path: 'expenses/new', name: 'Expense' }, { path: 'bills//new', name: intl.get('purchase_invoice') },
{ path: 'customers/new', name: 'Customer' }, { path: 'make-journal-entry', name: intl.get('manual_journal') },
{ path: 'vendors/new', name: 'Vendor' }, { path: 'expenses/new', name: intl.get('expense') },
{ path: 'customers/new', name: intl.get('customer') },
{ path: 'vendors/new', name: intl.get('vendor') },
]; ];

View File

@@ -1,16 +1,16 @@
import intl from 'react-intl-universal';
export const getSetupWizardSteps = () => [
export const registerWizardSteps = [
{ {
label: 'payment_or_trial', label: intl.get('Plans & Payment'),
}, },
{ {
label: 'initializing', label: intl.get('Initializing'),
}, },
{ {
label: 'getting_started', label: intl.get('Getting started'),
}, },
{ {
label: 'Congratulations', label: intl.get('Congratulations'),
}, },
]; ];

View File

@@ -2,7 +2,7 @@ import React, { useMemo, useCallback, useState } from 'react';
import { omit } from 'lodash'; import { omit } from 'lodash';
import { MenuItem, Button } from '@blueprintjs/core'; import { MenuItem, Button } from '@blueprintjs/core';
import MultiSelect from 'components/MultiSelect'; import MultiSelect from 'components/MultiSelect';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
export default function AccountsMultiSelect({ accounts, onAccountSelected }) { export default function AccountsMultiSelect({ accounts, onAccountSelected }) {
const [selectedAccounts, setSelectedAccounts] = useState({}); const [selectedAccounts, setSelectedAccounts] = useState({});
@@ -56,7 +56,7 @@ export default function AccountsMultiSelect({ accounts, onAccountSelected }) {
return ( return (
<MultiSelect <MultiSelect
items={accounts} items={accounts}
noResults={<MenuItem disabled={true} text="No results." />} noResults={<MenuItem disabled={true} text={<T id={'no_results'} />} />}
itemRenderer={accountItem} itemRenderer={accountItem}
popoverProps={{ minimal: true }} popoverProps={{ minimal: true }}
filterable={true} filterable={true}

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useState, useEffect, useMemo } from 'react'; import React, { useCallback, useState, useEffect, useMemo } from 'react';
import { MenuItem, Button } from '@blueprintjs/core'; import { MenuItem, Button } from '@blueprintjs/core';
import { Select } from '@blueprintjs/select'; import { Select } from '@blueprintjs/select';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import classNames from 'classnames'; import classNames from 'classnames';
import { filterAccountsByQuery } from './utils'; import { filterAccountsByQuery } from './utils';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';

View File

@@ -1,11 +1,12 @@
import React, { useState, useCallback, useEffect, useMemo } from 'react'; import React, { useState, useCallback, useEffect, useMemo } from 'react';
import { MenuItem } from '@blueprintjs/core'; import { MenuItem } from '@blueprintjs/core';
import { Suggest } from '@blueprintjs/select'; import { Suggest } from '@blueprintjs/select';
import intl from 'react-intl-universal';
import classNames from 'classnames'; import classNames from 'classnames';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { filterAccountsByQuery } from './utils'; import { filterAccountsByQuery } from './utils';
/** /**
@@ -15,7 +16,7 @@ export default function AccountsSuggestField({
accounts, accounts,
initialAccountId, initialAccountId,
selectedAccountId, selectedAccountId,
defaultSelectText = 'Select account', defaultSelectText = intl.formatMessage({ id: 'select_account' }),
popoverFill = false, popoverFill = false,
onAccountSelected, onAccountSelected,

View File

@@ -1,41 +1,54 @@
import React from 'react'; import React from 'react';
import { RawIntlProvider } from 'react-intl';
import { Router, Switch, Route } from 'react-router'; import { Router, Switch, Route } from 'react-router';
import { createBrowserHistory } from 'history'; import { createBrowserHistory } from 'history';
import { QueryClientProvider, QueryClient } from 'react-query'; import { QueryClientProvider, QueryClient } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools'; import { ReactQueryDevtools } from 'react-query/devtools';
import 'style/App.scss'; import 'style/App.scss';
import 'moment/locale/ar-ly';
import 'moment/locale/es-us'
import AppIntlLoader from './AppIntlLoader';
import PrivateRoute from 'components/Guards/PrivateRoute'; import PrivateRoute from 'components/Guards/PrivateRoute';
import Authentication from 'components/Authentication';
import DashboardPrivatePages from 'components/Dashboard/PrivatePages';
import GlobalErrors from 'containers/GlobalErrors/GlobalErrors'; import GlobalErrors from 'containers/GlobalErrors/GlobalErrors';
import intl from 'services/intl'; import DashboardPrivatePages from 'components/Dashboard/PrivatePages';
import Authentication from 'components/Authentication';
function App({ locale }) { // Query client config.
const history = createBrowserHistory(); const queryConfig = {
const queryConfig = {
defaultOptions: { defaultOptions: {
queries: { queries: {
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
staleTime: 30000, staleTime: 30000,
}, },
}, },
}; };
// Global fetch query.
function GlobalFetchQuery({
children
}) {
window.localStorage.setItem('lang', 'en');
return children
}
/**
* Core application.
*/
function App({ locale }) {
const history = createBrowserHistory();
// Query client.
const queryClient = new QueryClient(queryConfig); const queryClient = new QueryClient(queryConfig);
return ( return (
<RawIntlProvider value={intl}>
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<GlobalFetchQuery>
<AppIntlLoader>
<div className="App"> <div className="App">
<Router history={history}> <Router history={history}>
<Switch> <Switch>
<Route path={'/auth'}> <Route path={'/auth'} component={Authentication} />
<Authentication />
</Route>
<Route path={'/'}> <Route path={'/'}>
<PrivateRoute component={DashboardPrivatePages} /> <PrivateRoute component={DashboardPrivatePages} />
</Route> </Route>
@@ -44,10 +57,11 @@ function App({ locale }) {
<GlobalErrors /> <GlobalErrors />
</div> </div>
</AppIntlLoader>
</GlobalFetchQuery>
<ReactQueryDevtools initialIsOpen /> <ReactQueryDevtools initialIsOpen />
</QueryClientProvider> </QueryClientProvider>
</RawIntlProvider>
); );
} }

View File

@@ -0,0 +1,95 @@
import React from 'react';
import moment from 'moment';
import { setLocale } from 'yup';
import intl from 'react-intl-universal';
import { find } from 'lodash';
import rtlDetect from 'rtl-detect';
import DashboardLoadingIndicator from 'components/Dashboard/DashboardLoadingIndicator';
const SUPPORTED_LOCALES = [
{ name: 'English', value: 'en' },
{ name: 'العربية', value: 'ar-ly' },
];
/**
* Retrieve the current local.
*/
function getCurrentLocal() {
let currentLocale = intl.determineLocale({
urlLocaleKey: 'lang',
cookieLocaleKey: 'lang',
localStorageLocaleKey: 'lang',
});
if (!find(SUPPORTED_LOCALES, { value: currentLocale })) {
currentLocale = 'en';
}
return currentLocale;
}
/**
* Loads the localization data of the given locale.
*/
function loadLocales(currentLocale) {
return import(`../lang/${currentLocale}/index.json`);
}
function loadYupLocales(currentLocale) {
return import(`../lang/${currentLocale}/locale`);
}
/**
* Modifies the html document direction to RTl if it was rtl-language.
*/
function useDocumentDirectionModifier(locale) {
React.useEffect(() => {
const isRTL = rtlDetect.isRtlLang(locale);
if (isRTL) {
const htmlDocument = document.querySelector('html');
htmlDocument.setAttribute('dir', 'rtl');
htmlDocument.setAttribute('lang', locale);
}
}, []);
}
/**
* Application Intl loader.
*/
export default function AppIntlLoader({ children }) {
const [isLoading, setIsLoading] = React.useState(true);
const currentLocale = getCurrentLocal();
// Modifies the html document direction
useDocumentDirectionModifier(currentLocale);
React.useEffect(() => {
// Lodas the locales data file.
loadLocales(currentLocale)
.then((results) => {
return intl.init({
currentLocale,
locales: {
[currentLocale]: results,
},
});
})
.then(() => {
moment.locale(currentLocale);
setIsLoading(false);
});
}, [currentLocale, setIsLoading]);
React.useEffect(() => {
loadYupLocales(currentLocale)
.then(({ locale }) => {
setLocale(locale);
})
.then(() => {});
}, [currentLocale]);
return (
<DashboardLoadingIndicator isLoading={isLoading}>
{children}
</DashboardLoadingIndicator>
);
}

View File

@@ -3,7 +3,7 @@ import { Redirect, Route, Switch, Link, useLocation } from 'react-router-dom';
import BodyClassName from 'react-body-classname'; import BodyClassName from 'react-body-classname';
import { TransitionGroup, CSSTransition } from 'react-transition-group'; import { TransitionGroup, CSSTransition } from 'react-transition-group';
import authenticationRoutes from 'routes/authentication'; import authenticationRoutes from 'routes/authentication';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import Icon from 'components/Icon'; import Icon from 'components/Icon';
import { useIsAuthenticated } from 'hooks/state'; import { useIsAuthenticated } from 'hooks/state';
@@ -32,6 +32,7 @@ export default function AuthenticationWrapper({ ...rest }) {
> >
<T id={'go_to_bigcapital_com'} /> <T id={'go_to_bigcapital_com'} />
</a> </a>
<div class="authentication-page__form-wrapper"> <div class="authentication-page__form-wrapper">
<div class="authentication-insider"> <div class="authentication-insider">
<div className={'authentication-insider__logo-section'}> <div className={'authentication-insider__logo-section'}>

View File

@@ -1,5 +1,5 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { ListSelect } from 'components'; import { ListSelect } from 'components';
import { MenuItem } from '@blueprintjs/core'; import { MenuItem } from '@blueprintjs/core';
import { saveInvoke } from 'utils'; import { saveInvoke } from 'utils';

View File

@@ -1,5 +1,7 @@
import React, { useCallback, useState, useEffect, useMemo } from 'react'; import React, { useCallback, useState, useEffect, useMemo } from 'react';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { MenuItem, Button } from '@blueprintjs/core'; import { MenuItem, Button } from '@blueprintjs/core';
import { Select } from '@blueprintjs/select'; import { Select } from '@blueprintjs/select';
import classNames from 'classnames'; import classNames from 'classnames';
@@ -14,7 +16,7 @@ export default function ContactSelecetList({
onContactSelected, onContactSelected,
popoverFill = false, popoverFill = false,
disabled = false, disabled = false,
buttonProps buttonProps,
}) { }) {
const contacts = useMemo( const contacts = useMemo(
() => () =>
@@ -79,7 +81,7 @@ export default function ContactSelecetList({
return ( return (
<Select <Select
items={contacts} items={contacts}
noResults={<MenuItem disabled={true} text="No results." />} noResults={<MenuItem disabled={true} text={<T id={'no_results'} />} />}
itemRenderer={handleContactRenderer} itemRenderer={handleContactRenderer}
itemPredicate={filterContacts} itemPredicate={filterContacts}
filterable={true} filterable={true}
@@ -89,6 +91,9 @@ export default function ContactSelecetList({
className={classNames(CLASSES.FORM_GROUP_LIST_SELECT, { className={classNames(CLASSES.FORM_GROUP_LIST_SELECT, {
[CLASSES.SELECT_LIST_FILL_POPOVER]: popoverFill, [CLASSES.SELECT_LIST_FILL_POPOVER]: popoverFill,
})} })}
inputProps={{
placeholder: intl.get('filter_')
}}
> >
<Button <Button
disabled={disabled} disabled={disabled}

View File

@@ -2,7 +2,8 @@ import React, { useMemo, useCallback, useState } from 'react';
import { MenuItem, Button } from '@blueprintjs/core'; import { MenuItem, Button } from '@blueprintjs/core';
import { omit } from 'lodash'; import { omit } from 'lodash';
import MultiSelect from 'components/MultiSelect'; import MultiSelect from 'components/MultiSelect';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
export default function ContactsMultiSelect({ export default function ContactsMultiSelect({
contacts, contacts,
@@ -31,9 +32,10 @@ export default function ContactsMultiSelect({
[isContactSelect], [isContactSelect],
); );
const countSelected = useMemo(() => Object.values(selectedContacts).length, [ const countSelected = useMemo(
selectedContacts, () => Object.values(selectedContacts).length,
]); [selectedContacts],
);
const onContactSelect = useCallback( const onContactSelect = useCallback(
({ id }) => { ({ id }) => {
@@ -50,18 +52,13 @@ export default function ContactsMultiSelect({
setSelectedContacts({ ...selected }); setSelectedContacts({ ...selected });
onContactSelected && onContactSelected(selected); onContactSelected && onContactSelected(selected);
}, },
[ [setSelectedContacts, selectedContacts, isContactSelect, onContactSelected],
setSelectedContacts,
selectedContacts,
isContactSelect,
onContactSelected,
],
); );
return ( return (
<MultiSelect <MultiSelect
items={contacts} items={contacts}
noResults={<MenuItem disabled={true} text="No results." />} noResults={<MenuItem disabled={true} text={<T id={'no_results'} />} />}
itemRenderer={contactRenderer} itemRenderer={contactRenderer}
popoverProps={{ minimal: true }} popoverProps={{ minimal: true }}
filterable={true} filterable={true}
@@ -69,11 +66,9 @@ export default function ContactsMultiSelect({
> >
<Button <Button
text={ text={
countSelected === 0 ? ( countSelected === 0
defaultText ? defaultText
) : ( : intl.get('selected_customers', { count: countSelected })
<T id={'selected_customers'} values={{ count: countSelected }} />
)
} }
{...buttonProps} {...buttonProps}
/> />

View File

@@ -2,15 +2,16 @@ import React, { useCallback, useState, useEffect, useMemo } from 'react';
import { MenuItem } from '@blueprintjs/core'; import { MenuItem } from '@blueprintjs/core';
import { Suggest } from '@blueprintjs/select'; import { Suggest } from '@blueprintjs/select';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import classNames from 'classnames'; import classNames from 'classnames';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
import intl from 'react-intl-universal';
export default function ContactsSuggestField({ export default function ContactsSuggestField({
contactsList, contactsList,
initialContactId, initialContactId,
selectedContactId, selectedContactId,
defaultTextSelect = 'Select contact', defaultTextSelect = intl.get('select_contact'),
onContactSelected, onContactSelected,
selectedContactType = [], selectedContactType = [],

View File

@@ -1,5 +1,5 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
import classNames from 'classnames'; import classNames from 'classnames';
import { MenuItem, Button } from '@blueprintjs/core'; import { MenuItem, Button } from '@blueprintjs/core';

View File

@@ -9,7 +9,7 @@ import {
PopoverInteractionKind, PopoverInteractionKind,
Position, Position,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { Icon } from 'components'; import { Icon } from 'components';
/** /**

View File

@@ -1,8 +1,9 @@
import React from 'react'; import React from 'react';
import withBreadcrumbs from 'react-router-breadcrumbs-hoc'; import withBreadcrumbs from 'react-router-breadcrumbs-hoc';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import routes from 'routes/dashboard'; import { getDashboardRoutes } from 'routes/dashboard';
import { If, Icon } from 'components'; import { If, Icon } from 'components';
import { FormattedMessage as T } from 'components';
import withDashboard from 'containers/Dashboard/withDashboard'; import withDashboard from 'containers/Dashboard/withDashboard';
import { compose } from 'utils'; import { compose } from 'utils';
@@ -23,7 +24,7 @@ function DashboardBackLink({ dashboardBackLink, breadcrumbs }) {
<If condition={dashboardBackLink && crumb}> <If condition={dashboardBackLink && crumb}>
<div class="dashboard__back-link"> <div class="dashboard__back-link">
<a href="#no-link" onClick={handleClick}> <a href="#no-link" onClick={handleClick}>
<Icon icon={'arrow-left'} iconSize={18} /> Back to list. <Icon icon={'arrow-left'} iconSize={18} /> <T id={'back_to_list'} />
</a> </a>
</div> </div>
</If> </If>
@@ -31,7 +32,7 @@ function DashboardBackLink({ dashboardBackLink, breadcrumbs }) {
} }
export default compose( export default compose(
withBreadcrumbs(routes), withBreadcrumbs([]),
withDashboard(({ dashboardBackLink }) => ({ withDashboard(({ dashboardBackLink }) => ({
dashboardBackLink, dashboardBackLink,
})), })),

View File

@@ -6,7 +6,7 @@ import {
Boundary, Boundary,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import withBreadcrumbs from 'react-router-breadcrumbs-hoc'; import withBreadcrumbs from 'react-router-breadcrumbs-hoc';
import routes from 'routes/dashboard'; import { getDashboardRoutes } from 'routes/dashboard';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
function DashboardBreadcrumbs({ breadcrumbs }){ function DashboardBreadcrumbs({ breadcrumbs }){
@@ -31,4 +31,4 @@ function DashboardBreadcrumbs({ breadcrumbs }){
) )
} }
export default withBreadcrumbs(routes)(DashboardBreadcrumbs) export default withBreadcrumbs([])(DashboardBreadcrumbs)

View File

@@ -1,12 +1,15 @@
import React from 'react'; import React from 'react';
import { Route, Switch } from 'react-router-dom'; import { Route, Switch } from 'react-router-dom';
import routes from 'routes/dashboard';
import { getDashboardRoutes } from 'routes/dashboard';
import DashboardPage from './DashboardPage'; import DashboardPage from './DashboardPage';
/** /**
* Dashboard content route. * Dashboard content route.
*/ */
export default function DashboardContentRoute() { export default function DashboardContentRoute() {
const routes = getDashboardRoutes();
return ( return (
<Route pathname="/"> <Route pathname="/">
<Switch> <Switch>

View File

@@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { getFooterLinks } from 'config/footerLinks';
import footerLinks from 'config/footerLinks';
import { For } from 'components'; import { For } from 'components';
function FooterLinkItem({ title, link }) { function FooterLinkItem({ title, link }) {
@@ -14,6 +13,8 @@ function FooterLinkItem({ title, link }) {
} }
export default function DashboardFooter() { export default function DashboardFooter() {
const footerLinks = getFooterLinks();
return ( return (
<div class="dashboard__footer"> <div class="dashboard__footer">
<div class="footer-links"> <div class="footer-links">

View File

@@ -9,7 +9,7 @@ import {
Tooltip, Tooltip,
Position, Position,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import DashboardTopbarUser from 'components/Dashboard/TopbarUser'; import DashboardTopbarUser from 'components/Dashboard/TopbarUser';
import DashboardBreadcrumbs from 'components/Dashboard/DashboardBreadcrumbs'; import DashboardBreadcrumbs from 'components/Dashboard/DashboardBreadcrumbs';

View File

@@ -1,5 +1,5 @@
import React, { useRef, useState, useEffect } from 'react'; import React, { useRef, useState, useEffect } from 'react';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Button, Tabs, Tab, Tooltip, Position } from '@blueprintjs/core'; import { Button, Tabs, Tab, Tooltip, Position } from '@blueprintjs/core';
import { useHistory } from 'react-router'; import { useHistory } from 'react-router';

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import routes from 'routes/dashboard'; import { getDashboardRoutes } from 'routes/dashboard';
import withDashboardActions from 'containers/Dashboard/withDashboardActions'; import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import { compose } from 'utils'; import { compose } from 'utils';
@@ -10,6 +10,7 @@ function GlobalHotkeys({
toggleSidebarExpend, toggleSidebarExpend,
}) { }) {
const history = useHistory(); const history = useHistory();
const routes = getDashboardRoutes();
const globalHotkeys = routes const globalHotkeys = routes
.filter(({ hotkey }) => hotkey) .filter(({ hotkey }) => hotkey)

View File

@@ -8,7 +8,7 @@ import {
Popover, Popover,
Position, Position,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { firstLettersArgs } from 'utils'; import { firstLettersArgs } from 'utils';
import { useAuthActions, useAuthUser } from 'hooks/state'; import { useAuthActions, useAuthUser } from 'hooks/state';

View File

@@ -10,6 +10,7 @@ import {
useAsyncDebounce, useAsyncDebounce,
} from 'react-table'; } from 'react-table';
import { useSticky } from 'react-table-sticky'; import { useSticky } from 'react-table-sticky';
import intl from 'react-intl-universal';
import { useUpdateEffect } from 'hooks'; import { useUpdateEffect } from 'hooks';
import { saveInvoke } from 'utils'; import { saveInvoke } from 'utils';
@@ -122,7 +123,7 @@ export default function DataTable(props) {
autoResetFilters, autoResetFilters,
autoResetRowState, autoResetRowState,
...restProps ...restProps,
}, },
useSortBy, useSortBy,
useExpanded, useExpanded,
@@ -181,7 +182,6 @@ export default function DataTable(props) {
); );
} }
DataTable.defaultProps = { DataTable.defaultProps = {
pagination: false, pagination: false,
spinnerProps: { size: 30 }, spinnerProps: { size: 30 },
@@ -209,6 +209,6 @@ DataTable.defaultProps = {
TablePaginationRenderer: TablePagination, TablePaginationRenderer: TablePagination,
TableNoResultsRowRenderer: TableNoResultsRow, TableNoResultsRowRenderer: TableNoResultsRow,
noResults: 'There is no results in the table.', noResults: '',
payload: {}, payload: {},
}; };

View File

@@ -1,6 +1,7 @@
import React, { useRef, useCallback, useMemo } from 'react'; import React, { useRef, useCallback, useMemo } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { useCellAutoFocus } from 'hooks'; import { useCellAutoFocus } from 'hooks';
import intl from 'react-intl-universal';
import AccountsSuggestField from 'components/AccountsSuggestField'; import AccountsSuggestField from 'components/AccountsSuggestField';
@@ -61,6 +62,7 @@ export default function AccountCellRenderer({
filterByTypes={filterAccountsByTypes} filterByTypes={filterAccountsByTypes}
inputProps={{ inputProps={{
inputRef: (ref) => (accountRef.current = ref), inputRef: (ref) => (accountRef.current = ref),
placeholder: intl.get('search'),
}} }}
openOnKeyDown={true} openOnKeyDown={true}
blurOnSelectClose={false} blurOnSelectClose={false}

View File

@@ -4,6 +4,7 @@ import ItemsSuggestField from 'components/ItemsSuggestField';
import classNames from 'classnames'; import classNames from 'classnames';
import { FormGroup, Classes, Intent } from '@blueprintjs/core'; import { FormGroup, Classes, Intent } from '@blueprintjs/core';
import intl from 'react-intl-universal';
import { useCellAutoFocus } from 'hooks'; import { useCellAutoFocus } from 'hooks';
@@ -40,7 +41,7 @@ export default function ItemsListCell({
purchasable={filterPurchasable} purchasable={filterPurchasable}
inputProps={{ inputProps={{
inputRef: (ref) => (fieldRef.current = ref), inputRef: (ref) => (fieldRef.current = ref),
placeholder: 'Enter an item...' placeholder: intl.get('enter_an_item'),
}} }}
openOnKeyDown={true} openOnKeyDown={true}
blurOnSelectClose={false} blurOnSelectClose={false}

View File

@@ -46,6 +46,8 @@ export default function TableCell({
); );
} }
const isRTL = true;
return ( return (
<div <div
{...cell.getCellProps({ {...cell.getCellProps({
@@ -62,7 +64,7 @@ export default function TableCell({
'cell-inner', 'cell-inner',
)} )}
style={{ style={{
paddingLeft: [isRTL ? 'paddingRight' : 'paddingLeft']:
isExpandColumn && expandable isExpandColumn && expandable
? `${depth * expandColumnSpace}rem` ? `${depth * expandColumnSpace}rem`
: '', : '',

View File

@@ -1,4 +1,5 @@
import React, { useContext } from 'react'; import React, { useContext } from 'react';
import intl from 'react-intl-universal';
import TableContext from './TableContext'; import TableContext from './TableContext';
/** /**
@@ -6,12 +7,15 @@ import TableContext from './TableContext';
*/ */
export default function TableNoResultsRow() { export default function TableNoResultsRow() {
const { const {
props: { noResults } props: { noResults },
} = useContext(TableContext); } = useContext(TableContext);
const noResultText =
noResults || intl.get('there_is_no_results_in_the_table');
return ( return (
<div className={'tr no-results'}> <div className={'tr no-results'}>
<div class="td">{ noResults }</div> <div class="td">{noResultText}</div>
</div> </div>
); );
} }

View File

@@ -1,7 +1,8 @@
import React, { useState, useCallback, useEffect } from 'react' import React, { useState, useCallback, useEffect } from 'react';
import { useDropzone } from 'react-dropzone' import { useDropzone } from 'react-dropzone';
import classNames from 'classnames'; import classNames from 'classnames';
import Icon from 'components/Icon'; import Icon from 'components/Icon';
import intl from 'react-intl-universal';
// const initialFile: { // const initialFile: {
// file: ?File, // file: ?File,
@@ -11,7 +12,7 @@ import Icon from 'components/Icon';
// }; // };
export default function Dropzone({ export default function Dropzone({
text = 'Drag/Drop files here or click here', text = intl.get('drag_drop_files_here_or_click_here'),
onDrop, onDrop,
initialFiles = [], initialFiles = [],
onDeleteFile, onDeleteFile,
@@ -21,10 +22,10 @@ export default function Dropzone({
const [files, setFiles] = useState([]); const [files, setFiles] = useState([]);
useEffect(() => { useEffect(() => {
setFiles([ ...initialFiles ]); setFiles([...initialFiles]);
}, [initialFiles]); }, [initialFiles]);
const {getRootProps, getInputProps} = useDropzone({ const { getRootProps, getInputProps } = useDropzone({
accept: 'image/*', accept: 'image/*',
onDrop: (acceptedFiles) => { onDrop: (acceptedFiles) => {
const _files = acceptedFiles.map((file) => ({ const _files = acceptedFiles.map((file) => ({
@@ -33,27 +34,35 @@ export default function Dropzone({
uploaded: false, uploaded: false,
})); }));
setFiles(_files); setFiles(_files);
} },
}); });
const handleRemove = useCallback((index) => { const handleRemove = useCallback(
(index) => {
const deletedFile = files.splice(index, 1); const deletedFile = files.splice(index, 1);
setFiles([...files]); setFiles([...files]);
onDeleteFile && onDeleteFile(deletedFile); onDeleteFile && onDeleteFile(deletedFile);
}, [files, onDeleteFile]); },
[files, onDeleteFile],
);
const thumbs = files.map((file, index) => ( const thumbs = files.map((file, index) => (
<div className={'dropzone-thumb'} key={file.name}> <div className={'dropzone-thumb'} key={file.name}>
<div><img src={file.preview} /></div> <div>
<img src={file.preview} />
</div>
<button onClick={() => handleRemove(index)}> <button onClick={() => handleRemove(index)}>
<Icon icon={'times'} iconSize={12} /> <Icon icon={'times'} iconSize={12} />
</button> </button>
</div> </div>
)); ));
useEffect(() => () => { useEffect(
files.forEach(file => URL.revokeObjectURL(file.preview)); () => () => {
}, [files, onDrop]); files.forEach((file) => URL.revokeObjectURL(file.preview));
},
[files, onDrop],
);
useEffect(() => { useEffect(() => {
onDrop && onDrop(files); onDrop && onDrop(files);
@@ -61,16 +70,14 @@ export default function Dropzone({
return ( return (
<section className={classNames('dropzone-container', className)}> <section className={classNames('dropzone-container', className)}>
{(hint) && <div class="dropzone-hint">{ hint }</div>} {hint && <div class="dropzone-hint">{hint}</div>}
<div {...getRootProps({ className: 'dropzone' })}> <div {...getRootProps({ className: 'dropzone' })}>
<input {...getInputProps()} /> <input {...getInputProps()} />
<p>{ text }</p> <p>{text}</p>
</div> </div>
<div className={'dropzone-thumbs'}> <div className={'dropzone-thumbs'}>{thumbs}</div>
{ thumbs }
</div>
</section> </section>
); );
} }

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { Classes, Icon, H4, Button } from '@blueprintjs/core'; import { Classes, Icon, H4, Button } from '@blueprintjs/core';
import withDrawerActions from 'containers/Drawer/withDrawerActions'; import withDrawerActions from 'containers/Drawer/withDrawerActions';

View File

@@ -1,17 +1,15 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { HTMLSelect, Classes } from '@blueprintjs/core'; import { HTMLSelect, Classes } from '@blueprintjs/core';
import { useIntl } from 'react-intl'; import intl from 'react-intl-universal';
import { getConditionTypeCompatators } from './DynamicFilterCompatators'; import { getConditionTypeCompatators } from './DynamicFilterCompatators';
export default function DynamicFilterCompatatorField({ export default function DynamicFilterCompatatorField({
dataType, dataType,
...restProps ...restProps
}) { }) {
const { formatMessage } = useIntl();
const options = useMemo( const options = useMemo(
() => getConditionTypeCompatators(dataType).map(comp => ({ () => getConditionTypeCompatators(dataType).map(comp => ({
value: comp.value, label: formatMessage({ id: comp.label_id }), value: comp.value, label: intl.get(comp.label_id),
})), })),
[dataType] [dataType]
); );

View File

@@ -10,7 +10,8 @@ import { connect } from 'react-redux';
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import { DateInput } from '@blueprintjs/datetime'; import { DateInput } from '@blueprintjs/datetime';
import classNames from 'classnames'; import classNames from 'classnames';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import moment from 'moment'; import moment from 'moment';
@@ -45,7 +46,7 @@ function DynamicFilterValueField({
onChange, onChange,
inputDebounceWait = 250, inputDebounceWait = 250,
}) { }) {
const { formatMessage } = useIntl();
const [localValue, setLocalValue] = useState(); const [localValue, setLocalValue] = useState();
// Makes `localValue` controlled mode from `value`. // Makes `localValue` controlled mode from `value`.
@@ -185,7 +186,7 @@ function DynamicFilterValueField({
<Choose.Otherwise> <Choose.Otherwise>
<InputGroup <InputGroup
placeholder={formatMessage({ id: 'value' })} placeholder={intl.get('value')}
onChange={handleInputChange} onChange={handleInputChange}
value={localValue} value={localValue}
/> />

View File

@@ -12,7 +12,8 @@ import { isEqual, last } from 'lodash';
import { usePrevious } from 'react-use'; import { usePrevious } from 'react-use';
import Icon from 'components/Icon'; import Icon from 'components/Icon';
import { checkRequiredProperties, uniqueMultiProps } from 'utils'; import { checkRequiredProperties, uniqueMultiProps } from 'utils';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { import {
DynamicFilterValueField, DynamicFilterValueField,
DynamicFilterCompatatorField, DynamicFilterCompatatorField,
@@ -41,7 +42,7 @@ export default function FilterDropdown({
initialCondition, initialCondition,
initialConditions, initialConditions,
}) { }) {
const { formatMessage } = useIntl();
// Fields key -> metadata table. // Fields key -> metadata table.
const fieldsKeyMapped = useMemo(() => const fieldsKeyMapped = useMemo(() =>
@@ -51,10 +52,10 @@ export default function FilterDropdown({
// Conditions options. // Conditions options.
const conditionalsOptions = useMemo( const conditionalsOptions = useMemo(
() => [ () => [
{ value: '&&', label: formatMessage({ id: 'and' }) }, { value: '&&', label: intl.get('and') },
{ value: '||', label: formatMessage({ id: 'or' }) }, { value: '||', label: intl.get('or') },
], ],
[formatMessage], [],
); );
// Resources fileds options for fields options. // Resources fileds options for fields options.
const resourceFieldsOptions = useMemo( const resourceFieldsOptions = useMemo(
@@ -91,7 +92,7 @@ export default function FilterDropdown({
if (values.conditions.length >= 12) { if (values.conditions.length >= 12) {
limitToast = Toaster.show( limitToast = Toaster.show(
{ {
message: formatMessage({ id: 'you_reached_conditions_limit' }), message: intl.get('you_reached_conditions_limit'),
intent: Intent.WARNING, intent: Intent.WARNING,
}, },
limitToast, limitToast,
@@ -102,7 +103,7 @@ export default function FilterDropdown({
defaultFilterCondition defaultFilterCondition
]); ]);
} }
}, [values, setFieldValue, formatMessage, defaultFilterCondition]); }, [values, setFieldValue, defaultFilterCondition]);
// Filtered conditions that filters conditions that don't contain atleast // Filtered conditions that filters conditions that don't contain atleast
// on required fields or fileds keys that not exists. // on required fields or fileds keys that not exists.

View File

@@ -1,7 +1,8 @@
import React, { useMemo, useCallback } from 'react'; import React, { useMemo, useCallback } from 'react';
import moment from 'moment'; import moment from 'moment';
import classnames from 'classnames'; import classnames from 'classnames';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import 'style/pages/FinancialStatements/FinancialSheet.scss'; import 'style/pages/FinancialStatements/FinancialSheet.scss';
@@ -23,7 +24,7 @@ export default function FinancialSheet({
fullWidth = false, fullWidth = false,
currentDate = true, currentDate = true,
}) { }) {
const { formatMessage } = useIntl();
const format = 'DD MMMM YYYY'; const format = 'DD MMMM YYYY';
const formattedFromDate = useMemo(() => moment(fromDate).format(format), [ const formattedFromDate = useMemo(() => moment(fromDate).format(format), [
fromDate, fromDate,
@@ -38,10 +39,10 @@ export default function FinancialSheet({
const nameModifer = name ? `financial-sheet--${name}` : ''; const nameModifer = name ? `financial-sheet--${name}` : '';
const methodsLabels = useMemo( const methodsLabels = useMemo(
() => ({ () => ({
cash: formatMessage({ id: 'cash' }), cash: intl.get('cash'),
accrual: formatMessage({ id: 'accrual' }), accrual: intl.get('accrual'),
}), }),
[formatMessage], [],
); );
const getBasisLabel = useCallback((b) => methodsLabels[b], [methodsLabels]); const getBasisLabel = useCallback((b) => methodsLabels[b], [methodsLabels]);
const basisLabel = useMemo(() => getBasisLabel(basis), [ const basisLabel = useMemo(() => getBasisLabel(basis), [

View File

@@ -0,0 +1,9 @@
import intl from 'react-intl-universal';
export function FormattedMessage({ id }) {
return intl.get(id);
}
export function FormattedHTMLMessage({ ...args }) {
return intl.formatHTMLMessage({ ...args })
}

View File

@@ -68,7 +68,7 @@ function ItemsListField({
return ( return (
<ListSelect <ListSelect
items={filteredItems} items={filteredItems}
noResults={<MenuItem disabled={true} text="No results." />} noResults={<MenuItem disabled={true} text={<T id={'no_results'} />} />}
itemRenderer={itemRenderer} itemRenderer={itemRenderer}
itemPredicate={filterItem} itemPredicate={filterItem}
popoverProps={{ minimal: true }} popoverProps={{ minimal: true }}

View File

@@ -5,7 +5,7 @@ import { CLASSES } from 'common/classes';
import { Suggest } from '@blueprintjs/select'; import { Suggest } from '@blueprintjs/select';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
export default function ItemsSuggestField({ export default function ItemsSuggestField({
items, items,

View File

@@ -1,7 +1,7 @@
import React, { useState, useMemo, useEffect } from 'react'; import React, { useState, useMemo, useEffect } from 'react';
import { Button, MenuItem } from '@blueprintjs/core'; import { Button, MenuItem } from '@blueprintjs/core';
import { Select } from '@blueprintjs/select'; import { Select } from '@blueprintjs/select';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from './FormattedMessage';
import classNames from 'classnames'; import classNames from 'classnames';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';

View File

@@ -3,7 +3,7 @@ import { FastField, ErrorMessage } from 'formik';
import { FormGroup, Checkbox, Switch } from '@blueprintjs/core'; import { FormGroup, Checkbox, Switch } from '@blueprintjs/core';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
import { ListSelect } from 'components'; import { ListSelect } from 'components';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { inputIntent } from 'utils'; import { inputIntent } from 'utils';
import { import {
moneyFormat, moneyFormat,
@@ -73,7 +73,7 @@ export default function NumberFormatFields({}) {
label={<T id={'money_format'} />} label={<T id={'money_format'} />}
helperText={<ErrorMessage name="formatMoney" />} helperText={<ErrorMessage name="formatMoney" />}
intent={inputIntent({ error, touched })} intent={inputIntent({ error, touched })}
className={classNames(CLASSES.FILL)} className={classNames('form-group--money-format', CLASSES.FILL)}
> >
<ListSelect <ListSelect
items={moneyFormat} items={moneyFormat}

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { useFormikContext } from 'formik'; import { useFormikContext } from 'formik';
import { Button, Classes, Intent } from '@blueprintjs/core'; import { Button, Classes, Intent } from '@blueprintjs/core';
import classNames from 'classnames'; import classNames from 'classnames';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
/** /**
* Number format footer. * Number format footer.

View File

@@ -1,7 +1,8 @@
import React, { useReducer, useEffect } from 'react'; import React, { useReducer, useEffect } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { Button, ButtonGroup, Intent, HTMLSelect } from '@blueprintjs/core'; import { Button, ButtonGroup, Intent, HTMLSelect } from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { range } from 'lodash'; import { range } from 'lodash';
import { Icon } from 'components'; import { Icon } from 'components';
@@ -187,7 +188,7 @@ function Pagination({
</div> </div>
<div class="pagination__pagesize-control"> <div class="pagination__pagesize-control">
Page size <T id={'page_size'} />
<HTMLSelect <HTMLSelect
minimal={true} minimal={true}
options={pageSizesOptions} options={pageSizesOptions}
@@ -204,14 +205,11 @@ function Pagination({
</div> </div>
<div class="pagination__info"> <div class="pagination__info">
<T {intl.get('showing_current_page_to_total', {
id={'showing_current_page_to_total'}
values={{
currentPage: state.currentPage, currentPage: state.currentPage,
totalPages: state.totalPages, totalPages: state.totalPages,
total: total, total: total,
}} })}
/>
</div> </div>
</div> </div>
); );

View File

@@ -1,7 +1,7 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { MenuItem } from '@blueprintjs/core'; import { MenuItem } from '@blueprintjs/core';
import ListSelect from 'components/ListSelect'; import ListSelect from 'components/ListSelect';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
function PaymentReceiveListField({ function PaymentReceiveListField({
invoices, invoices,
@@ -23,7 +23,7 @@ function PaymentReceiveListField({
return ( return (
<ListSelect <ListSelect
item={invoices} item={invoices}
noResults={<MenuItem disabled={true} text="No results." />} noResults={<MenuItem disabled={true} text={<T id={'no_results'} />} />}
itemRenderer={handleInvoiceRenderer} itemRenderer={handleInvoiceRenderer}
popoverProps={{ minimal: true }} popoverProps={{ minimal: true }}
onItemSelect={onInvoiceSelect} onItemSelect={onInvoiceSelect}

View File

@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import { Menu, MenuItem, MenuDivider } from '@blueprintjs/core'; import { Menu, MenuItem, MenuDivider } from '@blueprintjs/core';
import { useHistory, useLocation } from 'react-router-dom'; import { useHistory, useLocation } from 'react-router-dom';
import { FormattedMessage as T } from 'components';
import preferencesMenu from 'config/preferencesMenu'; import preferencesMenu from 'config/preferencesMenu';
import PreferencesSidebarContainer from './PreferencesSidebarContainer'; import PreferencesSidebarContainer from './PreferencesSidebarContainer';
@@ -32,7 +33,7 @@ export default function PreferencesSidebar() {
return ( return (
<PreferencesSidebarContainer> <PreferencesSidebarContainer>
<div class="preferences-sidebar__head"> <div class="preferences-sidebar__head">
<h2>Preferences</h2> <h2>{<T id={'preferences'} />}</h2>
</div> </div>
<Menu className="preferences-sidebar__menu">{items}</Menu> <Menu className="preferences-sidebar__menu">{items}</Menu>

View File

@@ -1,20 +1,27 @@
import React from 'react'; import React from 'react';
import { import intl from 'react-intl-universal';
ListSelect,
} from 'components';
export default function SalutationList({ import { ListSelect } from 'components';
...restProps
}) { export default function SalutationList({ ...restProps }) {
const saluations = ['Mr.', 'Mrs.', 'Ms.', 'Miss', 'Dr.']; const saluations = [
const items = saluations.map((saluation) => ({ key: saluation, label: saluation })); intl.get('mr'),
intl.get('mrs'),
intl.get('ms'),
intl.get('miss'),
intl.get('dr'),
];
const items = saluations.map((saluation) => ({
key: saluation,
label: saluation,
}));
return ( return (
<ListSelect <ListSelect
items={items} items={items}
selectedItemProp={'key'} selectedItemProp={'key'}
textProp={'label'} textProp={'label'}
defaultText={'Salutation'} defaultText={intl.get('salutation')}
filterable={false} filterable={false}
{...restProps} {...restProps}
/> />

View File

@@ -3,6 +3,7 @@ import Money from './Money';
import Icon from './Icon'; import Icon from './Icon';
import Choose from './Utils/Choose'; import Choose from './Utils/Choose';
import For from './Utils/For'; import For from './Utils/For';
import { FormattedMessage, FormattedHTMLMessage } from './FormattedMessage';
import ListSelect from './ListSelect'; import ListSelect from './ListSelect';
import FinancialStatement from './FinancialStatement'; import FinancialStatement from './FinancialStatement';
import DynamicFilterValueField from './DynamicFilter/DynamicFilterValueField'; import DynamicFilterValueField from './DynamicFilter/DynamicFilterValueField';
@@ -58,14 +59,19 @@ import MaterialProgressBar from './MaterialProgressBar';
const Hint = FieldHint; const Hint = FieldHint;
const T = FormattedMessage;
export { export {
If, If,
For, For,
Money, Choose,
Icon, Icon,
FormattedMessage,
FormattedHTMLMessage,
T,
Money,
ListSelect, ListSelect,
FinancialStatement, FinancialStatement,
Choose,
DynamicFilterValueField, DynamicFilterValueField,
DynamicFilterCompatatorField, DynamicFilterCompatatorField,
MODIFIER, MODIFIER,

View File

@@ -1,47 +1,56 @@
import React from 'react';
import { FormattedMessage as T } from 'components';
export const financialReportMenus = [ export const financialReportMenus = [
{ {
sectionTitle: 'Financial Accounting', sectionTitle: <T id={'financial_accounting'} />,
reports: [ reports: [
{ {
title: 'Balance Sheet Report', title: <T id={'balance_sheet_report'} />,
desc: desc: (
"Reports a company's assets, liabilities and shareholders' equity at a specific point in time with comparison period(s).", <T id={'reports_a_company_s_assets_liabilities_and_shareholders'} />
),
link: '/financial-reports/balance-sheet', link: '/financial-reports/balance-sheet',
}, },
{ {
title: 'Trial Balance Sheet', title: <T id={'trial_balance_sheet'} />,
desc: desc: (
'Summarizes the credit and debit balance of each account in your chart of accounts at a specific point in time.', <T id={'summarizes_the_credit_and_debit_balance_of_each_account'} />
),
link: '/financial-reports/trial-balance-sheet', link: '/financial-reports/trial-balance-sheet',
}, },
{ {
title: 'Journal Report', title: <T id={'profit_loss_report'} />,
desc: desc: <T id={'reports_the_revenues_costs_and_expenses'} />,
'The debit and credit entries of system transactions, sorted by date.',
link: '/financial-reports/journal-sheet',
},
{
title: 'Profit/Loss Report',
desc:
'Reports the revenues, costs and expenses incurred during a specific point in time with comparison period(s).',
link: '/financial-reports/profit-loss-sheet', link: '/financial-reports/profit-loss-sheet',
}, },
{ {
title: 'General Ledger Report', title: <T id={'cash_flow_statement'} />,
desc: desc: (
'Reports every transaction going in and out of your accounts and organized by accounts and date to monitoring activity of accounts.', <T id={'reports_inflow_and_outflow_of_cash_and_cash_equivalents'} />
),
link: '/financial-reports/cash-flow',
},
{
title: <T id={'journal_report'} />,
desc: <T id={'the_debit_and_credit_entries_of_system_transactions'} />,
link: '/financial-reports/journal-sheet',
},
{
title: <T id={'general_ledger_report'} />,
desc: <T id={'reports_every_transaction_going_in_and_out_of_your'} />,
link: '/financial-reports/general-ledger', link: '/financial-reports/general-ledger',
}, },
{ {
title: 'Receivable Aging Summary', title: <T id={'receivable_aging_summary'} />,
desc: desc: (
'Summarize total unpaid balances of customers invoices with number of days the unpaid invoice is overdue.', <T id={'summarize_total_unpaid_balances_of_customers_invoices'} />
),
link: '/financial-reports/receivable-aging-summary', link: '/financial-reports/receivable-aging-summary',
}, },
{ {
title: 'Payable Aging Summary', title: <T id={'payable_aging_summary'} />,
desc: desc: <T id={'summarize_total_unpaid_balances_of_vendors_purchase'} />,
'Summarize total unpaid balances of vendors purchase invoices with the number of days the unpaid invoice is overdue.',
link: '/financial-reports/payable-aging-summary', link: '/financial-reports/payable-aging-summary',
}, },
], ],
@@ -50,46 +59,86 @@ export const financialReportMenus = [
export const SalesAndPurchasesReportMenus = [ export const SalesAndPurchasesReportMenus = [
{ {
sectionTitle: 'Sales/Purchases Reports', sectionTitle: <T id={'sales_purchases_reports'} />,
reports: [ reports: [
{ {
title: 'Purchases By Items', title: <T id={'purchases_by_items'} />,
desc: desc: (
'Shows the average age of unresolved issues for a project or filter. This helps you see whether your backlog is being kept up to date.', <T
id={
'summarize_the_business_s_purchase_items_quantity_cost_and_average'
}
/>
),
link: '/financial-reports/purchases-by-items', link: '/financial-reports/purchases-by-items',
}, },
{ {
title: 'Sales By Items', title: <T id={'sales_by_items'} />,
desc: desc: (
'Summarize the businesss sold items quantity, income and average income rate of each item during a specific point in time.', <T
id={
'summarize_the_business_s_sold_items_quantity_income_and_average_income_rate'
}
/>
),
link: '/financial-reports/sales-by-items', link: '/financial-reports/sales-by-items',
}, },
{ {
title: 'Inventory valuation', title: <T id={'inventory_valuation'} />,
desc: desc: (
'Summarize the businesss purchase items quantity, cost and average cost rate of each item during a specific point in time.', <T
id={
'summarize_the_business_s_purchase_items_quantity_cost_and_average'
}
/>
),
link: '/financial-reports/inventory-valuation', link: '/financial-reports/inventory-valuation',
}, },
{ {
title: 'Customers Balance summary', title: <T id={'customers_balance_summary'} />,
desc: 'Summerize the total amount of each customer owes your business.', desc: (
<T
id={
'summerize_the_total_amount_of_each_customer_owes_your_business'
}
/>
),
link: '/financial-reports/customers-balance-summary', link: '/financial-reports/customers-balance-summary',
}, },
{ {
title: 'Vendors Balance summary', title: <T id={'vendors_balance_summary'} />,
desc: 'Summerize the total amount your business owes each vendor.', desc: (
<T id={'summerize_the_total_amount_your_business_owes_each_vendor'} />
),
link: '/financial-reports/vendors-balance-summary', link: '/financial-reports/vendors-balance-summary',
}, },
{ {
title: 'Customers Transactions', title: <T id={'customers_transactions'} />,
desc: 'Reports every transaction going in and out of each customer.', desc: (
<T
id={'reports_every_transaction_going_in_and_out_of_each_customer'}
/>
),
link: '/financial-reports/transactions-by-customers', link: '/financial-reports/transactions-by-customers',
}, },
{ {
title: 'Vendors Transactions', title: <T id={'vendors_transactions'} />,
desc: 'Reports every transaction going in and out of each vendor/supplier.', desc: (
<T
id={
'reports_every_transaction_going_in_and_out_of_each_vendor_supplier'
}
/>
),
link: '/financial-reports/transactions-by-vendors', link: '/financial-reports/transactions-by-vendors',
}, },
{
title: <T id={'inventory_item_details'} />,
desc: (
<T id={'reports_every_transaction_going_in_and_out_of_your_items'} />
),
link: '/financial-reports/inventory-item-details',
},
], ],
}, },
]; ];

View File

@@ -1,29 +1,28 @@
import intl from 'react-intl-universal';
export const getFooterLinks = () => [
export default [
{ {
title: 'Blog', title: intl.get('blog'),
link: '#', link: '#',
}, },
{ {
title: 'Support', title: intl.get('support'),
link: '#', link: '#',
}, },
{ {
title: 'Status', title: intl.get('service_status'),
link: '#', link: '#',
}, },
{ {
title: 'Pricing', title: intl.get('pricing'),
link: '#', link: '#',
}, },
{ {
title: 'Solution Partner Program', title: intl.get('reseller_partner'),
link: '#', link: '#',
}, },
{ {
title: 'Docs', title: intl.get('docs'),
link: '#', link: '#',
}, },
{ {

View File

@@ -1,5 +1,5 @@
import React from 'react' import React from 'react'
import { FormattedMessage as T} from 'react-intl'; import { FormattedMessage as T } from 'components';
export default [ export default [
{ {

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
export default [ export default [
{ {
@@ -9,14 +9,14 @@ export default [
matchExact: true, matchExact: true,
}, },
{ {
text: 'Sales & inventory', text: <T id={'sales_inventory'} />,
label: true, label: true,
}, },
{ {
text: <T id={'items'} />, text: <T id={'items'} />,
children: [ children: [
{ {
text: <T id={'items_list'} />, text: <T id={'items'} />,
href: '/items', href: '/items',
}, },
{ {
@@ -67,7 +67,7 @@ export default [
newTabHref: '/bills/new', newTabHref: '/bills/new',
}, },
{ {
text: <T id={'payment_made'} />, text: <T id={'payment_mades'} />,
href: '/payment-mades', href: '/payment-mades',
newTabHref: '/payment-mades/new', newTabHref: '/payment-mades/new',
}, },
@@ -100,7 +100,7 @@ export default [
href: '/accounts', href: '/accounts',
}, },
{ {
text: <T id={'manual_journal'} />, text: <T id={'manual_journals'} />,
href: '/manual-journals', href: '/manual-journals',
}, },
{ {

View File

@@ -12,7 +12,7 @@ import {
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import classNames from 'classnames'; import classNames from 'classnames';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { useManualJournalsContext } from './ManualJournalsListProvider'; import { useManualJournalsContext } from './ManualJournalsListProvider';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
@@ -42,9 +42,7 @@ function ManualJournalActionsBar({
}; };
// Handle delete button click. // Handle delete button click.
const handleBulkDelete = () => { const handleBulkDelete = () => {};
};
// Handle tab change. // Handle tab change.
const handleTabChange = (customView) => { const handleTabChange = (customView) => {
@@ -77,7 +75,7 @@ function ManualJournalActionsBar({
className={classNames(Classes.MINIMAL, 'button--filter', { className={classNames(Classes.MINIMAL, 'button--filter', {
'has-active-filters': false, 'has-active-filters': false,
})} })}
text="Filter" text={<T id={'filter'} />}
icon={<Icon icon="filter-16" iconSize={16} />} icon={<Icon icon="filter-16" iconSize={16} />}
/> />
</Popover> </Popover>

View File

@@ -2,17 +2,17 @@ import React from 'react';
import { Button, Intent } from '@blueprintjs/core'; import { Button, Intent } from '@blueprintjs/core';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { EmptyStatus } from 'components'; import { EmptyStatus } from 'components';
import { FormattedMessage as T } from 'components';
export default function ManualJournalsEmptyStatus() { export default function ManualJournalsEmptyStatus() {
const history = useHistory(); const history = useHistory();
return ( return (
<EmptyStatus <EmptyStatus
title={'Create your first journal entries on accounts chart.'} title={<T id={'create_your_first_journal_entries_on_accounts_chart'} />}
description={ description={
<p> <p>
It is a long established fact that a reader will be distracted by the <T id={'it_is_a_long_established_fact_that_a_reader'} />
readable content of a page when looking at its layout.
</p> </p>
} }
action={ action={
@@ -24,11 +24,11 @@ export default function ManualJournalsEmptyStatus() {
history.push('/make-journal-entry'); history.push('/make-journal-entry');
}} }}
> >
Make journal <T id={'make_journal'} />
</Button> </Button>
<Button intent={Intent.NONE} large={true}> <Button intent={Intent.NONE} large={true}>
Learn more <T id={'learn_more'} />
</Button> </Button>
</> </>
} }

View File

@@ -11,11 +11,11 @@ import {
MenuDivider, MenuDivider,
Popover, Popover,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import moment from 'moment'; import moment from 'moment';
import { Choose, Money, If, Icon } from 'components'; import { Choose, Money, If, Icon } from 'components';
import { safeCallback } from 'utils'; import { safeCallback } from 'utils';
import { formatMessage } from 'services/intl'; import intl from 'react-intl-universal';
/** /**
* Amount accessor. * Amount accessor.
@@ -155,24 +155,24 @@ export const ActionsMenu = ({
<Menu> <Menu>
<MenuItem <MenuItem
icon={<Icon icon="reader-18" />} icon={<Icon icon="reader-18" />}
text={formatMessage({ id: 'view_details' })} text={intl.get('view_details')}
onClick={safeCallback(onViewDetails, original)} onClick={safeCallback(onViewDetails, original)}
/> />
<MenuDivider /> <MenuDivider />
<If condition={!original.is_published}> <If condition={!original.is_published}>
<MenuItem <MenuItem
icon={<Icon icon="arrow-to-top" />} icon={<Icon icon="arrow-to-top" />}
text={formatMessage({ id: 'publish_journal' })} text={intl.get('publish_journal')}
onClick={safeCallback(onPublish, original)} onClick={safeCallback(onPublish, original)}
/> />
</If> </If>
<MenuItem <MenuItem
icon={<Icon icon="pen-18" />} icon={<Icon icon="pen-18" />}
text={formatMessage({ id: 'edit_journal' })} text={intl.get('edit_journal')}
onClick={safeCallback(onEdit, original)} onClick={safeCallback(onEdit, original)}
/> />
<MenuItem <MenuItem
text={formatMessage({ id: 'delete_journal' })} text={intl.get('delete_journal')}
icon={<Icon icon="trash-16" iconSize={16} />} icon={<Icon icon="trash-16" iconSize={16} />}
intent={Intent.DANGER} intent={Intent.DANGER}
onClick={safeCallback(onDelete, original)} onClick={safeCallback(onDelete, original)}

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { formatMessage } from 'services/intl'; import intl from 'react-intl-universal';
import moment from 'moment'; import moment from 'moment';
import { import {
NoteAccessor, NoteAccessor,
@@ -16,42 +16,42 @@ export const useManualJournalsColumns = () => {
() => [ () => [
{ {
id: 'date', id: 'date',
Header: formatMessage({ id: 'date' }), Header: intl.get('date'),
accessor: DateAccessor, accessor: DateAccessor,
width: 115, width: 115,
className: 'date', className: 'date',
}, },
{ {
id: 'amount', id: 'amount',
Header: formatMessage({ id: 'amount' }), Header: intl.get('amount'),
accessor: AmountAccessor, accessor: AmountAccessor,
className: 'amount', className: 'amount',
width: 115, width: 115,
}, },
{ {
id: 'journal_number', id: 'journal_number',
Header: formatMessage({ id: 'journal_no' }), Header: intl.get('journal_no'),
accessor: (row) => `#${row.journal_number}`, accessor: (row) => `#${row.journal_number}`,
className: 'journal_number', className: 'journal_number',
width: 100, width: 100,
}, },
{ {
id: 'journal_type', id: 'journal_type',
Header: formatMessage({ id: 'journal_type' }), Header: intl.get('journal_type'),
accessor: 'journal_type', accessor: 'journal_type',
width: 110, width: 110,
className: 'journal_type', className: 'journal_type',
}, },
{ {
id: 'status', id: 'status',
Header: formatMessage({ id: 'publish' }), Header: intl.get('publish'),
accessor: (row) => StatusAccessor(row), accessor: (row) => StatusAccessor(row),
width: 95, width: 95,
className: 'status', className: 'status',
}, },
{ {
id: 'note', id: 'note',
Header: formatMessage({ id: 'note' }), Header: intl.get('note'),
accessor: NoteAccessor, accessor: NoteAccessor,
disableSortBy: true, disableSortBy: true,
width: 85, width: 85,
@@ -59,7 +59,7 @@ export const useManualJournalsColumns = () => {
}, },
{ {
id: 'created_at', id: 'created_at',
Header: formatMessage({ id: 'created_at' }), Header: intl.get('created_at'),
accessor: (r) => moment(r.created_at).format('YYYY MMM DD'), accessor: (r) => moment(r.created_at).format('YYYY MMM DD'),
width: 125, width: 125,
className: 'created_at', className: 'created_at',

View File

@@ -1,5 +1,5 @@
import * as Yup from 'yup'; import * as Yup from 'yup';
import { formatMessage } from 'services/intl'; import intl from 'react-intl-universal';
import { DATATYPES_LENGTH } from 'common/dataTypes'; import { DATATYPES_LENGTH } from 'common/dataTypes';
const Schema = Yup.object().shape({ const Schema = Yup.object().shape({
@@ -7,15 +7,15 @@ const Schema = Yup.object().shape({
.required() .required()
.min(1) .min(1)
.max(DATATYPES_LENGTH.STRING) .max(DATATYPES_LENGTH.STRING)
.label(formatMessage({ id: 'journal_number_' })), .label(intl.get('journal_number_')),
journal_type: Yup.string() journal_type: Yup.string()
.required() .required()
.min(1) .min(1)
.max(DATATYPES_LENGTH.STRING) .max(DATATYPES_LENGTH.STRING)
.label(formatMessage({ id: 'journal_type' })), .label(intl.get('journal_type')),
date: Yup.date() date: Yup.date()
.required() .required()
.label(formatMessage({ id: 'date' })), .label(intl.get('date')),
currency_code: Yup.string().max(3), currency_code: Yup.string().max(3),
publish: Yup.boolean(), publish: Yup.boolean(),
reference: Yup.string().nullable().min(1).max(DATATYPES_LENGTH.STRING), reference: Yup.string().nullable().min(1).max(DATATYPES_LENGTH.STRING),

View File

@@ -9,7 +9,7 @@ import {
Menu, Menu,
MenuItem, MenuItem,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { useFormikContext } from 'formik'; import { useFormikContext } from 'formik';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
import classNames from 'classnames'; import classNames from 'classnames';

View File

@@ -1,7 +1,7 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import { Intent } from '@blueprintjs/core'; import { Intent } from '@blueprintjs/core';
import { useIntl } from 'react-intl'; import intl from 'react-intl-universal';
import { defaultTo, isEmpty, omit } from 'lodash'; import { defaultTo, isEmpty, omit } from 'lodash';
import classNames from 'classnames'; import classNames from 'classnames';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
@@ -48,7 +48,6 @@ function MakeJournalEntriesForm({
submitPayload, submitPayload,
} = useMakeJournalFormContext(); } = useMakeJournalFormContext();
const { formatMessage } = useIntl();
const history = useHistory(); const history = useHistory();
// New journal number. // New journal number.
@@ -92,18 +91,14 @@ function MakeJournalEntriesForm({
// Validate the total credit should be eqials total debit. // Validate the total credit should be eqials total debit.
if (totalCredit !== totalDebit) { if (totalCredit !== totalDebit) {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('should_total_of_credit_and_debit_be_equal'),
id: 'should_total_of_credit_and_debit_be_equal',
}),
intent: Intent.DANGER, intent: Intent.DANGER,
}); });
setSubmitting(false); setSubmitting(false);
return; return;
} else if (totalCredit === 0 || totalDebit === 0) { } else if (totalCredit === 0 || totalDebit === 0) {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('amount_cannot_be_zero_or_empty'),
id: 'amount_cannot_be_zero_or_empty',
}),
intent: Intent.DANGER, intent: Intent.DANGER,
}); });
setSubmitting(false); setSubmitting(false);
@@ -131,12 +126,10 @@ function MakeJournalEntriesForm({
// Handle the request success. // Handle the request success.
const handleSuccess = (errors) => { const handleSuccess = (errors) => {
AppToaster.show({ AppToaster.show({
message: formatMessage( message: intl.get(
{ isNewMode
id: isNewMode
? 'the_journal_has_been_created_successfully' ? 'the_journal_has_been_created_successfully'
: 'the_journal_has_been_edited_successfully', : 'the_journal_has_been_edited_successfully',
},
{ number: values.journal_number }, { number: values.journal_number },
), ),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,

View File

@@ -2,6 +2,7 @@ import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { useFormikContext } from 'formik'; import { useFormikContext } from 'formik';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
import { FormattedMessage as T } from 'components';
import MakeJournalEntriesHeaderFields from './MakeJournalEntriesHeaderFields'; import MakeJournalEntriesHeaderFields from './MakeJournalEntriesHeaderFields';
import { PageFormBigNumber } from 'components'; import { PageFormBigNumber } from 'components';
import { safeSumBy } from 'utils'; import { safeSumBy } from 'utils';
@@ -20,7 +21,7 @@ export default function MakeJournalEntriesHeader() {
<MakeJournalEntriesHeaderFields /> <MakeJournalEntriesHeaderFields />
<PageFormBigNumber <PageFormBigNumber
label={'Due Amount'} label={<T id={'amount'} />}
amount={total} amount={total}
currencyCode={currency_code} currencyCode={currency_code}
/> />

View File

@@ -7,7 +7,7 @@ import {
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { FastField, ErrorMessage } from 'formik'; import { FastField, ErrorMessage } from 'formik';
import { DateInput } from '@blueprintjs/datetime'; import { DateInput } from '@blueprintjs/datetime';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import classNames from 'classnames'; import classNames from 'classnames';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
@@ -131,7 +131,9 @@ function MakeJournalEntriesHeader({
}} }}
tooltip={true} tooltip={true}
tooltipProps={{ tooltipProps={{
content: 'Setting your auto-generated journal number', content: (
<T id={'setting_your_auto_generated_journal_number'} />
),
position: Position.BOTTOM_LEFT, position: Position.BOTTOM_LEFT,
}} }}
/> />

View File

@@ -11,7 +11,7 @@ import {
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { useFormikContext } from 'formik'; import { useFormikContext } from 'formik';
import classNames from 'classnames'; import classNames from 'classnames';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
import { Icon, If } from 'components'; import { Icon, If } from 'components';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';

View File

@@ -3,7 +3,7 @@ import { FastField } from 'formik';
import classNames from 'classnames'; import classNames from 'classnames';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
import { FormGroup, TextArea } from '@blueprintjs/core'; import { FormGroup, TextArea } from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { Postbox, ErrorMessage, Row, Col } from 'components'; import { Postbox, ErrorMessage, Row, Col } from 'components';
import Dragzone from 'components/Dragzone'; import Dragzone from 'components/Dragzone';
import { inputIntent } from 'utils'; import { inputIntent } from 'utils';
@@ -11,7 +11,7 @@ import { inputIntent } from 'utils';
export default function MakeJournalFormFooter() { export default function MakeJournalFormFooter() {
return ( return (
<div className={classNames(CLASSES.PAGE_FORM_FOOTER)}> <div className={classNames(CLASSES.PAGE_FORM_FOOTER)}>
<Postbox title={'Journal details'} defaultOpen={false}> <Postbox title={<T id={'journal_details'} />} defaultOpen={false}>
<Row> <Row>
<Col md={8}> <Col md={8}>
<FastField name={'description'}> <FastField name={'description'}>
@@ -34,7 +34,7 @@ export default function MakeJournalFormFooter() {
initialFiles={[]} initialFiles={[]}
// onDrop={handleDropFiles} // onDrop={handleDropFiles}
// onDeleteFile={handleDeleteFile} // onDeleteFile={handleDeleteFile}
hint={'Attachments: Maxiumum size: 20MB'} hint={<T id={'attachments_maximum'} />}
/> />
</Col> </Col>
</Row> </Row>

View File

@@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import { Intent, Position, Button, Tooltip } from '@blueprintjs/core'; import { Intent, Position, Button, Tooltip } from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import { Icon, Money, Hint } from 'components'; import { Icon, Money, Hint } from 'components';
import { formatMessage } from 'services/intl'; import intl from 'react-intl-universal';
import { import {
AccountsListFieldCell, AccountsListFieldCell,
MoneyFieldCell, MoneyFieldCell,
@@ -30,21 +30,25 @@ export function ContactHeaderCell() {
* Credit header cell. * Credit header cell.
*/ */
export function CreditHeaderCell({ payload: { currencyCode } }) { export function CreditHeaderCell({ payload: { currencyCode } }) {
return formatMessage({ id: 'credit_currency' }, { currency: currencyCode }); return intl.get('credit_currency', { currency: currencyCode });
} }
/** /**
* debit header cell. * debit header cell.
*/ */
export function DebitHeaderCell({ payload: { currencyCode } }) { export function DebitHeaderCell({ payload: { currencyCode } }) {
return formatMessage({ id: 'debit_currency' }, { currency: currencyCode }); return intl.get('debit_currency', { currency: currencyCode });
} }
/** /**
* Account footer cell. * Account footer cell.
*/ */
function AccountFooterCell({ payload: { currencyCode } }) { function AccountFooterCell({ payload: { currencyCode } }) {
return <span>{`Total ${currencyCode} `}</span>; return (
<span>
{intl.get('total_currency', { currency: currencyCode })}
</span>
);
} }
/** /**
@@ -116,7 +120,7 @@ export const useJournalTableEntriesColumns = () => {
sticky: 'left', sticky: 'left',
}, },
{ {
Header: formatMessage({ id: 'account' }), Header: intl.get('account'),
id: 'account_id', id: 'account_id',
accessor: 'account_id', accessor: 'account_id',
Cell: AccountsListFieldCell, Cell: AccountsListFieldCell,
@@ -153,7 +157,7 @@ export const useJournalTableEntriesColumns = () => {
width: 120, width: 120,
}, },
{ {
Header: formatMessage({ id: 'note' }), Header: intl.get('note'),
accessor: 'note', accessor: 'note',
Cell: InputGroupCell, Cell: InputGroupCell,
disableSortBy: true, disableSortBy: true,
@@ -170,6 +174,6 @@ export const useJournalTableEntriesColumns = () => {
width: 45, width: 45,
}, },
], ],
[formatMessage], [],
); );
}; };

View File

@@ -10,7 +10,7 @@ import {
transformToForm, transformToForm,
} from 'utils'; } from 'utils';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
import { formatMessage } from 'services/intl'; import intl from 'react-intl-universal';
import { useFormikContext } from 'formik'; import { useFormikContext } from 'formik';
const ERROR = { const ERROR = {
@@ -118,23 +118,19 @@ export const transformErrors = (resErrors, { setErrors, errors }) => {
if ((error = getError(ERROR.RECEIVABLE_ENTRIES_HAS_NO_CUSTOMERS))) { if ((error = getError(ERROR.RECEIVABLE_ENTRIES_HAS_NO_CUSTOMERS))) {
toastMessages.push( toastMessages.push(
formatMessage({ intl.get('should_select_customers_with_entries_have_receivable_account'),
id: 'should_select_customers_with_entries_have_receivable_account',
}),
); );
setEntriesErrors(error.indexes, 'contact_id', 'error'); setEntriesErrors(error.indexes, 'contact_id', 'error');
} }
if ((error = getError(ERROR.ENTRIES_SHOULD_ASSIGN_WITH_CONTACT))) { if ((error = getError(ERROR.ENTRIES_SHOULD_ASSIGN_WITH_CONTACT))) {
if (error.meta.find(meta => meta.contact_type === 'customer')) { if (error.meta.find(meta => meta.contact_type === 'customer')) {
toastMessages.push( toastMessages.push(
formatMessage({ intl.get('receivable_accounts_should_assign_with_customers'),
id: 'receivable_accounts_should_assign_with_customers',
}),
); );
} }
if (error.meta.find(meta => meta.contact_type === 'vendor')) { if (error.meta.find(meta => meta.contact_type === 'vendor')) {
toastMessages.push( toastMessages.push(
formatMessage({ id: 'payable_accounts_should_assign_with_vendors' }), intl.get('payable_accounts_should_assign_with_vendors'),
); );
} }
const indexes = error.meta.map((meta => meta.indexes)).flat(); const indexes = error.meta.map((meta => meta.indexes)).flat();
@@ -144,9 +140,7 @@ export const transformErrors = (resErrors, { setErrors, errors }) => {
newErrors = setWith( newErrors = setWith(
newErrors, newErrors,
'journal_number', 'journal_number',
formatMessage({ intl.get('journal_number_is_already_used'),
id: 'journal_number_is_already_used',
}),
); );
} }
setErrors({ ...newErrors }); setErrors({ ...newErrors });

View File

@@ -12,7 +12,8 @@ import {
Intent, Intent,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import classNames from 'classnames'; import classNames from 'classnames';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { If, DashboardActionViewsList } from 'components'; import { If, DashboardActionViewsList } from 'components';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
@@ -104,7 +105,7 @@ function AccountsActionsBar({
true ? ( true ? (
<T id={'filter'} /> <T id={'filter'} />
) : ( ) : (
<T id={'count_filters_applied'} values={{ count: 0 }} /> intl.get('count_filters_applied', { count: 0 })
) )
} }
icon={<Icon icon="filter-16" iconSize={16} />} icon={<Icon icon="filter-16" iconSize={16} />}
@@ -159,5 +160,5 @@ export default compose(
withAccounts(({ accountsSelectedRows }) => ({ withAccounts(({ accountsSelectedRows }) => ({
accountsSelectedRows, accountsSelectedRows,
})), })),
withAccountsTableActions withAccountsTableActions,
)(AccountsActionsBar); )(AccountsActionsBar);

View File

@@ -1,6 +1,8 @@
import React, { useMemo, useCallback } from 'react'; import React, { useMemo, useCallback } from 'react';
import { Alignment, Navbar, NavbarGroup } from '@blueprintjs/core'; import { Alignment, Navbar, NavbarGroup } from '@blueprintjs/core';
import { pick } from 'lodash'; import { pick } from 'lodash';
import intl from 'react-intl-universal';
import { DashboardViewsTabs } from 'components'; import { DashboardViewsTabs } from 'components';
import { useAccountsChartContext } from 'containers/Accounts/AccountsChartProvider'; import { useAccountsChartContext } from 'containers/Accounts/AccountsChartProvider';
@@ -45,7 +47,7 @@ function AccountsViewsTabs({
<Navbar className="navbar--dashboard-views"> <Navbar className="navbar--dashboard-views">
<NavbarGroup align={Alignment.LEFT}> <NavbarGroup align={Alignment.LEFT}>
<DashboardViewsTabs <DashboardViewsTabs
defaultTabText={'All Accounts'} defaultTabText={intl.get('all_accounts_')}
currentViewId={accountsCustomViewId} currentViewId={accountsCustomViewId}
resourceName={'accounts'} resourceName={'accounts'}
onChange={handleTabChange} onChange={handleTabChange}

View File

@@ -10,9 +10,8 @@ import {
Popover, Popover,
Button, Button,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { useIntl } from 'react-intl';
import { Icon, Money, If } from 'components'; import { Icon, Money, If } from 'components';
import { formatMessage } from 'services/intl'; import intl from 'react-intl-universal';
import { safeCallback } from 'utils'; import { safeCallback } from 'utils';
/** /**
@@ -34,37 +33,37 @@ export function ActionsMenu({
<Menu> <Menu>
<MenuItem <MenuItem
icon={<Icon icon="reader-18" />} icon={<Icon icon="reader-18" />}
text={formatMessage({ id: 'view_details' })} text={intl.get('view_details')}
onClick={safeCallback(onViewDetails, original)} onClick={safeCallback(onViewDetails, original)}
/> />
<MenuDivider /> <MenuDivider />
<MenuItem <MenuItem
icon={<Icon icon="pen-18" />} icon={<Icon icon="pen-18" />}
text={formatMessage({ id: 'edit_account' })} text={intl.get('edit_account')}
onClick={safeCallback(onEdit, original)} onClick={safeCallback(onEdit, original)}
/> />
<MenuItem <MenuItem
icon={<Icon icon="plus" />} icon={<Icon icon="plus" />}
text={formatMessage({ id: 'new_child_account' })} text={intl.get('new_child_account')}
onClick={safeCallback(onNewChild, original)} onClick={safeCallback(onNewChild, original)}
/> />
<MenuDivider /> <MenuDivider />
<If condition={original.active}> <If condition={original.active}>
<MenuItem <MenuItem
text={formatMessage({ id: 'inactivate_account' })} text={intl.get('inactivate_account')}
icon={<Icon icon="pause-16" iconSize={16} />} icon={<Icon icon="pause-16" iconSize={16} />}
onClick={safeCallback(onInactivate, original)} onClick={safeCallback(onInactivate, original)}
/> />
</If> </If>
<If condition={!original.active}> <If condition={!original.active}>
<MenuItem <MenuItem
text={formatMessage({ id: 'activate_account' })} text={intl.get('activate_account')}
icon={<Icon icon="play-16" iconSize={16} />} icon={<Icon icon="play-16" iconSize={16} />}
onClick={safeCallback(onActivate, original)} onClick={safeCallback(onActivate, original)}
/> />
</If> </If>
<MenuItem <MenuItem
text={formatMessage({ id: 'delete_account' })} text={intl.get('delete_account')}
icon={<Icon icon="trash-16" iconSize={16} />} icon={<Icon icon="trash-16" iconSize={16} />}
intent={Intent.DANGER} intent={Intent.DANGER}
onClick={safeCallback(onDelete, original)} onClick={safeCallback(onDelete, original)}
@@ -77,7 +76,6 @@ export function ActionsMenu({
* Normal cell. * Normal cell.
*/ */
export function NormalCell({ cell: { value } }) { export function NormalCell({ cell: { value } }) {
const { formatMessage } = useIntl();
const arrowDirection = value === 'credit' ? 'down' : 'up'; const arrowDirection = value === 'credit' ? 'down' : 'up';
// Can't continue if the value is not `credit` or `debit`. // Can't continue if the value is not `credit` or `debit`.
@@ -87,7 +85,7 @@ export function NormalCell({ cell: { value } }) {
return ( return (
<Tooltip <Tooltip
className={Classes.TOOLTIP_INDICATOR} className={Classes.TOOLTIP_INDICATOR}
content={formatMessage({ id: value })} content={intl.get(value)}
position={Position.RIGHT} position={Position.RIGHT}
hoverOpenDelay={100} hoverOpenDelay={100}
> >

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { Intent, Tag } from '@blueprintjs/core'; import { Intent, Tag } from '@blueprintjs/core';
import { If, AppToaster } from 'components'; import { If, AppToaster } from 'components';
import { formatMessage } from 'services/intl'; import intl from 'react-intl-universal';
import { NormalCell, BalanceCell } from './components'; import { NormalCell, BalanceCell } from './components';
import { isBlank, compose } from 'utils'; import { isBlank, compose } from 'utils';
@@ -25,17 +25,13 @@ export const accountNameAccessor = (account) => {
export const handleDeleteErrors = (errors) => { export const handleDeleteErrors = (errors) => {
if (errors.find((e) => e.type === 'ACCOUNT.PREDEFINED')) { if (errors.find((e) => e.type === 'ACCOUNT.PREDEFINED')) {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('you_could_not_delete_predefined_accounts'),
id: 'you_could_not_delete_predefined_accounts',
}),
intent: Intent.DANGER, intent: Intent.DANGER,
}); });
} }
if (errors.find((e) => e.type === 'ACCOUNT.HAS.ASSOCIATED.TRANSACTIONS')) { if (errors.find((e) => e.type === 'ACCOUNT.HAS.ASSOCIATED.TRANSACTIONS')) {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('cannot_delete_account_has_associated_transactions'),
id: 'cannot_delete_account_has_associated_transactions',
}),
intent: Intent.DANGER, intent: Intent.DANGER,
}); });
} }
@@ -56,28 +52,28 @@ export const useAccountsTableColumns = () => {
() => [ () => [
{ {
id: 'name', id: 'name',
Header: formatMessage({ id: 'account_name' }), Header: intl.get('account_name'),
accessor: 'name', accessor: 'name',
className: 'account_name', className: 'account_name',
width: 200, width: 200,
}, },
{ {
id: 'code', id: 'code',
Header: formatMessage({ id: 'code' }), Header: intl.get('code'),
accessor: AccountCodeAccessor, accessor: AccountCodeAccessor,
className: 'code', className: 'code',
width: 80, width: 80,
}, },
{ {
id: 'type', id: 'type',
Header: formatMessage({ id: 'type' }), Header: intl.get('type'),
accessor: 'account_type_label', accessor: 'account_type_label',
className: 'type', className: 'type',
width: 140, width: 140,
}, },
{ {
id: 'normal', id: 'normal',
Header: formatMessage({ id: 'normal' }), Header: intl.get('account_normal'),
Cell: NormalCell, Cell: NormalCell,
accessor: 'account_normal', accessor: 'account_normal',
className: 'normal', className: 'normal',
@@ -85,13 +81,13 @@ export const useAccountsTableColumns = () => {
}, },
{ {
id: 'currency', id: 'currency',
Header: formatMessage({ id: 'currency' }), Header: intl.get('currency'),
accessor: 'currency_code', accessor: 'currency_code',
width: 75, width: 75,
}, },
{ {
id: 'balance', id: 'balance',
Header: formatMessage({ id: 'balance' }), Header: intl.get('balance'),
accessor: 'amount', accessor: 'amount',
Cell: BalanceCell, Cell: BalanceCell,
width: 150, width: 150,

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster, FormattedMessage as T } from 'components';
import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
import withAlertActions from 'containers/Alert/withAlertActions'; import withAlertActions from 'containers/Alert/withAlertActions';
@@ -20,7 +20,7 @@ function AccountActivateAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { const {
mutateAsync: activateAccount, mutateAsync: activateAccount,
isLoading isLoading
@@ -35,9 +35,7 @@ function AccountActivateAlert({
const handleConfirmAccountActivate = () => { const handleConfirmAccountActivate = () => {
activateAccount(accountId).then(() => { activateAccount(accountId).then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_account_has_been_successfully_activated'),
id: 'the_account_has_been_successfully_activated',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
closeAlert('account-activate'); closeAlert('account-activate');

View File

@@ -1,8 +1,8 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { queryCache } from 'react-query'; import { queryCache } from 'react-query';
import { AppToaster } from 'components'; import { FormattedMessage as T, AppToaster } from 'components';
import withAccountsActions from 'containers/Accounts/withAccountsActions'; import withAccountsActions from 'containers/Accounts/withAccountsActions';
import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
@@ -20,7 +20,6 @@ function AccountBulkActivateAlert({
requestBulkActivateAccounts, requestBulkActivateAccounts,
}) { }) {
const { formatMessage } = useIntl();
const [isLoading, setLoading] = useState(false); const [isLoading, setLoading] = useState(false);
const selectedRowsCount = 0; const selectedRowsCount = 0;
@@ -35,9 +34,7 @@ function AccountBulkActivateAlert({
requestBulkActivateAccounts(accountsIds) requestBulkActivateAccounts(accountsIds)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_accounts_has_been_successfully_activated'),
id: 'the_accounts_has_been_successfully_activated',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
queryCache.invalidateQueries('accounts-table'); queryCache.invalidateQueries('accounts-table');
@@ -52,9 +49,7 @@ function AccountBulkActivateAlert({
return ( return (
<Alert <Alert
cancelButtonText={<T id={'cancel'} />} cancelButtonText={<T id={'cancel'} />}
confirmButtonText={`${formatMessage({ confirmButtonText={`${intl.get('activate')} (${selectedRowsCount})`}
id: 'activate',
})} (${selectedRowsCount})`}
intent={Intent.WARNING} intent={Intent.WARNING}
isOpen={isOpen} isOpen={isOpen}
onCancel={handleClose} onCancel={handleClose}

View File

@@ -1,5 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { queryCache } from 'react-query'; import { queryCache } from 'react-query';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
@@ -29,7 +30,7 @@ function AccountBulkDeleteAlert({
// #withAccountsActions // #withAccountsActions
requestDeleteBulkAccounts, requestDeleteBulkAccounts,
}) { }) {
const { formatMessage } = useIntl();
const [isLoading, setLoading] = useState(false); const [isLoading, setLoading] = useState(false);
const selectedRowsCount = 0; const selectedRowsCount = 0;
@@ -43,9 +44,7 @@ function AccountBulkDeleteAlert({
requestDeleteBulkAccounts(accountsIds) requestDeleteBulkAccounts(accountsIds)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_accounts_has_been_successfully_deleted'),
id: 'the_accounts_has_been_successfully_deleted',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
queryCache.invalidateQueries('accounts-table'); queryCache.invalidateQueries('accounts-table');
@@ -62,9 +61,7 @@ function AccountBulkDeleteAlert({
return ( return (
<Alert <Alert
cancelButtonText={<T id={'cancel'} />} cancelButtonText={<T id={'cancel'} />}
confirmButtonText={`${formatMessage({ confirmButtonText={`${intl.get('delete')} (${selectedRowsCount})`}
id: 'delete',
})} (${selectedRowsCount})`}
icon="trash" icon="trash"
intent={Intent.DANGER} intent={Intent.DANGER}
isOpen={isOpen} isOpen={isOpen}

View File

@@ -1,5 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { queryCache } from 'react-query'; import { queryCache } from 'react-query';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
@@ -20,7 +21,7 @@ function AccountBulkInactivateAlert({
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const [isLoading, setLoading] = useState(false); const [isLoading, setLoading] = useState(false);
const selectedRowsCount = 0; const selectedRowsCount = 0;
@@ -34,9 +35,7 @@ function AccountBulkInactivateAlert({
requestBulkInactiveAccounts(accountsIds) requestBulkInactiveAccounts(accountsIds)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_accounts_have_been_successfully_inactivated'),
id: 'the_accounts_have_been_successfully_inactivated',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
queryCache.invalidateQueries('accounts-table'); queryCache.invalidateQueries('accounts-table');
@@ -51,9 +50,7 @@ function AccountBulkInactivateAlert({
return ( return (
<Alert <Alert
cancelButtonText={<T id={'cancel'} />} cancelButtonText={<T id={'cancel'} />}
confirmButtonText={`${formatMessage({ confirmButtonText={`${intl.get('inactivate')} (${selectedRowsCount})`}
id: 'inactivate',
})} (${selectedRowsCount})`}
intent={Intent.WARNING} intent={Intent.WARNING}
isOpen={isOpen} isOpen={isOpen}
onCancel={handleCancel} onCancel={handleCancel}

View File

@@ -1,10 +1,8 @@
import React from 'react'; import React from 'react';
import { import intl from 'react-intl-universal';
FormattedMessage as T, import { FormattedMessage as T, FormattedHTMLMessage } from 'components';
FormattedHTMLMessage,
useIntl,
} from 'react-intl';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
import { handleDeleteErrors } from 'containers/Accounts/utils'; import { handleDeleteErrors } from 'containers/Accounts/utils';
@@ -28,7 +26,6 @@ function AccountDeleteAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { isLoading, mutateAsync: deleteAccount } = useDeleteAccount(); const { isLoading, mutateAsync: deleteAccount } = useDeleteAccount();
// handle cancel delete account alert. // handle cancel delete account alert.
@@ -40,9 +37,7 @@ function AccountDeleteAlert({
deleteAccount(accountId) deleteAccount(accountId)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_account_has_been_successfully_deleted'),
id: 'the_account_has_been_successfully_deleted',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
closeAlert(name); closeAlert(name);

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
@@ -22,7 +23,7 @@ function AccountInactivateAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { const {
mutateAsync: inactivateAccount, mutateAsync: inactivateAccount,
isLoading isLoading
@@ -35,9 +36,7 @@ function AccountInactivateAlert({
const handleConfirmAccountActive = () => { const handleConfirmAccountActive = () => {
inactivateAccount(accountId).then(() => { inactivateAccount(accountId).then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_account_has_been_successfully_inactivated'),
id: 'the_account_has_been_successfully_inactivated',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
}).catch(() => { }).catch(() => {

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
@@ -23,7 +24,7 @@ function BillDeleteAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { isLoading, mutateAsync: deleteBillMutate } = useDeleteBill(); const { isLoading, mutateAsync: deleteBillMutate } = useDeleteBill();
// Handle cancel Bill // Handle cancel Bill
@@ -36,9 +37,7 @@ function BillDeleteAlert({
deleteBillMutate(billId) deleteBillMutate(billId)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_bill_has_been_deleted_successfully'),
id: 'the_bill_has_been_deleted_successfully',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
}) })

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
@@ -22,7 +23,7 @@ function BillOpenAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { isLoading, mutateAsync: openBillMutate } = useOpenBill(); const { isLoading, mutateAsync: openBillMutate } = useOpenBill();
// Handle cancel open bill alert. // Handle cancel open bill alert.
@@ -35,9 +36,7 @@ function BillOpenAlert({
openBillMutate(billId) openBillMutate(billId)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_bill_has_been_opened_successfully'),
id: 'the_bill_has_been_opened_successfully',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
closeAlert(name); closeAlert(name);

View File

@@ -1,10 +1,8 @@
import React from 'react'; import React from 'react';
import { import intl from 'react-intl-universal';
FormattedMessage as T, import { FormattedMessage as T, FormattedHTMLMessage } from 'components';
FormattedHTMLMessage,
useIntl,
} from 'react-intl';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
import { useDeleteCurrency } from 'hooks/query'; import { useDeleteCurrency } from 'hooks/query';
@@ -27,7 +25,7 @@ function CurrencyDeleteAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { mutateAsync: deleteCurrency, isLoading } = useDeleteCurrency(); const { mutateAsync: deleteCurrency, isLoading } = useDeleteCurrency();
// handle cancel delete currency alert. // handle cancel delete currency alert.
@@ -38,9 +36,7 @@ function CurrencyDeleteAlert({
deleteCurrency(currency_code) deleteCurrency(currency_code)
.then((response) => { .then((response) => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_currency_has_been_deleted_successfully'),
id: 'the_currency_has_been_deleted_successfully',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
closeAlert(name); closeAlert(name);

View File

@@ -1,5 +1,6 @@
import React, { useCallback, useState } from 'react'; import React, { useCallback, useState } from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
import { transformErrors } from 'containers/Customers/utils'; import { transformErrors } from 'containers/Customers/utils';
@@ -22,7 +23,7 @@ function CustomerBulkDeleteAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const [isLoading, setLoading] = useState(false); const [isLoading, setLoading] = useState(false);
// handle cancel delete alert. // handle cancel delete alert.
@@ -38,9 +39,7 @@ function CustomerBulkDeleteAlert({
requestDeleteBulkCustomers(customersIds) requestDeleteBulkCustomers(customersIds)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_customers_has_been_deleted_successfully'),
id: 'the_customers_has_been_deleted_successfully',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
}) })
@@ -51,7 +50,7 @@ function CustomerBulkDeleteAlert({
setLoading(false); setLoading(false);
closeAlert(name); closeAlert(name);
}); });
}, [requestDeleteBulkCustomers, customersIds, formatMessage]); }, [requestDeleteBulkCustomers, customersIds]);
return ( return (
<Alert <Alert

View File

@@ -1,9 +1,6 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { import intl from 'react-intl-universal';
FormattedMessage as T, import { FormattedMessage as T, FormattedHTMLMessage } from 'components';
FormattedHTMLMessage,
useIntl,
} from 'react-intl';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
import { transformErrors } from 'containers/Customers/utils'; import { transformErrors } from 'containers/Customers/utils';
@@ -28,7 +25,7 @@ function CustomerDeleteAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { const {
mutateAsync: deleteCustomerMutate, mutateAsync: deleteCustomerMutate,
isLoading isLoading
@@ -44,9 +41,7 @@ function CustomerDeleteAlert({
deleteCustomerMutate(customerId) deleteCustomerMutate(customerId)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_customer_has_been_deleted_successfully'),
id: 'the_customer_has_been_deleted_successfully',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
}) })
@@ -56,7 +51,7 @@ function CustomerDeleteAlert({
.finally(() => { .finally(() => {
closeAlert(name); closeAlert(name);
}); });
}, [deleteCustomerMutate, customerId, closeAlert, name, formatMessage]); }, [deleteCustomerMutate, customerId, closeAlert, name]);
return ( return (
<Alert <Alert

View File

@@ -1,5 +1,6 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { queryCache } from 'react-query'; import { queryCache } from 'react-query';
@@ -24,7 +25,7 @@ function EstimateApproveAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { const {
mutateAsync: deliverEstimateMutate, mutateAsync: deliverEstimateMutate,
isLoading, isLoading,
@@ -39,9 +40,7 @@ function EstimateApproveAlert({
deliverEstimateMutate(estimateId) deliverEstimateMutate(estimateId)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_estimate_has_been_approved_successfully'),
id: 'the_estimate_has_been_approved_successfully',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
queryCache.invalidateQueries('estimates-table'); queryCache.invalidateQueries('estimates-table');
@@ -50,7 +49,7 @@ function EstimateApproveAlert({
.finally(() => { .finally(() => {
closeAlert(name); closeAlert(name);
}); });
}, [estimateId, deliverEstimateMutate, closeAlert, name, formatMessage]); }, [estimateId, deliverEstimateMutate, closeAlert, name]);
return ( return (
<Alert <Alert

View File

@@ -1,10 +1,8 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { import intl from 'react-intl-universal';
FormattedMessage as T, import { FormattedMessage as T, FormattedHTMLMessage } from 'components';
FormattedHTMLMessage,
useIntl,
} from 'react-intl';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { useDeleteEstimate } from 'hooks/query'; import { useDeleteEstimate } from 'hooks/query';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
@@ -27,7 +25,7 @@ function EstimateDeleteAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { mutateAsync: deleteEstimateMutate, isLoading } = useDeleteEstimate(); const { mutateAsync: deleteEstimateMutate, isLoading } = useDeleteEstimate();
// handle cancel delete alert. // handle cancel delete alert.
@@ -40,9 +38,7 @@ function EstimateDeleteAlert({
deleteEstimateMutate(estimateId) deleteEstimateMutate(estimateId)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_estimate_has_been_deleted_successfully'),
id: 'the_estimate_has_been_deleted_successfully',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
}) })

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { useDeliverEstimate } from 'hooks/query'; import { useDeliverEstimate } from 'hooks/query';
@@ -23,7 +24,7 @@ function EstimateDeliveredAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { mutateAsync: deliverEstimateMutate, isLoading } = useDeliverEstimate(); const { mutateAsync: deliverEstimateMutate, isLoading } = useDeliverEstimate();
// Handle cancel delivered estimate alert. // Handle cancel delivered estimate alert.
@@ -36,9 +37,7 @@ function EstimateDeliveredAlert({
deliverEstimateMutate(estimateId) deliverEstimateMutate(estimateId)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_estimate_has_been_delivered_successfully'),
id: 'the_estimate_has_been_delivered_successfully',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}) })
}) })

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
@@ -23,7 +24,7 @@ function EstimateRejectAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { const {
mutateAsync: rejectEstimateMutate, mutateAsync: rejectEstimateMutate,
isLoading isLoading
@@ -39,9 +40,7 @@ function EstimateRejectAlert({
rejectEstimateMutate(estimateId) rejectEstimateMutate(estimateId)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_estimate_has_been_rejected_successfully'),
id: 'the_estimate_has_been_rejected_successfully',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
}) })

View File

@@ -1,5 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { size } from 'lodash'; import { size } from 'lodash';
import { AppToaster } from 'components'; import { AppToaster } from 'components';

View File

@@ -1,9 +1,6 @@
import React from 'react'; import React from 'react';
import { import intl from 'react-intl-universal';
FormattedMessage as T, import { FormattedMessage as T, FormattedHTMLMessage } from 'components';
FormattedHTMLMessage,
useIntl,
} from 'react-intl';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
@@ -30,7 +27,7 @@ function ExchangeRateDeleteAlert({
mutateAsync: deleteExchangeRate, mutateAsync: deleteExchangeRate,
isLoading, isLoading,
} = useDeleteExchangeRate(); } = useDeleteExchangeRate();
const { formatMessage } = useIntl();
// Handle cancel delete exchange rate alert. // Handle cancel delete exchange rate alert.
const handleCancelExchangeRateDelete = () => closeAlert(name); const handleCancelExchangeRateDelete = () => closeAlert(name);
@@ -39,9 +36,7 @@ function ExchangeRateDeleteAlert({
deleteExchangeRate(exchangeRateId) deleteExchangeRate(exchangeRateId)
.then((response) => { .then((response) => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_exchange_rates_has_been_deleted_successfully'),
id: 'the_exchange_rates_has_been_deleted_successfully',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
closeAlert(name); closeAlert(name);

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
@@ -20,7 +21,7 @@ function ExpenseDeleteAlert({
isOpen, isOpen,
payload: { expenseId }, payload: { expenseId },
}) { }) {
const { formatMessage } = useIntl();
const { const {
mutateAsync: deleteExpenseMutate, mutateAsync: deleteExpenseMutate,
isLoading, isLoading,
@@ -35,8 +36,8 @@ function ExpenseDeleteAlert({
const handleConfirmExpenseDelete = () => { const handleConfirmExpenseDelete = () => {
deleteExpenseMutate(expenseId).then(() => { deleteExpenseMutate(expenseId).then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage( message: intl.get(
{ id: 'the_expense_has_been_deleted_successfully' }, 'the_expense_has_been_deleted_successfully',
{ number: expenseId }, { number: expenseId },
), ),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl'; import { FormattedMessage as T } from 'components';
import withAlertActions from 'containers/Alert/withAlertActions'; import withAlertActions from 'containers/Alert/withAlertActions';
import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
@@ -20,7 +21,7 @@ function ExpensePublishAlert({
payload: { expenseId }, payload: { expenseId },
isOpen, isOpen,
}) { }) {
const { formatMessage } = useIntl();
const { mutateAsync: publishExpenseMutate, isLoading } = usePublishExpense(); const { mutateAsync: publishExpenseMutate, isLoading } = usePublishExpense();
const handleCancelPublishExpense = () => { const handleCancelPublishExpense = () => {
@@ -32,9 +33,7 @@ function ExpensePublishAlert({
publishExpenseMutate(expenseId) publishExpenseMutate(expenseId)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_expense_has_been_published'),
id: 'the_expense_has_been_published',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
closeAlert(name) closeAlert(name)

View File

@@ -1,9 +1,6 @@
import React from 'react'; import React from 'react';
import { import intl from 'react-intl-universal';
FormattedMessage as T, import { FormattedMessage as T, FormattedHTMLMessage } from 'components';
FormattedHTMLMessage,
useIntl,
} from 'react-intl';
import { Intent, Alert } from '@blueprintjs/core'; import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components'; import { AppToaster } from 'components';
import { useDeleteInvoice } from 'hooks/query'; import { useDeleteInvoice } from 'hooks/query';
@@ -28,7 +25,7 @@ function InvoiceDeleteAlert({
// #withAlertActions // #withAlertActions
closeAlert, closeAlert,
}) { }) {
const { formatMessage } = useIntl();
const { mutateAsync: deleteInvoiceMutate, isLoading } = useDeleteInvoice(); const { mutateAsync: deleteInvoiceMutate, isLoading } = useDeleteInvoice();
// handle cancel delete invoice alert. // handle cancel delete invoice alert.
@@ -41,9 +38,7 @@ function InvoiceDeleteAlert({
deleteInvoiceMutate(invoiceId) deleteInvoiceMutate(invoiceId)
.then(() => { .then(() => {
AppToaster.show({ AppToaster.show({
message: formatMessage({ message: intl.get('the_invoice_has_been_deleted_successfully'),
id: 'the_invoice_has_been_deleted_successfully',
}),
intent: Intent.SUCCESS, intent: Intent.SUCCESS,
}); });
}) })

Some files were not shown because too many files have changed in this diff Show More