From 4f2679592f7b132f420c83a9e860bcfe8aee3db1 Mon Sep 17 00:00:00 2001 From: elforjani3 Date: Mon, 27 Jul 2020 02:39:26 +0200 Subject: [PATCH 1/6] WIP / Features / Sate --- .../components/DataTableCells/DivFieldCell.js | 11 + .../DataTableCells/EstimatesListFieldCell.js | 38 ++ .../DataTableCells/InputGroupCell.js | 13 +- .../DataTableCells/PercentFieldCell.js | 43 ++ client/src/components/DataTableCells/index.js | 9 +- client/src/components/EstimateListField.js | 41 ++ client/src/config/sidebarMenu.js | 25 +- .../Sales/Estimate/EntriesItemsTable.js | 259 ++++++++++++ .../Sales/Estimate/EstimateActionsBar.js | 140 +++++++ .../containers/Sales/Estimate/EstimateForm.js | 334 +++++++++++++++ .../Sales/Estimate/EstimateFormFooter.js | 41 ++ .../Sales/Estimate/EstimateFormHeader.js | 192 +++++++++ .../containers/Sales/Estimate/EstimateList.js | 120 ++++++ .../containers/Sales/Estimate/Estimates.js | 49 +++ .../Sales/Estimate/EstimatesDataTable.js | 196 +++++++++ .../Sales/Estimate/withEstimateActions.js | 32 ++ .../Sales/Estimate/withEstimateDetail.js | 11 + .../Sales/Estimate/withEstimates.js | 24 ++ .../Sales/Invoice/InvoiceActionsBar.js | 133 ++++++ .../containers/Sales/Invoice/InvoiceForm.js | 321 +++++++++++++++ .../Sales/Invoice/InvoiceFormFooter.js | 41 ++ .../Sales/Invoice/InvoiceFormHeader.js | 177 ++++++++ .../containers/Sales/Invoice/InvoiceList.js | 109 +++++ .../src/containers/Sales/Invoice/Invoices.js | 49 +++ .../Sales/Invoice/InvoicesDataTable.js | 189 +++++++++ .../Sales/Invoice/withInvoiceActions.js | 31 ++ .../Sales/Invoice/withInvoiceDetail.js | 11 + .../Sales/Receipt/ReceiptActionsBar.js | 0 .../containers/Sales/Receipt/ReceiptForm.js | 325 +++++++++++++++ .../Sales/Receipt/ReceiptFormFooter.js | 41 ++ .../Sales/Receipt/ReceiptFormHeader.js | 214 ++++++++++ .../src/containers/Sales/Receipt/Receipts.js | 65 +++ .../Sales/Receipt/withReceipActions.js | 33 ++ client/src/lang/en/index.js | 103 ++++- client/src/routes/dashboard.js | 71 ++++ .../src/store/Estimate/estimates.actions.js | 138 +++++++ .../src/store/Estimate/estimates.reducer.js | 105 +++++ .../src/store/Estimate/estimates.selectors.js | 44 ++ client/src/store/Estimate/estimates.types.js | 13 + client/src/store/Invoice/invoices.actions.js | 137 +++++++ client/src/store/Invoice/invoices.reducer.js | 32 ++ client/src/store/Invoice/invoices.selector.js | 9 + client/src/store/Invoice/invoices.types.js | 12 + client/src/store/receipt/receipt.actions.js | 136 +++++++ client/src/store/receipt/receipt.reducer.js | 0 client/src/store/receipt/receipt.selector.js | 0 client/src/store/receipt/receipt.type.js | 12 + client/src/store/reducers.js | 2 + client/src/store/types.js | 6 + client/src/style/App.scss | 43 +- client/src/style/pages/estimate.scss | 379 ++++++++++++++++++ 51 files changed, 4515 insertions(+), 44 deletions(-) create mode 100644 client/src/components/DataTableCells/DivFieldCell.js create mode 100644 client/src/components/DataTableCells/EstimatesListFieldCell.js create mode 100644 client/src/components/DataTableCells/PercentFieldCell.js create mode 100644 client/src/components/EstimateListField.js create mode 100644 client/src/containers/Sales/Estimate/EntriesItemsTable.js create mode 100644 client/src/containers/Sales/Estimate/EstimateActionsBar.js create mode 100644 client/src/containers/Sales/Estimate/EstimateForm.js create mode 100644 client/src/containers/Sales/Estimate/EstimateFormFooter.js create mode 100644 client/src/containers/Sales/Estimate/EstimateFormHeader.js create mode 100644 client/src/containers/Sales/Estimate/EstimateList.js create mode 100644 client/src/containers/Sales/Estimate/Estimates.js create mode 100644 client/src/containers/Sales/Estimate/EstimatesDataTable.js create mode 100644 client/src/containers/Sales/Estimate/withEstimateActions.js create mode 100644 client/src/containers/Sales/Estimate/withEstimateDetail.js create mode 100644 client/src/containers/Sales/Estimate/withEstimates.js create mode 100644 client/src/containers/Sales/Invoice/InvoiceActionsBar.js create mode 100644 client/src/containers/Sales/Invoice/InvoiceForm.js create mode 100644 client/src/containers/Sales/Invoice/InvoiceFormFooter.js create mode 100644 client/src/containers/Sales/Invoice/InvoiceFormHeader.js create mode 100644 client/src/containers/Sales/Invoice/InvoiceList.js create mode 100644 client/src/containers/Sales/Invoice/Invoices.js create mode 100644 client/src/containers/Sales/Invoice/InvoicesDataTable.js create mode 100644 client/src/containers/Sales/Invoice/withInvoiceActions.js create mode 100644 client/src/containers/Sales/Invoice/withInvoiceDetail.js create mode 100644 client/src/containers/Sales/Receipt/ReceiptActionsBar.js create mode 100644 client/src/containers/Sales/Receipt/ReceiptForm.js create mode 100644 client/src/containers/Sales/Receipt/ReceiptFormFooter.js create mode 100644 client/src/containers/Sales/Receipt/ReceiptFormHeader.js create mode 100644 client/src/containers/Sales/Receipt/Receipts.js create mode 100644 client/src/containers/Sales/Receipt/withReceipActions.js create mode 100644 client/src/store/Estimate/estimates.actions.js create mode 100644 client/src/store/Estimate/estimates.reducer.js create mode 100644 client/src/store/Estimate/estimates.selectors.js create mode 100644 client/src/store/Estimate/estimates.types.js create mode 100644 client/src/store/Invoice/invoices.actions.js create mode 100644 client/src/store/Invoice/invoices.reducer.js create mode 100644 client/src/store/Invoice/invoices.selector.js create mode 100644 client/src/store/Invoice/invoices.types.js create mode 100644 client/src/store/receipt/receipt.actions.js create mode 100644 client/src/store/receipt/receipt.reducer.js create mode 100644 client/src/store/receipt/receipt.selector.js create mode 100644 client/src/store/receipt/receipt.type.js create mode 100644 client/src/style/pages/estimate.scss diff --git a/client/src/components/DataTableCells/DivFieldCell.js b/client/src/components/DataTableCells/DivFieldCell.js new file mode 100644 index 000000000..a9274ceae --- /dev/null +++ b/client/src/components/DataTableCells/DivFieldCell.js @@ -0,0 +1,11 @@ +import React, { useState, useEffect } from 'react'; + +export default function DivFieldCell({ cell: { value: initialValue } }) { + const [value, setValue] = useState(initialValue); + + useEffect(() => { + setValue(initialValue); + }, [initialValue]); + + return
${value}
; +} diff --git a/client/src/components/DataTableCells/EstimatesListFieldCell.js b/client/src/components/DataTableCells/EstimatesListFieldCell.js new file mode 100644 index 000000000..1923028c0 --- /dev/null +++ b/client/src/components/DataTableCells/EstimatesListFieldCell.js @@ -0,0 +1,38 @@ +import React, { useCallback, useMemo } from 'react'; +import EstimateListField from 'components/EstimateListField'; +import classNames from 'classnames'; +import { FormGroup, Classes, Intent } from '@blueprintjs/core'; + +function EstimatesListFieldCell({ + column: { id }, + row: { index }, + cell: { value: initialValue }, + payload: { products, updateData, errors }, +}) { + const handleProductSelected = useCallback( + (item) => { + updateData(index, id, item.id); + }, + [updateData, index, id], + ); + + const error = errors?.[index]?.[id]; + + return ( + + + + ); +} + +export default EstimatesListFieldCell; diff --git a/client/src/components/DataTableCells/InputGroupCell.js b/client/src/components/DataTableCells/InputGroupCell.js index 07872a00f..3521fcbba 100644 --- a/client/src/components/DataTableCells/InputGroupCell.js +++ b/client/src/components/DataTableCells/InputGroupCell.js @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import classNames from 'classnames'; -import { Classes, InputGroup, FormGroup } from '@blueprintjs/core'; +import { Classes, InputGroup, FormGroup, Intent } from '@blueprintjs/core'; const InputEditableCell = ({ row: { index }, @@ -20,8 +20,17 @@ const InputEditableCell = ({ setValue(initialValue); }, [initialValue]); + const error = payload.errors?.[index]?.[id]; + return ( - + { + const [value, setValue] = useState(initialValue); + + const onBlur = (e) => { + updateData(index, id, parseInt(e.target.value, 10)); + }; + + const onChange = useCallback((e) => { + setValue(e.target.value); + }, []); + + + useEffect(() => { + setValue(initialValue); + }, [initialValue]); + + const error = errors?.[index]?.[id]; + + return ( + + + + ); +}; + +export default PercentFieldCell; diff --git a/client/src/components/DataTableCells/index.js b/client/src/components/DataTableCells/index.js index 60232831e..54be925fe 100644 --- a/client/src/components/DataTableCells/index.js +++ b/client/src/components/DataTableCells/index.js @@ -2,10 +2,15 @@ import AccountsListFieldCell from './AccountsListFieldCell'; import MoneyFieldCell from './MoneyFieldCell'; import InputGroupCell from './InputGroupCell'; import ContactsListFieldCell from './ContactsListFieldCell'; - +import EstimatesListFieldCell from './EstimatesListFieldCell'; +import PercentFieldCell from './PercentFieldCell'; +import DivFieldCell from './DivFieldCell'; export { AccountsListFieldCell, MoneyFieldCell, InputGroupCell, ContactsListFieldCell, -} \ No newline at end of file + EstimatesListFieldCell, + PercentFieldCell, + DivFieldCell, +}; diff --git a/client/src/components/EstimateListField.js b/client/src/components/EstimateListField.js new file mode 100644 index 000000000..ea37b794f --- /dev/null +++ b/client/src/components/EstimateListField.js @@ -0,0 +1,41 @@ +import React, { useCallback, useMemo, useEffect, useState } from 'react'; +import { MenuItem, Button } from '@blueprintjs/core'; +import ListSelect from 'components/ListSelect'; +import { FormattedMessage as T } from 'react-intl'; + +function EstimateListField({ + products, + selectedProductId, + onProductSelected, + defautlSelectText = , +}) { + const onProductSelect = useCallback( + (product) => { + onProductSelected && onProductSelected(product); + }, + [onProductSelected], + ); + + const productRenderer = useCallback( + (item, { handleClick, modifiers, query }) => ( + + ), + [], + ); + + return ( + } + itemRenderer={productRenderer} + popoverProps={{ minimal: true }} + onItemSelect={onProductSelect} + selectedItem={`${selectedProductId}`} + selectedItemProp={'id'} + labelProp={'name'} + defaultText={defautlSelectText} + /> + ); +} + +export default EstimateListField; diff --git a/client/src/config/sidebarMenu.js b/client/src/config/sidebarMenu.js index 1f904e8cd..7f6e7bf23 100644 --- a/client/src/config/sidebarMenu.js +++ b/client/src/config/sidebarMenu.js @@ -37,7 +37,20 @@ export default [ }, { text: , - children: [], + children: [ + { + text: , + href: '/estimates/new', + }, + { + text: , + href: '/invoices/new', + }, + { + text: , + href: '/receipts/new', + }, + ], }, { text: , @@ -99,11 +112,11 @@ export default [ text: , children: [ { - text: , + text: , href: '/expenses-list', }, { - text: , + text: , href: '/expenses/new', }, ], @@ -140,12 +153,12 @@ export default [ }, { text: 'Receivable Aging Summary', - href: '/financial-reports/receivable-aging-summary' + href: '/financial-reports/receivable-aging-summary', }, { text: 'Payable Aging Summary', - href: '/financial-reports/payable-aging-summary' - } + href: '/financial-reports/payable-aging-summary', + }, ], }, { diff --git a/client/src/containers/Sales/Estimate/EntriesItemsTable.js b/client/src/containers/Sales/Estimate/EntriesItemsTable.js new file mode 100644 index 000000000..eaa0a370e --- /dev/null +++ b/client/src/containers/Sales/Estimate/EntriesItemsTable.js @@ -0,0 +1,259 @@ +import React, { useState, useMemo, useEffect, useCallback } from 'react'; +import { Button, Intent, Position, Tooltip } from '@blueprintjs/core'; +import { FormattedMessage as T, useIntl } from 'react-intl'; +import DataTable from 'components/DataTable'; +import Icon from 'components/Icon'; + +import { compose, formattedAmount, transformUpdatedRows } from 'utils'; +import { + InputGroupCell, + MoneyFieldCell, + EstimatesListFieldCell, + PercentFieldCell, + DivFieldCell, +} from 'components/DataTableCells'; + +import withItems from 'containers/Items/withItems'; +import { omit } from 'lodash'; + +const ActionsCellRenderer = ({ + row: { index }, + column: { id }, + cell: { value }, + data, + payload, +}) => { + if (data.length <= index + 1) { + return ''; + } + const onRemoveRole = () => { + payload.removeRow(index); + }; + return ( + } position={Position.LEFT}> + + + + + + ); +} + +export default compose( + withItems(({ itemsCurrentPage }) => ({ + itemsCurrentPage, + })), +)(EstimateTable); diff --git a/client/src/containers/Sales/Estimate/EstimateActionsBar.js b/client/src/containers/Sales/Estimate/EstimateActionsBar.js new file mode 100644 index 000000000..dca9ab169 --- /dev/null +++ b/client/src/containers/Sales/Estimate/EstimateActionsBar.js @@ -0,0 +1,140 @@ +import React, { useMemo, useCallback } from 'react'; +import Icon from 'components/Icon'; +import { + Button, + Classes, + Menu, + MenuItem, + Popover, + NavbarDivider, + NavbarGroup, + PopoverInteractionKind, + Position, + Intent, +} from '@blueprintjs/core'; +import classNames from 'classnames'; +import { useRouteMatch, useHistory } from 'react-router-dom'; +import { FormattedMessage as T } from 'react-intl'; + +import { If } from 'components'; +import FilterDropdown from 'components/FilterDropdown'; +import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; + +import withResourceDetail from 'containers/Resources/withResourceDetails'; +import withDialogActions from 'containers/Dialog/withDialogActions'; +import withEstimateActions from './withEstimateActions'; + +import withEstimates from './withEstimates'; + +import { compose } from 'utils'; +import { connect } from 'react-redux'; + +function EstimateActionsBar({ + // #withResourceDetail + resourceFields, + + //#withEstimates + estimateViews, + + // #withEstimateActions + addEstimatesTableQueries, + + // #own Porps + onFilterChanged, + selectedRows, +}) { + const { path } = useRouteMatch(); + const history = useHistory(); + + const onClickNewEstimate = useCallback(() => { + // history.push('/estimates/new'); + }, [history]); + + const filterDropdown = FilterDropdown({ + initialCondition: { + fieldKey: '', + compatator: '', + value: '', + }, + fields: resourceFields, + onFilterChange: (filterConditions) => { + addEstimatesTableQueries({ + filter_roles: filterConditions || '', + }); + onFilterChanged && onFilterChange(filterConditions); + }, + }); + + const hasSelectedRows = useMemo(() => selectedRows.length > 0, [ + selectedRows, + ]); + + return ( + + + +