fix bugs.

This commit is contained in:
Ahmed Bouhuolia
2020-04-29 05:11:02 +02:00
parent f4520e4e5c
commit f6c5cae82e
42 changed files with 575 additions and 401 deletions

View File

@@ -12,19 +12,24 @@ import Progress from 'components/NProgress/Progress';
import messages from 'lang/en';
import 'style/App.scss';
function App(props) {
function App({
isAuthorized,
locale,
}) {
const history = createBrowserHistory();
history.listen((location, action) => {
console.log(`new location via ${action}`, location);
});
return (
<IntlProvider locale={props.locale} messages={messages}>
<IntlProvider locale={locale} messages={messages}>
<div className="App">
<Router history={history}>
<Authentication isAuthenticated={props.isAuthorized} />
<PrivateRoute isAuthenticated={props.isAuthorized} component={Dashboard} />
<Authentication isAuthenticated={isAuthorized} />
<PrivateRoute isAuthenticated={isAuthorized} component={Dashboard} />
</Router>
</div>
<Progress isAnimating={props.isLoading} />
</IntlProvider>
);
}
@@ -33,13 +38,10 @@ App.defaultProps = {
locale: 'en',
};
App.propTypes = {
locale: PropTypes.string,
isAuthorized: PropTypes.bool,
const mapStateToProps = (state) => {
return {
isAuthorized: isAuthenticated(state),
};
};
const mapStateToProps = (state) => ({
isAuthorized: isAuthenticated(state),
isLoading: !!state.dashboard.requestsLoading,
});
export default connect(mapStateToProps)(App);

View File

@@ -9,7 +9,8 @@ export default function DashboardContentRoute() {
<Switch>
{ routes.map((route, index) => (
<Route
key={index}
exact
// key={index}
path={`${route.path}`}
component={route.component} />
))}

View File

@@ -15,11 +15,8 @@ function DashboardTopbarUser({ logout }) {
const onClickLogout = useCallback(() => {
logout();
setTimeout(() => {
history.push('/auth/login');
}, 100);
}, [history, logout]);
history.go('/auth/login');
}, [logout, history]);
const userAvatarDropMenu = useMemo(() => (
<Menu>

View File

@@ -93,9 +93,9 @@ export default function DataTable({
...(selectionColumn) ? [{
id: 'selection',
disableResizing: true,
minWidth: 35,
width: 35,
maxWidth: 35,
minWidth: 42,
width: 42,
maxWidth: 42,
// The header can use the table's getToggleAllRowsSelectedProps method
// to render a checkbox
Header: ({ getToggleAllRowsSelectedProps }) => (

View File

@@ -22,15 +22,15 @@ import classNames from 'classnames';
import Icon from 'components/Icon';
import ItemCategoryConnect from 'connectors/ItemsCategory.connect';
import MoneyInputGroup from 'components/MoneyInputGroup';
import {useHistory} from 'react-router-dom';
const ItemForm = ({
requestSubmitItem,
accounts,
categories,
categoriesList,
}) => {
const [selectedAccounts, setSelectedAccounts] = useState({});
const history = useHistory();
const ItemTypeDisplay = useMemo(() => ([
{ value: null, label: 'Select Item Type' },
@@ -43,7 +43,7 @@ const ItemForm = ({
active: Yup.boolean(),
name: Yup.string().required(),
type: Yup.string().trim().required(),
sku: Yup.string().required(),
sku: Yup.string().trim(),
cost_price: Yup.number(),
sell_price: Yup.number(),
cost_account_id: Yup.number().required(),
@@ -71,7 +71,14 @@ const ItemForm = ({
note: '',
}), []);
const formik = useFormik({
const {
getFieldProps,
setFieldValue,
values,
touched,
errors,
handleSubmit,
} = useFormik({
enableReinitialize: true,
validationSchema: validationSchema,
initialValues: {
@@ -83,13 +90,13 @@ const ItemForm = ({
message: 'The_Items_has_been_Submit'
});
setSubmitting(false);
history.push('/dashboard/items');
})
.catch((error) => {
setSubmitting(false);
});
}
});
const {errors, values, touched} = useMemo(() => formik, [formik]);
const accountItem = useCallback((item, { handleClick }) => (
<MenuItem key={item.id} text={item.name} label={item.code} onClick={handleClick} />
@@ -112,9 +119,9 @@ const ItemForm = ({
...selectedAccounts,
[filedName]: account
});
formik.setFieldValue(filedName, account.id);
setFieldValue(filedName, account.id);
};
}, [formik, selectedAccounts]);
}, [setFieldValue, selectedAccounts]);
const categoryItem = useCallback((item, { handleClick }) => (
<MenuItem text={item.name} onClick={handleClick} />
@@ -129,12 +136,12 @@ const ItemForm = ({
const infoIcon = useMemo(() => (<Icon icon="info-circle" iconSize={12} />), []);
const handleMoneyInputChange = (fieldKey) => (e, value) => {
formik.setFieldValue(fieldKey, value);
setFieldValue(fieldKey, value);
};
return (
<div class='item-form'>
<form onSubmit={formik.handleSubmit}>
<form onSubmit={handleSubmit}>
<div class="item-form__primary-section">
<FormGroup
medium={true}
@@ -142,13 +149,13 @@ const ItemForm = ({
labelInfo={requiredSpan}
className={'form-group--item-type'}
intent={(errors.type && touched.type) && Intent.DANGER}
helperText={<ErrorMessage {...formik} name="type" />}
helperText={<ErrorMessage {...{errors, touched}} name="type" />}
inline={true}
>
<HTMLSelect
fill={true}
options={ItemTypeDisplay}
{...formik.getFieldProps('type')}
{...getFieldProps('type')}
/>
</FormGroup>
@@ -157,13 +164,13 @@ const ItemForm = ({
labelInfo={requiredSpan}
className={'form-group--item-name'}
intent={(errors.name && touched.name) && Intent.DANGER}
helperText={<ErrorMessage {...formik} name="name" />}
helperText={<ErrorMessage {...{errors, touched}} name="name" />}
inline={true}
>
<InputGroup
medium={true}
intent={(errors.name && touched.name) && Intent.DANGER}
{...formik.getFieldProps('name')}
{...getFieldProps('name')}
/>
</FormGroup>
@@ -172,13 +179,13 @@ const ItemForm = ({
labelInfo={infoIcon}
className={'form-group--item-sku'}
intent={(errors.sku && touched.sku) && Intent.DANGER}
helperText={<ErrorMessage {...formik} name="sku" />}
helperText={<ErrorMessage {...{errors, touched}} name="sku" />}
inline={true}
>
<InputGroup
medium={true}
intent={(errors.sku && touched.sku) && Intent.DANGER}
{...formik.getFieldProps('sku')}
{...getFieldProps('sku')}
/>
</FormGroup>
@@ -187,7 +194,7 @@ const ItemForm = ({
labelInfo={infoIcon}
inline={true}
intent={(errors.category_id && touched.category_id) && Intent.DANGER}
helperText={<ErrorMessage {...formik} name="category" />}
helperText={<ErrorMessage {...{errors, touched}} name="category" />}
className={classNames(
'form-group--select-list',
'form-group--category',
@@ -195,7 +202,7 @@ const ItemForm = ({
)}
>
<Select
items={categoriesList}
items={categories}
itemRenderer={categoryItem}
itemPredicate={filterAccounts}
popoverProps={{ minimal: true }}
@@ -218,7 +225,7 @@ const ItemForm = ({
inline={true}
label={'Active'}
defaultChecked={values.active}
{...formik.getFieldProps('active')}
{...getFieldProps('active')}
/>
</FormGroup>
</div>
@@ -231,7 +238,7 @@ const ItemForm = ({
label={'Selling Price'}
className={'form-group--item-selling-price'}
intent={(errors.selling_price && touched.selling_price) && Intent.DANGER}
helperText={<ErrorMessage {...formik} name="selling_price" />}
helperText={<ErrorMessage {...{errors, touched}} name="selling_price" />}
inline={true}
>
<MoneyInputGroup
@@ -249,7 +256,7 @@ const ItemForm = ({
labelInfo={infoIcon}
inline={true}
intent={(errors.sell_account_id && touched.sell_account_id) && Intent.DANGER}
helperText={<ErrorMessage {...formik} name="sell_account_id" />}
helperText={<ErrorMessage {...{errors, touched}} name="sell_account_id" />}
className={classNames(
'form-group--sell-account',
'form-group--select-list',
@@ -280,7 +287,7 @@ const ItemForm = ({
label={'Cost Price'}
className={'form-group--item-cost-price'}
intent={(errors.cost_price && touched.cost_price) && Intent.DANGER}
helperText={<ErrorMessage {...formik} name="cost_price" />}
helperText={<ErrorMessage {...{errors, touched}} name="cost_price" />}
inline={true}
>
<MoneyInputGroup
@@ -298,7 +305,7 @@ const ItemForm = ({
labelInfo={infoIcon}
inline={true}
intent={(errors.cost_account_id && touched.cost_account_id) && Intent.DANGER}
helperText={<ErrorMessage {...formik} name="cost_account_id" />}
helperText={<ErrorMessage {...{errors, touched}} name="cost_account_id" />}
className={classNames(
'form-group--cost-account',
'form-group--select-list',
@@ -331,7 +338,7 @@ const ItemForm = ({
label={'Inventory Account'}
inline={true}
intent={(errors.inventory_account_id && touched.inventory_account_id) && Intent.DANGER}
helperText={<ErrorMessage {...formik} name="inventory_account_id" />}
helperText={<ErrorMessage {...{errors, touched}} name="inventory_account_id" />}
className={classNames(
'form-group--item-inventory_account',
'form-group--select-list',
@@ -361,8 +368,8 @@ const ItemForm = ({
>
<InputGroup
medium={true}
intent={formik.errors.stock && Intent.DANGER}
{...formik.getFieldProps('stock')}
intent={errors.stock && Intent.DANGER}
{...getFieldProps('stock')}
/>
</FormGroup>
</Col>

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useCallback, useState, useMemo } from 'react';
import React, { useCallback, useMemo } from 'react';
import Icon from 'components/Icon';
import ItemsCategoryConnect from 'connectors/ItemsCategory.connect';
import DialogConnect from 'connectors/Dialog.connector';
@@ -11,8 +11,6 @@ import {
Menu,
MenuItem,
Position,
Classes,
Tooltip,
} from '@blueprintjs/core';
const ItemsCategoryList = ({
@@ -22,6 +20,7 @@ const ItemsCategoryList = ({
onEditCategory,
openDialog,
count,
onSelectedRowsChange,
}) => {
const handelEditCategory = (category) => () => {
openDialog('item-form', { action: 'edit', id: category.id });
@@ -42,51 +41,51 @@ const ItemsCategoryList = ({
</Menu>
);
const columns = useMemo(
() => [
{
id: 'name',
Header: 'Category Name',
accessor: 'name',
width: 150,
},
{
id: 'description',
Header: 'Description',
accessor: 'description',
className: 'description',
width: 150,
},
{
id: 'count',
Header: 'Count',
accessor: () => <span>{count}</span>,
className: 'count',
width: 50,
},
{
id: 'actions',
Header: '',
Cell: ({ cell }) => (
<Popover
content={actionMenuList(cell.row.original)}
position={Position.RIGHT_BOTTOM}
>
<Button icon={<Icon icon='ellipsis-h' />} />
</Popover>
),
className: 'actions',
width: 50,
// canResize: false
},
],
[]
);
const columns = useMemo(() => [
{
id: 'name',
Header: 'Category Name',
accessor: 'name',
width: 150,
},
{
id: 'description',
Header: 'Description',
accessor: 'description',
className: 'description',
width: 150,
},
{
id: 'count',
Header: 'Count',
accessor: (r) => r.count || '',
className: 'count',
width: 50,
},
{
id: 'actions',
Header: '',
Cell: ({ cell }) => (
<Popover
content={actionMenuList(cell.row.original)}
position={Position.RIGHT_BOTTOM}
>
<Button icon={<Icon icon='ellipsis-h' />} />
</Popover>
),
className: 'actions',
width: 50,
disableResizing: false
},
], [actionMenuList]);
const handelFetchData = useCallback(() => {
onFetchData && onFetchData();
}, []);
const handleSelectedRowsChange = useCallback((selectedRows) => {
onSelectedRowsChange && onSelectedRowsChange(selectedRows.map(s => s.original));
}, [onSelectedRowsChange]);
return (
<LoadingIndicator spinnerSize={30}>
@@ -97,10 +96,13 @@ const ItemsCategoryList = ({
manualSortBy={true}
selectionColumn={true}
expandable={true}
treeGraph={true}
onSelectedRowsChange={handleSelectedRowsChange}
/>
</LoadingIndicator>
);
};
export default compose(DialogConnect, ItemsCategoryConnect)(ItemsCategoryList);
export default compose(
DialogConnect,
ItemsCategoryConnect,
)(ItemsCategoryList);

View File

@@ -25,7 +25,9 @@ function ManualJournalActionsBar({
views,
getResourceFields,
addManualJournalsTableQueries,
onFilterChanged
onFilterChanged,
selectedRows,
onBulkDelete
}) {
const { path } = useRouteMatch();
const history = useHistory();
@@ -50,6 +52,13 @@ function ManualJournalActionsBar({
onFilterChanged && onFilterChanged(filterConditions);
}
});
const hasSelectedRows = useMemo(() => selectedRows.length > 0, [selectedRows]);
// Handle delete button click.
const handleBulkDelete = useCallback(() => {
onBulkDelete && onBulkDelete(selectedRows.map(r => r.id));
}, [onBulkDelete, selectedRows]);
return (
<DashboardActionsBar>
<NavbarGroup>
@@ -85,12 +94,13 @@ function ManualJournalActionsBar({
/>
</Popover>
{ (false) && (
{(hasSelectedRows) && (
<Button
className={Classes.MINIMAL}
icon={<Icon icon='trash' iconSize={15} />}
text='Delete'
intent={Intent.DANGER}
onClick={handleBulkDelete}
/>
)}
<Button

View File

@@ -8,7 +8,7 @@ import {
MenuDivider,
Position,
} from '@blueprintjs/core';
import { useParams, useHistory } from 'react-router-dom';
import { useParams } from 'react-router-dom';
import Icon from 'components/Icon';
import { compose } from 'utils';
import moment from 'moment';
@@ -16,7 +16,7 @@ import ManualJournalsConnect from 'connectors/ManualJournals.connect';
import DialogConnect from 'connectors/Dialog.connector';
import DashboardConnect from 'connectors/Dashboard.connector';
import ViewConnect from 'connectors/View.connector';
import LoadingIndicator from 'components/LoadingIndicator';
import { useUpdateEffect } from 'hooks';
import DataTable from 'components/DataTable';
import Money from 'components/Money';
@@ -31,8 +31,16 @@ function ManualJournalsDataTable({
onEditJournal,
onDeleteJournal,
onPublishJournal,
onSelectedRowsChange,
}) {
const { custom_view_id: customViewId } = useParams();
const [initialMount, setInitialMount] = useState(false);
useUpdateEffect(() => {
if (!manualJournalsLoading) {
setInitialMount(true);
}
}, [manualJournalsLoading, setInitialMount]);
useEffect(() => {
const viewMeta = getViewItem(customViewId);
@@ -42,7 +50,25 @@ function ManualJournalsDataTable({
setTopbarEditView(customViewId);
}
changePageSubtitle(customViewId && viewMeta ? viewMeta.name : '');
}, [customViewId]);
}, [
customViewId,
changeCurrentView,
changePageSubtitle,
setTopbarEditView,
getViewItem,
]);
const handlePublishJournal = useCallback((journal) => () => {
onPublishJournal && onPublishJournal(journal);
}, [onPublishJournal]);
const handleEditJournal = useCallback((journal) => () => {
onEditJournal && onEditJournal(journal);
}, [onEditJournal]);
const handleDeleteJournal = useCallback((journal) => () => {
onDeleteJournal && onDeleteJournal(journal);
}, [onDeleteJournal]);
const actionMenuList = (journal) => (
<Menu>
@@ -51,21 +77,15 @@ function ManualJournalsDataTable({
{!journal.status && (
<MenuItem
text="Publish Journal"
onClick={() => {
onPublishJournal && onPublishJournal(journal);
}} />
onClick={handlePublishJournal(journal)} />
)}
<MenuItem
text='Edit Journal'
onClick={() => {
onEditJournal && onEditJournal(journal);
}} />
onClick={handleEditJournal(journal)} />
<MenuItem
text='Delete Journal'
intent={Intent.DANGER}
onClick={() => {
onDeleteJournal && onDeleteJournal(journal);
}} />
onClick={handleDeleteJournal(journal)} />
</Menu>
);
@@ -143,26 +163,25 @@ function ManualJournalsDataTable({
},
], []);
const handleDataTableFetchData = useCallback(() => {
onFetchData && onFetchData();
const handleDataTableFetchData = useCallback((...args) => {
onFetchData && onFetchData(...args);
}, [onFetchData]);
const selectionColumn = useMemo(() => ({
minWidth: 42,
width: 42,
maxWidth: 42,
}), []);
const handleSelectedRowsChange = useCallback((selectedRows) => {
onSelectedRowsChange && onSelectedRowsChange(selectedRows.map(s => s.original));
}, [onSelectedRowsChange]);
return (
<LoadingIndicator loading={manualJournalsLoading} spinnerSize={30}>
<DataTable
columns={columns}
data={manualJournals}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={selectionColumn}
/>
</LoadingIndicator>
<DataTable
columns={columns}
data={manualJournals}
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
noInitialFetch={true}
loading={manualJournalsLoading && !initialMount}
onSelectedRowsChange={handleSelectedRowsChange}
/>
);
}

View File

@@ -0,0 +1,18 @@
import React from 'react';
import {connect} from 'react-redux';
import Progress from './Progress';
function AppProgress({
isAnimating,
}) {
return (
<Progress isAnimating={isAnimating} />
);
};
const mapStateToProps = (state) => ({
isAnimating: state.dashboard.requestsLoading > 0,
});
export default connect(mapStateToProps)(AppProgress);

View File

@@ -21,8 +21,11 @@ export default function SidebarMenu() {
};
return (
(item.divider) ?
<MenuDivider title={item.title} /> :
<MenuDivider
key={index}
title={item.title} /> :
<MenuItem
key={index}
active={isActive}
icon={<Icon icon={item.icon} iconSize={item.iconSize} />}
text={item.text}