Merge branch 'develop'

This commit is contained in:
a.bouhuolia
2022-01-03 11:46:00 +02:00
512 changed files with 20008 additions and 2564 deletions

View File

@@ -1,17 +1,60 @@
import React from 'react';
import clsx from 'classnames';
import styled from 'styled-components';
import Style from './style.module.scss';
export function Alert({ title, description, intent }) {
export function Alert({ title, description, children, intent, className }) {
return (
<div
className={clsx(Style.root, {
[`${Style['root_' + intent]}`]: intent,
})}
>
{title && <h3 className={clsx(Style.title)}>{title}</h3>}
{description && <p class={clsx(Style.description)}>{description}</p>}
</div>
<AlertRoot className={clsx(className)} intent={intent}>
{title && <AlertTitle>{title}</AlertTitle>}
{description && <AlertDesc>{description}</AlertDesc>}
{children && <AlertDesc>{children}</AlertDesc>}
</AlertRoot>
);
}
const AlertRoot = styled.div`
border: 1px solid rgb(223, 227, 230);
padding: 12px;
border-radius: 6px;
margin-bottom: 20px;
${(props) =>
props.intent === 'danger' &&
`
border-color: rgb(249, 198, 198);
background: rgb(255, 248, 248);
${AlertDesc} {
color: #d95759;
}
${AlertTitle} {
color: rgb(205, 43, 49);
}
`}
${(props) =>
props.intent === 'primary' &&
`
background: #fff;
border-color: #98a8ee;
${AlertTitle} {
color: #1a3bd4;
}
${AlertDesc} {
color: #455883;
}
`}
`;
export const AlertTitle = styled.h3`
color: rgb(17, 24, 28);
margin-bottom: 4px;
font-size: 14px;
font-weight: 600;
`;
export const AlertDesc = styled.p`
color: rgb(104, 112, 118);
margin: 0;
`;

View File

@@ -1,32 +0,0 @@
.root {
border: 1px solid rgb(223, 227, 230);
padding: 12px;
border-radius: 6px;
margin-bottom: 20px;
&_danger {
border-color: rgb(249, 198, 198);
background: rgb(255, 248, 248);
.description {
color: #d95759;
}
.title {
color: rgb(205, 43, 49);
}
}
}
.title {
color: rgb(17, 24, 28);
margin-bottom: 4px;
font-size: 14px;
font-weight: 600;
}
.description {
color: rgb(104, 112, 118);
margin: 0;
}

View File

@@ -4,7 +4,6 @@ import styled from 'styled-components';
import { Classes } from '@blueprintjs/core';
import clsx from 'classnames';
import Icon from '../Icon';
import { whenRtl, whenLtr } from 'utils/styled-components';
const ACCOUNT_TYPE = {
CASH: 'cash',
@@ -185,9 +184,7 @@ const MetaLineValue = styled.div`
text-align: center;
color: rgb(23, 43, 77);
font-size: 11px;
${whenLtr(`margin-left: auto;`)}
${whenRtl(`margin-right: auto;`)}
margin-left: auto;
`;
const BankAccountMeta = styled.div`
@@ -204,7 +201,5 @@ const AccountIconWrap = styled.div`
position: absolute;
top: 14px;
color: #abb3bb;
${whenLtr(`right: 12px;`)}
${whenRtl(`left: 12px;`)}
right: 12px;
`;

View File

@@ -5,6 +5,7 @@ export const ButtonLink = styled.button`
border: 0;
background: transparent;
cursor: pointer;
text-align: inherit;
&:hover,
&:active {

View File

@@ -1,6 +0,0 @@
import React from 'react';
import classNames from 'classnames';
export default function Card({ className, children }) {
return <div className={classNames('card', className)}>{children}</div>;
}

View File

@@ -0,0 +1,27 @@
import React from 'react';
import styled from 'styled-components';
export function Card({ className, children }) {
return <CardRoot className={className}>{children}</CardRoot>;
}
const CardRoot = styled.div`
padding: 15px;
margin: 15px;
background: #fff;
border: 1px solid #d2dce2;
`;
export const CardFooterActions = styled.div`
padding-top: 16px;
border-top: 1px solid #e0e7ea;
margin-top: 30px;
.bp3-button {
min-width: 70px;
+ .bp3-button {
margin-left: 10px;
}
}
`;

View File

@@ -0,0 +1,25 @@
import styled from 'styled-components';
import { Card } from '../Card';
import DataTable from '../DataTable';
export const CommercialDocBox = styled(Card)`
padding: 22px 20px;
`;
export const CommercialDocHeader = styled.div`
margin-bottom: 25px;
`;
export const CommercialDocTopHeader = styled.div`
margin-bottom: 25px;
`;
export const CommercialDocEntriesTable = styled(DataTable)`
.tbody .tr:last-child .td {
border-bottom: 1px solid #d2dce2;
}
`;
export const CommercialDocFooter = styled.div`
margin-top: 25px;
`;

View File

@@ -0,0 +1,25 @@
import React from 'react';
import * as R from 'ramda';
import { ButtonLink } from 'components';
import withDrawerActions from 'containers/Drawer/withDrawerActions';
function CustomerDrawerLinkComponent({
// #ownProps
children,
customerId,
// #withDrawerActions
openDrawer,
}) {
// Handle view customer drawer.
const handleCustomerDrawer = () => {
openDrawer('customer-details-drawer', { customerId });
};
return <ButtonLink onClick={handleCustomerDrawer}>{children}</ButtonLink>;
}
export const CustomerDrawerLink = R.compose(withDrawerActions)(
CustomerDrawerLinkComponent,
);

View File

@@ -0,0 +1 @@
export * from './CustomerDrawerLink';

View File

@@ -1,16 +1,19 @@
import React from 'react';
import classnames from 'classnames';
import clsx from 'classnames';
import { Navbar } from '@blueprintjs/core';
export default function DashboardActionsBar({ children, name }) {
export default function DashboardActionsBar({ className, children, name }) {
return (
<div
className={classnames({
'dashboard__actions-bar': true,
[`dashboard__actions-bar--${name}`]: !!name
})}
className={clsx(
{
'dashboard__actions-bar': true,
[`dashboard__actions-bar--${name}`]: !!name,
},
className,
)}
>
<Navbar className='navbar--dashboard-actions-bar'>{children}</Navbar>
<Navbar className="navbar--dashboard-actions-bar">{children}</Navbar>
</div>
);
}

View File

@@ -1,9 +1,16 @@
import React from 'react';
import { ThemeProvider } from 'styled-components';
import { ThemeProvider, StyleSheetManager } from 'styled-components';
import rtlcss from 'stylis-rtlcss';
import { useAppIntlContext } from '../AppIntlProvider';
export function DashboardThemeProvider({ children }) {
const { direction } = useAppIntlContext();
return <ThemeProvider theme={{ dir: direction }}>{children}</ThemeProvider>;
return (
<StyleSheetManager
{...(direction === 'rtl' ? { stylisPlugins: [rtlcss] } : {})}
>
<ThemeProvider theme={{ dir: direction }}>{children}</ThemeProvider>
</StyleSheetManager>
);
}

View File

@@ -16,6 +16,7 @@ export default function TableWrapper({ children }) {
expandable,
virtualizedRows,
className,
styleName,
size,
},
} = useContext(TableContext);
@@ -28,6 +29,7 @@ export default function TableWrapper({ children }) {
'is-expandable': expandable,
'is-loading': loading,
'has-virtualized-rows': virtualizedRows,
[`table--${styleName}`]: styleName,
})}
>
<ScrollSync>

View File

@@ -17,6 +17,7 @@ const useDetailsMenuContext = () => React.useContext(DetailsMenuContext);
export function DetailsMenu({
children,
direction = DIRECTION.VERTICAL,
textAlign,
minLabelSize,
className,
}) {
@@ -27,6 +28,7 @@ export function DetailsMenu({
{
'details-menu--vertical': direction === DIRECTION.VERTICAL,
'details-menu--horizantal': direction === DIRECTION.HORIZANTAL,
[`align-${textAlign}`]: textAlign,
},
className,
)}

View File

@@ -2,6 +2,10 @@ import React from 'react';
import styled from 'styled-components';
import { Classes } from '@blueprintjs/core';
/**
* Dialog footer actions.
* @returns {React.JSX}
*/
export function DialogFooterActions({ alignment = 'right', children }) {
return (
<DialogFooterActionsRoot
@@ -13,6 +17,19 @@ export function DialogFooterActions({ alignment = 'right', children }) {
);
}
/**
* Dialog footer.
* @returns {React.JSX}
*/
export function DialogFooter({ ...props }) {
return <DialogFooterRoot {...props} />;
}
const DialogFooterRoot = styled.div`
flex: 0 0 auto;
margin: 0 20px;
`;
const DialogFooterActionsRoot = styled.div`
${(props) =>
props.alignment === 'right' ? 'margin-left: auto;' : 'margin-right: auto;'};

View File

@@ -25,7 +25,13 @@ import NotifyReceiptViaSMSDialog from '../containers/Dialogs/NotifyReceiptViaSMS
import NotifyEstimateViaSMSDialog from '../containers/Dialogs/NotifyEstimateViaSMSDialog';
import NotifyPaymentReceiveViaSMSDialog from '../containers/Dialogs/NotifyPaymentReceiveViaSMSDialog';
import SMSMessageDialog from '../containers/Dialogs/SMSMessageDialog';
import TransactionsLockingDialog from '../containers/Dialogs/TransactionsLockingDialog';
import RefundCreditNoteDialog from '../containers/Dialogs/RefundCreditNoteDialog';
import RefundVendorCreditDialog from '../containers/Dialogs/RefundVendorCreditDialog';
import ReconcileCreditNoteDialog from '../containers/Dialogs/ReconcileCreditNoteDialog';
import ReconcileVendorCreditDialog from '../containers/Dialogs/ReconcileVendorCreditDialog';
import LockingTransactionsDialog from '../containers/Dialogs/LockingTransactionsDialog';
import UnlockingTransactionsDialog from '../containers/Dialogs/UnlockingTransactionsDialog';
import UnlockingPartialTransactionsDialog from '../containers/Dialogs/UnlockingPartialTransactionsDialog';
/**
* Dialogs container.
@@ -59,7 +65,15 @@ export default function DialogsContainer() {
<BadDebtDialog dialogName={'write-off-bad-debt'} />
<SMSMessageDialog dialogName={'sms-message-form'} />
<TransactionsLockingDialog dialogName={'transactions-locking'} />
<RefundCreditNoteDialog dialogName={'refund-credit-note'} />
<RefundVendorCreditDialog dialogName={'refund-vendor-credit'} />
<ReconcileCreditNoteDialog dialogName={'reconcile-credit-note'} />
<ReconcileVendorCreditDialog dialogName={'reconcile-vendor-credit'} />
<LockingTransactionsDialog dialogName={'locking-transactions'} />
<UnlockingTransactionsDialog dialogName={'unlocking-transactions'} />
<UnlockingPartialTransactionsDialog
dialogName={'unlocking-partial-transactions'}
/>
</div>
);
}

View File

@@ -0,0 +1,12 @@
import React from 'react';
import styled from 'styled-components';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
export function DrawerActionsBar({ ...props }) {
return <DrawerActionsBarRoot {...props} />;
}
const DrawerActionsBarRoot = styled(DashboardActionsBar)`
border-bottom: 1px solid #d9d9da;
`;

View File

@@ -1,15 +1,54 @@
import React from 'react';
import { Tabs } from '@blueprintjs/core';
import styled from 'styled-components';
/**
* Drawer main tabs.
*/
export function DrawerMainTabs({ children, ...restProps }) {
return (
<div class="drawer__main-tabs">
<DrawerMainTabsRoot>
<Tabs animate={true} large={true} {...restProps}>
{children}
</Tabs>
</div>
</DrawerMainTabsRoot>
);
}
const DrawerMainTabsRoot = styled.div`
.bp3-tabs {
.bp3-tab-list {
position: relative;
background-color: #fff;
padding: 0 15px;
border-bottom: 2px solid #e1e2e8;
> *:not(:last-child) {
margin-right: 25px;
}
&.bp3-large > .bp3-tab {
font-size: 15px;
color: #7f8596;
margin: 0 1rem;
&[aria-selected='true'],
&:not([aria-disabled='true']):hover {
color: #0052cc;
}
}
.bp3-tab-indicator-wrapper .bp3-tab-indicator {
height: 2px;
bottom: -2px;
}
}
.bp3-tab-panel {
margin-top: 0;
.card {
margin: 15px;
}
}
}
`;

View File

@@ -13,3 +13,5 @@ export function DrawerLoading({ loading, mount = false, children }) {
export function DrawerBody({ children }) {
return <div className={Classes.DRAWER_BODY}>{children}</div>;
}
export * from './DrawerActionsBar';

View File

@@ -17,6 +17,10 @@ import CashflowTransactionDetailDrawer from '../containers/Drawers/CashflowTrans
import QuickCreateCustomerDrawer from '../containers/Drawers/QuickCreateCustomerDrawer';
import QuickCreateItemDrawer from '../containers/Drawers/QuickCreateItemDrawer';
import QuickWriteVendorDrawer from '../containers/Drawers/QuickWriteVendorDrawer';
import CreditNoteDetailDrawer from '../containers/Drawers/CreditNoteDetailDrawer';
import VendorCreditDetailDrawer from '../containers/Drawers/VendorCreditDetailDrawer';
import RefundCreditNoteDetailDrawer from '../containers/Drawers/RefundCreditNoteDetailDrawer';
import RefundVendorCreditDetailDrawer from '../containers/Drawers/RefundVendorCreditDetailDrawer';
import { DRAWERS } from 'common/drawers';
@@ -47,6 +51,14 @@ export default function DrawersContainer() {
<QuickCreateCustomerDrawer name={DRAWERS.QUICK_CREATE_CUSTOMER} />
<QuickCreateItemDrawer name={DRAWERS.QUICK_CREATE_ITEM} />
<QuickWriteVendorDrawer name={DRAWERS.QUICK_WRITE_VENDOR} />
<CreditNoteDetailDrawer name={DRAWERS.CREDIT_NOTE_DETAIL_DRAWER} />
<VendorCreditDetailDrawer name={DRAWERS.VENDOR_CREDIT_DETAIL_DRAWER} />
<RefundCreditNoteDetailDrawer
name={DRAWERS.REFUND_CREDIT_NOTE_DETAIL_DRAWER}
/>
<RefundVendorCreditDetailDrawer
name={DRAWERS.REFUND_VENDOR_CREDIT_DETAIL_DRAWER}
/>
</div>
);
}

View File

@@ -0,0 +1,14 @@
import { useDeepCompareEffect } from 'hooks/utils';
export function FormikObserver({ onChange, values }) {
useDeepCompareEffect(() => {
onChange(values);
}, [values]);
return null;
}
FormikObserver.defaultProps = {
onChange: () => null,
};

View File

@@ -1 +1,2 @@
export * from './FormObserver';
export * from './FormObserver';
export * from './FormikObserver';

View File

@@ -1,6 +1,8 @@
import React from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import classNames from 'classnames';
import * as R from 'ramda';
import { CLASSES } from 'common/classes';
import PreferencesTopbar from 'components/Preferences/PreferencesTopbar';
@@ -8,18 +10,28 @@ import PreferencesContentRoute from 'components/Preferences/PreferencesContentRo
import DashboardErrorBoundary from 'components/Dashboard/DashboardErrorBoundary';
import PreferencesSidebar from 'components/Preferences/PreferencesSidebar';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import 'style/pages/Preferences/Page.scss';
/**
* Preferences page.
*/
export default function PreferencesPage() {
function PreferencesPage({ toggleSidebarExpand }) {
// Shrink the dashboard sidebar once open application preferences page.
React.useEffect(() => {
toggleSidebarExpand(false);
}, [toggleSidebarExpand]);
return (
<ErrorBoundary FallbackComponent={DashboardErrorBoundary}>
<div id={'dashboard'} className={classNames(
CLASSES.DASHBOARD_CONTENT,
CLASSES.DASHBOARD_CONTENT_PREFERENCES,
)}>
<div
id={'dashboard'}
className={classNames(
CLASSES.DASHBOARD_CONTENT,
CLASSES.DASHBOARD_CONTENT_PREFERENCES,
)}
>
<div className={classNames(CLASSES.PREFERENCES_PAGE)}>
<PreferencesSidebar />
@@ -32,3 +44,5 @@ export default function PreferencesPage() {
</ErrorBoundary>
);
}
export default R.compose(withDashboardActions)(PreferencesPage);

View File

@@ -0,0 +1,33 @@
import styled from 'styled-components';
export const Table = styled.table`
width: 100%;
vertical-align: top;
border-color: #dee2e6;
border-spacing: 0;
`;
export const TBody = styled.tbody``;
export const TR = styled.tr``;
export const TD = styled.td`
padding: 0.5rem 0.5rem;
border-bottom-width: 1px;
border-bottom-color: inherit;
border-bottom-style: solid;
${(props) =>
props.textAlign === 'right' &&
`
text-align: right;`}
`;
export const TRDarkSingleLine = styled(TR)`
${TD} {
border-bottom: 1px solid #000;
}
`;
export const TRDarkDoubleLines = styled(TR)`
${TD} {
border-bottom: 3px double #000;
}
`;

View File

@@ -0,0 +1,11 @@
import styled from 'styled-components';
export const CurrencyTag = styled.span`
background: #3e9215;
color: #fff;
display: inline-block;
border-radius: 3px;
padding: 2px 4px;
line-height: 1;
margin-left: 4px;
`;

View File

@@ -0,0 +1,3 @@
export * from './CurrencyTag';

View File

@@ -0,0 +1,28 @@
import React from 'react';
import styled from 'styled-components';
export function TextStatus({ intent, children }) {
return <TextStatusRoot intent={intent}>{children}</TextStatusRoot>;
}
const TextStatusRoot = styled.span`
${(props) =>
props.intent === 'warning' &&
`
color: #ec5b0a;`}
${(props) =>
props.intent === 'success' &&
`
color: #2ba01d;`}
${(props) =>
props.intent === 'none' &&
`
color: #777;`}
${(props) =>
props.intent === 'primary' &&
`
color: #1652c8;`}
`;

View File

@@ -1,12 +0,0 @@
.total_lines {}
.total_line {
display: flex;
border-bottom: 1px solid #d2dde2;
:global .amount,
:global .title{
padding: 8px;
}
}

View File

@@ -1,23 +1,93 @@
import React from 'react';
import clsx from 'classnames';
import styled from 'styled-components';
import TotalLinesCls from './TotalLines.module.scss';
export const TotalLineBorderStyle = {
SingleDark: 'SingleDark',
DoubleDark: 'DoubleDark',
};
export function TotalLines({ children, className }) {
export const TotalLineTextStyle = {
Regular: 'Regular',
Bold: 'Bold',
};
export function TotalLines({
children,
amountColWidth,
labelColWidth,
className,
}) {
return (
<div className={clsx('total_lines', TotalLinesCls.total_lines, className)}>
<TotalLinesRoot
className={className}
amountColWidth={amountColWidth}
labelColWidth={labelColWidth}
>
{children}
</div>
</TotalLinesRoot>
);
}
export function TotalLine({ title, value, className }) {
export function TotalLine({ title, value, borderStyle, textStyle, className }) {
return (
<div
className={clsx('total_lines_line', TotalLinesCls.total_line, className)}
<TotalLineRoot
borderStyle={borderStyle}
textStyle={textStyle}
className={className}
>
<div class="title">{title}</div>
<div class="amount">{value}</div>
</div>
</TotalLineRoot>
);
}
export const TotalLinesRoot = styled.div`
display: table;
${(props) =>
props.amountColWidth &&
`
.amount{
width: ${props.amountColWidth}
}
`}
${(props) =>
props.labelColWidth &&
`
.title{
width: ${props.labelColWidth}
}
`}
`;
export const TotalLineRoot = styled.div`
display: table-row;
.amount,
.title {
display: table-cell;
padding: 8px;
border-bottom: 1px solid #d2dde2;
${(props) =>
props.borderStyle === TotalLineBorderStyle.DoubleDark &&
`
border-bottom: 3px double #000;
`}
${(props) =>
props.borderStyle === TotalLineBorderStyle.SingleDark &&
`
border-bottom: 1px double #000;
`}
${(props) =>
props.textStyle === TotalLineTextStyle.Bold &&
`
font-weight: 600;
`}
}
.amount {
text-align: right;
}
`;

View File

@@ -0,0 +1,6 @@
import React from 'react';
import clsx from 'classnames';
export function Paragraph({ className, children }) {
return <p className={clsx('paragraph', className)}>{children}</p>;
}

View File

@@ -0,0 +1,2 @@
export * from './Paragraph';

View File

@@ -0,0 +1,13 @@
import React from 'react';
export function Join({ items, sep }) {
return items.length > 0
? items.reduce((result, item) => (
<>
{result}
{sep}
{item}
</>
))
: null;
}

View File

@@ -1,4 +1,5 @@
export * from './FormatNumber';
export * from './FormatDate';
export * from './FormatDate';
export * from './Join';

View File

@@ -0,0 +1,23 @@
import React from 'react';
import * as R from 'ramda';
import { ButtonLink } from 'components';
import withDrawerActions from 'containers/Drawer/withDrawerActions';
function VendorDrawerLinkComponent({
// #ownProps
children,
vendorId,
// #withDrawerActions
openDrawer,
}) {
// Handle view customer drawer.
const handleVendorDrawer = () => {
openDrawer('vendor-details-drawer', { vendorId });
};
return <ButtonLink onClick={handleVendorDrawer}>{children}</ButtonLink>;
}
export const VendorDrawerLink = R.compose(withDrawerActions)(VendorDrawerLinkComponent);

View File

@@ -0,0 +1 @@
export * from './VendorDrawerLink'

View File

@@ -54,7 +54,6 @@ import Postbox from './Postbox';
import AccountsSuggestField from './AccountsSuggestField';
import MaterialProgressBar from './MaterialProgressBar';
import { MoneyFieldCell } from './DataTableCells';
import Card from './Card';
import AvaterCell from './AvaterCell';
import { ItemsMultiSelect } from './Items';
@@ -87,6 +86,15 @@ export * from './Button';
export * from './IntersectionObserver';
export * from './SMSPreview';
export * from './Contacts';
export * from './Utils/Join';
export * from './Typo';
export * from './TextStatus';
export * from './Tags';
export * from './CommercialDoc';
export * from './Card';
export * from './Customers'
export * from './Vendors'
export * from './Table';
const Hint = FieldHint;
@@ -153,7 +161,6 @@ export {
MaterialProgressBar,
MoneyFieldCell,
ItemsMultiSelect,
Card,
AvaterCell,
MoreMenuItems,
};