fix: logo style.

fix: page forms style.
feat: auto-fill items entries from item details.
fix: hiding dashboard copyright bar.
This commit is contained in:
a.bouhuolia
2021-02-25 10:51:27 +02:00
parent 5a58e9bafd
commit 9e2c995813
84 changed files with 1019 additions and 682 deletions

View File

@@ -1,7 +1,8 @@
import React, { useCallback } from 'react';
import React, { useEffect, useCallback } from 'react';
import { Button } from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl';
import classNames from 'classnames';
import { useItem } from 'hooks/query';
import ItemsEntriesDeleteAlert from 'containers/Alerts/ItemsEntries/ItemsEntriesDeleteAlert';
import withAlertActions from 'containers/Alert/withAlertActions';
@@ -17,7 +18,15 @@ import {
removeRowsByIndex,
compose,
} from 'utils';
import { updateItemsEntriesTotal } from './utils';
import { updateItemsEntriesTotal, ITEM_TYPE } from './utils';
import { last } from 'lodash';
const updateAutoAddNewLine = (defaultEntry) => (entries) => {
const newEntries = [...entries];
const lastEntry = last(newEntries);
return (lastEntry.item_id) ? [...entries, defaultEntry] : [...entries];
};
/**
* Items entries table.
@@ -34,11 +43,64 @@ function ItemsEntriesTable({
errors,
onUpdateData,
linesNumber,
itemType, // sellable or purchasable
}) {
const [rows, setRows] = React.useState(initialEntries);
const [rowItem, setRowItem] = React.useState(null);
const [cellsLoading, setCellsLoading] = React.useState(null);
// Fetches the item details.
const { data: item, isFetching: isItemFetching } = useItem(
rowItem && rowItem.itemId,
{
enabled: !!rowItem,
},
);
// Once the item start loading give the table cells loading state.
useEffect(() => {
if (rowItem && isItemFetching) {
setCellsLoading([
[rowItem.rowIndex, 'rate'],
[rowItem.rowIndex, 'description'],
[rowItem.rowIndex, 'quantity'],
[rowItem.rowIndex, 'discount'],
]);
} else {
setCellsLoading(null);
}
}, [isItemFetching, setCellsLoading, rowItem]);
// Once the item selected and fetched set the initial details to the table.
useEffect(() => {
if (item && rowItem) {
const { rowIndex } = rowItem;
const price =
itemType === ITEM_TYPE.PURCHASABLE
? item.purchase_price
: item.sell_price;
const description =
itemType === ITEM_TYPE.PURCHASABLE
? item.purchase_description
: item.sell_description;
// Update the rate, description and quantity data of the row.
const newRows = compose(
updateItemsEntriesTotal,
updateTableRow(rowIndex, 'rate', price),
updateTableRow(rowIndex, 'description', description),
updateTableRow(rowIndex, 'quantity', 1),
)(rows);
setRows(newRows);
setRowItem(null);
saveInvoke(onUpdateData, newRows);
}
}, [item, rowItem, rows, itemType, onUpdateData]);
// Allows to observes `entries` to make table rows outside controlled.
React.useEffect(() => {
useEffect(() => {
if (entries && entries !== rows) {
setRows(entries);
}
@@ -50,15 +112,19 @@ function ItemsEntriesTable({
// Handles the editor data update.
const handleUpdateData = useCallback(
(rowIndex, columnId, value) => {
if (columnId === 'item_id') {
setRowItem({ rowIndex, columnId, itemId: value });
}
const newRows = compose(
updateAutoAddNewLine(defaultEntry),
updateItemsEntriesTotal,
updateTableRow(rowIndex, columnId, value),
)(entries);
)(rows);
setRows(newRows);
onUpdateData(newRows);
},
[entries, onUpdateData],
[rows, defaultEntry, onUpdateData],
);
// Handle table rows removing by index.
@@ -80,9 +146,7 @@ function ItemsEntriesTable({
openAlert('items-entries-clear-lines');
};
/**
* Handle alert confirm of clear all lines.
*/
// Handle alert confirm of clear all lines.
const handleClearLinesAlertConfirm = () => {
const newRows = repeatValue(defaultEntry, linesNumber);
setRows(newRows);
@@ -94,8 +158,12 @@ function ItemsEntriesTable({
<DataTableEditable
className={classNames(CLASSES.DATATABLE_EDITOR_ITEMS_ENTRIES)}
columns={columns}
data={entries}
data={rows}
sticky={true}
progressBarLoading={isItemFetching}
cellsLoading={isItemFetching}
cellsLoadingCoords={cellsLoading}
footer={true}
payload={{
items,
errors: errors || [],
@@ -103,25 +171,7 @@ function ItemsEntriesTable({
removeRow: handleRemoveRow,
autoFocus: ['item_id', 0],
}}
actions={
<>
<Button
small={true}
className={'button--secondary button--new-line'}
onClick={onClickNewRow}
>
<T id={'new_lines'} />
</Button>
<Button
small={true}
className={'button--secondary button--clear-lines ml1'}
onClick={handleClickClearAllLines}
>
<T id={'clear_all_lines'} />
</Button>
</>
}
/>
<ItemsEntriesDeleteAlert
name={'items-entries-clear-lines'}

View File

@@ -1,9 +1,8 @@
import React from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { Tooltip, Button, Intent, Position } from '@blueprintjs/core';
import { sumBy } from 'lodash';
import { Hint, Icon } from 'components';
import { formattedAmount } from 'utils';
import { formattedAmount, safeSumBy } from 'utils';
import {
InputGroupCell,
MoneyFieldCell,
@@ -62,7 +61,7 @@ export function ActionsCellRenderer({
* Quantity total footer cell.
*/
export function QuantityTotalFooterCell({ rows }) {
const quantity = sumBy(rows, r => parseInt(r.original.quantity, 10));
const quantity = safeSumBy(rows, 'original.quantity');
return <span>{ quantity }</span>;
}
@@ -70,7 +69,7 @@ export function QuantityTotalFooterCell({ rows }) {
* Total footer cell.
*/
export function TotalFooterCell({ rows }) {
const total = sumBy(rows, 'original.total');
const total = safeSumBy(rows, 'original.total');
return <span>{ formattedAmount(total, 'USD') }</span>;
}
@@ -110,9 +109,8 @@ export function useEditableItemsEntriesColumns() {
Cell: ItemsListCell,
Footer: ItemFooterCell,
disableSortBy: true,
width: 180,
// filterPurchasable: filterPurchasableItems,
// filterSellable: filterSellableItems,
width: 130,
className: 'item',
},
{
Header: formatMessage({ id: 'description' }),
@@ -120,7 +118,7 @@ export function useEditableItemsEntriesColumns() {
Cell: InputGroupCell,
disableSortBy: true,
className: 'description',
width: 100,
width: 120,
},
{
Header: formatMessage({ id: 'quantity' }),
@@ -128,7 +126,7 @@ export function useEditableItemsEntriesColumns() {
Cell: NumericInputCell,
Footer: QuantityTotalFooterCell,
disableSortBy: true,
width: 80,
width: 70,
className: 'quantity',
},
{
@@ -136,7 +134,7 @@ export function useEditableItemsEntriesColumns() {
accessor: 'rate',
Cell: MoneyFieldCell,
disableSortBy: true,
width: 80,
width: 70,
className: 'rate',
},
{
@@ -144,7 +142,7 @@ export function useEditableItemsEntriesColumns() {
accessor: 'discount',
Cell: PercentFieldCell,
disableSortBy: true,
width: 80,
width: 60,
className: 'discount',
},
{
@@ -153,7 +151,7 @@ export function useEditableItemsEntriesColumns() {
accessor: 'total',
Cell: TotalCell,
disableSortBy: true,
width: 120,
width: 100,
className: 'total',
},
{

View File

@@ -23,4 +23,9 @@ export function updateItemsEntriesTotal(rows) {
...row,
total: calcItemEntryTotal(row.discount, row.quantity, row.rate)
}));
};
};
export const ITEM_TYPE = {
SELLABLE: 'SELLABLE',
PURCHASABLE: 'PURCHASABLE',
};