feat: optimize style of reconcile customer/vendor credit table.

This commit is contained in:
a.bouhuolia
2021-12-21 20:09:32 +02:00
parent dd7b44eb29
commit 1e5b394575
8 changed files with 321 additions and 263 deletions

View File

@@ -1,7 +1,9 @@
import React from 'react';
import intl from 'react-intl-universal';
import { MoneyFieldCell, DataTableEditable, FormatDateCell } from 'components';
import styled from 'styled-components';
import { DataTableEditable } from 'components';
import { compose, updateTableCell } from 'utils';
import { useReconcileCreditNoteTableColumns } from './utils';
/**
* Reconcile credit note entries table.
@@ -11,45 +13,8 @@ export default function ReconcileCreditNoteEntriesTable({
entries,
errors,
}) {
const columns = React.useMemo(
() => [
{
Header: intl.get('invoice_date'),
accessor: 'formatted_invoice_date',
Cell: FormatDateCell,
disableSortBy: true,
width: '120',
},
{
Header: intl.get('invoice_no'),
accessor: 'invoice_no',
disableSortBy: true,
width: '100',
},
{
Header: intl.get('amount'),
accessor: 'formatted_amount',
disableSortBy: true,
align: 'right',
width: '100',
},
{
Header: intl.get('reconcile_credit_note.column.remaining_amount'),
accessor: 'formatted_due_amount',
disableSortBy: true,
align: 'right',
width: '150',
},
{
Header: intl.get('reconcile_credit_note.column.amount_to_credit'),
accessor: 'amount',
Cell: MoneyFieldCell,
disableSortBy: true,
width: '150',
},
],
[],
);
// Retrieve the reconcile credit note table columns.
const columns = useReconcileCreditNoteTableColumns();
// Handle update data.
const handleUpdateData = React.useCallback(
@@ -63,7 +28,7 @@ export default function ReconcileCreditNoteEntriesTable({
);
return (
<DataTableEditable
<ReconcileCreditNoteEditableTable
columns={columns}
data={entries}
payload={{
@@ -73,3 +38,22 @@ export default function ReconcileCreditNoteEntriesTable({
/>
);
}
export const ReconcileCreditNoteEditableTable = styled(DataTableEditable)`
.table {
max-height: 400px;
overflow: auto;
.thead .tr .th {
padding-top: 8px;
padding-bottom: 8px;
}
.tbody {
.tr .td {
padding: 2px 4px;
min-height: 38px;
}
}
}
`;

View File

@@ -1,7 +1,15 @@
import React from 'react';
import { FastField, useFormikContext } from 'formik';
import { Classes } from '@blueprintjs/core';
import { T, TotalLines, TotalLine } from 'components';
import styled from 'styled-components';
import {
T,
TotalLines,
TotalLine,
TotalLineBorderStyle,
TotalLineTextStyle,
} from 'components';
import { subtract } from 'lodash';
import { getEntriesTotal } from 'containers/Entries/utils';
import ReconcileCreditNoteEntriesTable from './ReconcileCreditNoteEntriesTable';
@@ -13,11 +21,44 @@ import { formattedAmount } from 'utils';
*/
export default function ReconcileCreditNoteFormFields() {
const {
creditNote: {
formatted_credits_remaining,
credits_remaining,
currency_code,
},
creditNote: { formatted_credits_remaining },
} = useReconcileCreditNoteContext();
return (
<div className={Classes.DIALOG_BODY}>
<CreditRemainingRoot>
<T id={'reconcile_credit_note.dialog.credits_balance'} />
<CreditRemainingBalance>
{formatted_credits_remaining}
</CreditRemainingBalance>
</CreditRemainingRoot>
{/*------------ Reconcile credit entries table -----------*/}
<FastField name={'entries'}>
{({ form: { setFieldValue }, field: { value }, meta: { error } }) => (
<ReconcileCreditNoteEntriesTable
entries={value}
errors={error}
onUpdateData={(newEntries) => {
setFieldValue('entries', newEntries);
}}
/>
)}
</FastField>
<ReconcileCreditNoteTotalLines />
</div>
);
}
/**
* Reconcile credit note total lines.
* @returns {React.JSX}
*/
function ReconcileCreditNoteTotalLines() {
const {
creditNote: { credits_remaining, currency_code },
} = useReconcileCreditNoteContext();
const { values } = useFormikContext();
@@ -32,46 +73,42 @@ export default function ReconcileCreditNoteFormFields() {
const creditsRemaining = subtract(credits_remaining, totalAmount);
return (
<div className={Classes.DIALOG_BODY}>
<div className="credit-remaining">
<div className="credit-remaining__label">
<T id={'reconcile_credit_note.dialog.credits_balance'} />
</div>
<div className="credit-remaining__balance">
{formatted_credits_remaining}
</div>
</div>
{/*------------ Reconcile credit entries table -----------*/}
<FastField name={'entries'}>
{({
form: { setFieldValue, values },
field: { value },
meta: { error, touched },
}) => (
<ReconcileCreditNoteEntriesTable
entries={value}
errors={error}
onUpdateData={(newEntries) => {
setFieldValue('entries', newEntries);
}}
/>
)}
</FastField>
<div className="footer">
<TotalLines className="total_lines">
<TotalLine
title={
<T id={'reconcile_credit_note.dialog.total_amount_to_credit'} />
}
value={formattedAmount(totalAmount, currency_code)}
/>
<TotalLine
title={<T id={'reconcile_credit_note.dialog.remaining_credits'} />}
value={formattedAmount(creditsRemaining, currency_code)}
/>
</TotalLines>
</div>
</div>
<ReconcileCreditNoteTotalLinesRoot>
<ReconcileTotalLines labelColWidth={'180px'} amountColWidth={'180px'}>
<TotalLine
title={
<T id={'reconcile_credit_note.dialog.total_amount_to_credit'} />
}
value={formattedAmount(totalAmount, currency_code)}
borderStyle={TotalLineBorderStyle.SingleDark}
/>
<TotalLine
title={<T id={'reconcile_credit_note.dialog.remaining_credits'} />}
value={formattedAmount(creditsRemaining, currency_code)}
borderStyle={TotalLineBorderStyle.SingleDark}
textStyle={TotalLineTextStyle.Bold}
/>
</ReconcileTotalLines>
</ReconcileCreditNoteTotalLinesRoot>
);
}
export const CreditRemainingRoot = styled.div`
display: flex;
justify-content: flex-end;
padding-bottom: 15px;
`;
export const CreditRemainingBalance = styled.span`
font-weight: 600;
color: #343463;
margin-left: 5px;
`;
export const ReconcileCreditNoteTotalLinesRoot = styled.div`
margin-top: 15px;
`;
export const ReconcileTotalLines = styled(TotalLines)`
margin-left: auto;
`;

View File

@@ -1,8 +1,10 @@
import React from 'react';
import intl from 'react-intl-universal';
import { Callout, Intent, Classes } from '@blueprintjs/core';
import clsx from 'classnames';
import { AppToaster, T } from 'components';
import { CLASSES } from 'common/classes';
import { MoneyFieldCell, FormatDateCell, AppToaster, T } from 'components';
export const transformErrors = (errors, { setErrors }) => {
if (errors.some((e) => e.type === 'INVOICES_HAS_NO_REMAINING_AMOUNT')) {
@@ -33,3 +35,50 @@ export function EmptyStatuCallout() {
</div>
);
}
/**
* Retrieves reconcile credit note table columns.
* @returns
*/
export const useReconcileCreditNoteTableColumns = () => {
return React.useMemo(
() => [
{
Header: intl.get('invoice_date'),
accessor: 'formatted_invoice_date',
Cell: FormatDateCell,
disableSortBy: true,
width: '120',
},
{
Header: intl.get('invoice_no'),
accessor: 'invoice_no',
disableSortBy: true,
width: '100',
},
{
Header: intl.get('amount'),
accessor: 'formatted_amount',
disableSortBy: true,
align: 'right',
width: '100',
},
{
Header: intl.get('reconcile_credit_note.column.remaining_amount'),
accessor: 'formatted_due_amount',
disableSortBy: true,
align: 'right',
width: '150',
className: clsx(CLASSES.FONT_BOLD),
},
{
Header: intl.get('reconcile_credit_note.column.amount_to_credit'),
accessor: 'amount',
Cell: MoneyFieldCell,
disableSortBy: true,
width: '150',
},
],
[],
)
}