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,17 +12,17 @@ import moment from 'moment';
import {momentFormatter} from 'utils';
import Icon from 'components/Icon';
import CurrenciesSelectList from 'components/CurrenciesSelectList';
import ErrorMessage from 'components/ErrorMessage';
export default function MakeJournalEntriesHeader({
formik
formik: { errors, touched, setFieldValue, getFieldProps }
}) {
const intl = useIntl();
const handleDateChange = useCallback((date) => {
const formatted = moment(date).format('YYYY-MM-DD');
formik.setFieldValue('date', formatted);
}, [formik]);
setFieldValue('date', formatted);
}, [setFieldValue]);
const infoIcon = useMemo(() =>
(<Icon icon="info-circle" iconSize={12} />), []);
@@ -35,22 +35,22 @@ export default function MakeJournalEntriesHeader({
label={'Journal number'}
labelInfo={infoIcon}
className={'form-group--journal-number'}
intent={formik.errors.journal_number && Intent.DANGER}
helperText={formik.errors.journal_number && formik.errors.journal_number}
intent={(errors.journal_number && touched.journal_number) && Intent.DANGER}
helperText={<ErrorMessage name="journal_number" {...{errors, touched}} />}
fill={true}>
<InputGroup
intent={formik.errors.journal_number && Intent.DANGER}
intent={(errors.journal_number && touched.journal_number) && Intent.DANGER}
fill={true}
{...formik.getFieldProps('journal_number')} />
{...getFieldProps('journal_number')} />
</FormGroup>
</Col>
<Col sm={2}>
<FormGroup
label={intl.formatMessage({'id': 'date'})}
intent={formik.errors.date && Intent.DANGER}
helperText={formik.errors.date && formik.errors.date}
intent={(errors.date && touched.date) && Intent.DANGER}
helperText={<ErrorMessage name="date" {...{errors, touched}} />}
minimal={true}>
<DateInput
@@ -65,14 +65,14 @@ export default function MakeJournalEntriesHeader({
<FormGroup
label={intl.formatMessage({'id': 'description'})}
className={'form-group--description'}
intent={formik.errors.name && Intent.DANGER}
helperText={formik.errors.name && formik.errors.label}
intent={(errors.name && touched.name) && Intent.DANGER}
helperText={<ErrorMessage name="description" {...{errors, touched}} />}
fill={true}>
<InputGroup
intent={formik.errors.name && Intent.DANGER}
intent={(errors.name && touched.name) && Intent.DANGER}
fill={true}
{...formik.getFieldProps('description')} />
{...getFieldProps('description')} />
</FormGroup>
</Col>
</Row>
@@ -83,14 +83,14 @@ export default function MakeJournalEntriesHeader({
label={'Reference'}
labelInfo={infoIcon}
className={'form-group--reference'}
intent={formik.errors.reference && Intent.DANGER}
helperText={formik.errors.reference && formik.errors.reference}
intent={(errors.reference && touched.reference) && Intent.DANGER}
helperText={<ErrorMessage name="reference" {...{errors, touched}} />}
fill={true}>
<InputGroup
intent={formik.errors.reference && Intent.DANGER}
intent={(errors.reference && touched.reference) && Intent.DANGER}
fill={true}
{...formik.getFieldProps('reference')} />
{...getFieldProps('reference')} />
</FormGroup>
</Col>

View File

@@ -2,7 +2,7 @@ import React, {useMemo, useCallback} from 'react';
import { useParams, useHistory } from 'react-router-dom';
import { useAsync } from 'react-use';
import MakeJournalEntriesForm from './MakeJournalEntriesForm';
import LoadingIndicator from 'components/LoadingIndicator';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import DashboardConnect from 'connectors/Dashboard.connector';
import {compose} from 'utils';
import MakeJournalEntriesConnect from 'connectors/MakeJournalEntries.connect';
@@ -36,12 +36,12 @@ function MakeJournalEntriesPage({
}, [history]);
return (
<LoadingIndicator loading={fetchJournal.loading} mount={false}>
<DashboardInsider loading={fetchJournal.pending} name={'make-journal-page'}>
<MakeJournalEntriesForm
onFormSubmit={handleFormSubmit}
editJournal={editJournal}
onCancelForm={handleCancel} />
</LoadingIndicator>
</DashboardInsider>
);
}

View File

@@ -7,7 +7,7 @@ import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import ManualJournalsViewTabs from 'components/JournalEntry/ManualJournalsViewTabs';
import ManualJournalsDataTable from 'components/JournalEntry/ManualJournalsDataTable';
import DashboardActionsBar from 'components/JournalEntry/ManualJournalActionsBar';
import ManualJournalsActionsBar from 'components/JournalEntry/ManualJournalActionsBar';
import ManualJournalsConnect from 'connectors/ManualJournals.connect';
import DashboardConnect from 'connectors/Dashboard.connector';
import CustomViewConnect from 'connectors/CustomView.connector';
@@ -16,13 +16,20 @@ import { compose } from 'utils';
function ManualJournalsTable({
changePageTitle,
fetchResourceViews,
fetchManualJournalsTable,
requestDeleteManualJournal,
requestPublishManualJournal,
requestDeleteBulkManualJournals,
addManualJournalsTableQueries
}) {
const history = useHistory();
const [deleteManualJournal, setDeleteManualJournal] = useState(false);
const [selectedRows, setSelectedRows] = useState([]);
const [bulkDelete, setBulkDelete] = useState(false);
const fetchHook = useAsync(async () => {
await Promise.all([
@@ -32,16 +39,23 @@ function ManualJournalsTable({
const fetchManualJournalsHook = useAsync(async () => {
return fetchManualJournalsTable();
}, false);
});
useEffect(() => {
changePageTitle('Manual Journals');
}, []);
}, [changePageTitle]);
const handleCancelManualJournalDelete = () => {
// Handle delete manual journal click.
const handleDeleteJournal = useCallback((journal) => {
setDeleteManualJournal(journal);
}, [setDeleteManualJournal]);
// Handle cancel delete manual journal.
const handleCancelManualJournalDelete = useCallback(() => {
setDeleteManualJournal(false);
};
}, [setDeleteManualJournal]);
// Handle confirm delete manual journal.
const handleConfirmManualJournalDelete = useCallback(() => {
requestDeleteManualJournal(deleteManualJournal.id).then(() => {
setDeleteManualJournal(false);
@@ -49,25 +63,53 @@ function ManualJournalsTable({
});
}, [deleteManualJournal, requestDeleteManualJournal]);
const handleBulkDelete = useCallback((accountsIds) => {
setBulkDelete(accountsIds);
}, [setBulkDelete]);
const handleConfirmBulkDelete = useCallback(() => {
requestDeleteBulkManualJournals(bulkDelete).then(() => {
setBulkDelete(false);
AppToaster.show({ message: 'the_accounts_have_been_deleted' });
}).catch((error) => {
setBulkDelete(false);
});
}, [
requestDeleteBulkManualJournals,
bulkDelete,
]);
const handleCancelBulkDelete = useCallback(() => {
setBulkDelete(false);
}, []);
const handleEditJournal = useCallback((journal) => {
history.push(`/dashboard/accounting/manual-journals/${journal.id}/edit`);
}, [history]);
const handleDeleteJournal = useCallback((journal) => {
setDeleteManualJournal(journal);
}, []);
// Handle filter change to re-fetch data-table.
const handleFilterChanged = useCallback(() => {
fetchManualJournalsHook.execute();
}, []);
}, [fetchManualJournalsHook]);
// Handle view change to re-fetch data table.
const handleViewChanged = useCallback(() => {
fetchManualJournalsHook.execute();
}, []);
}, [fetchManualJournalsHook]);
const handleFetchData = useCallback(() => {
// Handle fetch data of manual jouranls datatable.
const handleFetchData = useCallback(({ pageIndex, pageSize, sortBy }) => {
addManualJournalsTableQueries({
...(sortBy.length > 0) ? {
column_sort_by: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
} : {},
});
fetchManualJournalsHook.execute();
}, []);
}, [
fetchManualJournalsHook,
addManualJournalsTableQueries,
]);
const handlePublishJournal = useCallback((journal) => {
requestPublishManualJournal(journal.id).then(() => {
@@ -75,9 +117,16 @@ function ManualJournalsTable({
})
}, [requestPublishManualJournal]);
// Handle selected rows change.
const handleSelectedRowsChange = useCallback((accounts) => {
setSelectedRows(accounts);
}, [setSelectedRows]);
return (
<DashboardInsider loading={fetchHook.pending} name={'manual-journals'}>
<DashboardActionsBar
<ManualJournalsActionsBar
onBulkDelete={handleBulkDelete}
selectedRows={selectedRows}
onFilterChanged={handleFilterChanged} />
<DashboardPageContent>
@@ -97,7 +146,8 @@ function ManualJournalsTable({
onDeleteJournal={handleDeleteJournal}
onFetchData={handleFetchData}
onEditJournal={handleEditJournal}
onPublishJournal={handlePublishJournal} />
onPublishJournal={handlePublishJournal}
onSelectedRowsChange={handleSelectedRowsChange} />
<Alert
cancelButtonText='Cancel'
@@ -113,6 +163,21 @@ function ManualJournalsTable({
able to restore it later, but it will become private to you.
</p>
</Alert>
<Alert
cancelButtonText='Cancel'
confirmButtonText='Move to Trash'
icon='trash'
intent={Intent.DANGER}
isOpen={bulkDelete}
onCancel={handleCancelBulkDelete}
onConfirm={handleConfirmBulkDelete}
>
<p>
Are you sure you want to move <b>filename</b> to Trash? You will be
able to restore it later, but it will become private to you.
</p>
</Alert>
</DashboardPageContent>
</DashboardInsider>
);

View File

@@ -26,8 +26,6 @@ function AccountsChart({
requestFetchAccountsTable,
addAccountsTableQueries,
requestDeleteBulkAccounts,
setDashboardRequestLoading,
setDashboardRequestCompleted,
}) {
const [deleteAccount, setDeleteAccount] = useState(false);
const [inactiveAccount, setInactiveAccount] = useState(false);
@@ -36,23 +34,17 @@ function AccountsChart({
// Fetch accounts resource views and fields.
const fetchHook = useAsync(async () => {
setDashboardRequestLoading();
await Promise.all([
fetchResourceViews('accounts'),
fetchResourceFields('accounts'),
]);
setDashboardRequestCompleted();
});
// Fetch accounts list according to the given custom view id.
const fetchAccountsHook = useAsync(async () => {
setDashboardRequestLoading();
await Promise.all([
requestFetchAccountsTable(),
]);
setDashboardRequestCompleted();
}, false);
useEffect(() => {
@@ -102,7 +94,7 @@ function AccountsChart({
requestFetchAccountsTable();
AppToaster.show({ message: 'the_account_has_been_inactivated' });
});
}, [inactiveAccount]);
}, [inactiveAccount, requestFetchAccountsTable, requestInactiveAccount]);
const handleEditAccount = (account) => {

View File

@@ -8,11 +8,7 @@ import {
FormGroup,
InputGroup,
Intent,
TextArea,
MenuItem,
Checkbox,
Classes,
HTMLSelect,
} from '@blueprintjs/core';
import UserFormDialogConnect from 'connectors/UserFormDialog.connector';
import DialogReduxConnect from 'components/DialogReduxConnect';
@@ -22,7 +18,6 @@ import { objectKeysTransform } from 'utils';
import { pick, snakeCase } from 'lodash';
import ErrorMessage from 'components/ErrorMessage';
import classNames from 'classnames';
import Icon from 'components/Icon';
import { compose } from 'utils';
function UserFormDialog({
@@ -32,7 +27,6 @@ function UserFormDialog({
name,
payload,
isOpen,
userDetails,
closeDialog,
}) {
const intl = useIntl();
@@ -84,11 +78,6 @@ function UserFormDialog({
});
const { values, errors, touched } = useMemo(() => formik, [formik]);
const statusOptions = [
{ value: 1, label: 'Active' },
{ value: 2, label: 'Inactive' },
];
const onDialogOpening = () => {
fetchHook.execute();
};

View File

@@ -15,11 +15,12 @@ const ItemFormContainer = ({
requestFetchItemCategories,
}) => {
const { id } = useParams();
useEffect(() => {
id ?
changePageTitle('Edit Item Details') :
changePageTitle('New Item');
}, []);
}, [id, changePageTitle]);
const fetchHook = useAsync(async () => {
await Promise.all([

View File

@@ -29,8 +29,8 @@ const ItemsActionsBar = ({
getResourceViews,
views,
onFilterChanged,
bulkSelected,
addItemsTableQueries,
selectedRows = [],
}) => {
const { path } = useRouteMatch();
const history = useHistory();
@@ -43,6 +43,7 @@ const ItemsActionsBar = ({
history.push('/dashboard/items/new');
};
const itemsFields = getResourceFields('items');
const hasSelectedRows = useMemo(() => selectedRows.length > 0, [selectedRows]);
const filterDropdown = FilterDropdown({
fields: itemsFields,
@@ -54,12 +55,7 @@ const ItemsActionsBar = ({
onFilterChanged && onFilterChanged(filterConditions);
}
});
const hasBulkActionsSelected = useMemo(
() => !!Object.keys(bulkSelected).length,
[bulkSelected]
);
const onClickNewCategory = useCallback(() => {
openDialog('item-form', {});
}, [openDialog]);
@@ -108,7 +104,7 @@ const ItemsActionsBar = ({
onClick={onClickNewCategory}
/>
{hasBulkActionsSelected && (
{hasSelectedRows && (
<Button
className={Classes.MINIMAL}
intent={Intent.DANGER}

View File

@@ -1,7 +1,5 @@
import React, { useMemo } from 'react';
import {} from 'reselect';
import React, { useCallback, useMemo } from 'react';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import { compose } from 'utils';
import {
NavbarGroup,
@@ -20,21 +18,24 @@ import DialogConnect from 'connectors/Dialog.connector';
import FilterDropdown from 'components/FilterDropdown';
import ResourceConnect from 'connectors/Resource.connector';
const ItemsCategoryActionsBar = ({
openDialog,
onDeleteCategory,
onFilterChanged,
getResourceFields,
selectedRows,
}) => {
const onClickNewCategory = () => {
const onClickNewCategory = useCallback(() => {
openDialog('item-form', {});
};
}, [openDialog]);
const handleDeleteCategory = (category) => {
onDeleteCategory(category);
};
const handleDeleteCategory = useCallback((category) => {
onDeleteCategory(selectedRows);
}, [selectedRows, onDeleteCategory]);
const categoriesFields = getResourceFields('itemCategories');
const hasSelectedRows = useMemo(() => selectedRows.length > 0, [selectedRows]);
const filterDropdown = FilterDropdown({
fields: categoriesFields,
@@ -63,14 +64,15 @@ const ItemsCategoryActionsBar = ({
/>
</Popover>
<Button
className={Classes.MINIMAL}
icon={<Icon icon='trash' iconSize={15} />}
text='Delete Category'
intent={Intent.DANGER}
onClick={handleDeleteCategory}
/>
{ hasSelectedRows && (
<Button
className={Classes.MINIMAL}
icon={<Icon icon='trash' iconSize={15} />}
text='Delete'
intent={Intent.DANGER}
onClick={handleDeleteCategory}
/>
)}
<Button
className={Classes.MINIMAL}
icon={<Icon icon='file-import' />}

View File

@@ -20,25 +20,29 @@ const ItemCategoriesList = ({
}) => {
const { id } = useParams();
const [deleteCategory, setDeleteCategory] = useState(false);
const [selectedRows, setSelectedRows] = useState([]);
useEffect(() => {
id
? changePageTitle('Edit Item Details')
: changePageTitle('Categories List');
}, []);
}, [id, changePageTitle]);
const fetchHook = useAsync(async () => {
await Promise.all([requestFetchItemCategories()]);
await Promise.all([
requestFetchItemCategories(),
]);
}, false);
const handelDeleteCategory = category => {
const handelDeleteCategory = useCallback((category) => {
setDeleteCategory(category);
};
}, [setDeleteCategory]);
const handelEditCategory = category => {};
const handelCancelCategoryDelete = () => {
const handelCancelCategoryDelete = useCallback(() => {
setDeleteCategory(false);
};
}, [setDeleteCategory]);
const handelConfirmCategoryDelete = useCallback(() => {
requestDeleteItemCategory(deleteCategory.id).then(() => {
@@ -47,23 +51,30 @@ const ItemCategoriesList = ({
message: 'the_category_has_been_delete'
});
});
}, [deleteCategory]);
}, [deleteCategory, requestDeleteItemCategory, setDeleteCategory]);
const handleFetchData = useCallback(() => {
fetchHook.execute();
}, []);
// Handle selected rows change.
const handleSelectedRowsChange = useCallback((accounts) => {
setSelectedRows(accounts);
}, [setSelectedRows]);
return (
<DashboardInsider loading={fetchHook.pending}>
<ItemsCategoryActionsBar
views={views}
onDeleteCategory={handelDeleteCategory}
selectedRows={selectedRows}
/>
<DashboardPageContent>
<ItemsCategoryList
onDeleteCategory={handelDeleteCategory}
onFetchData={handleFetchData}
onEditCategory={handelEditCategory}
categories
onSelectedRowsChange={handleSelectedRowsChange}
/>
<Alert

View File

@@ -1,4 +1,4 @@
import React, {useEffect, useCallback, useMemo} from 'react';
import React, {useState, useEffect, useCallback, useMemo} from 'react';
import {
Button,
Popover,
@@ -7,7 +7,6 @@ import {
MenuDivider,
Position,
} from '@blueprintjs/core'
import LoadingIndicator from 'components/LoadingIndicator';
import CustomViewConnect from 'connectors/View.connector';
import ItemsConnect from 'connectors/Items.connect';
import {compose} from 'utils';
@@ -22,7 +21,16 @@ const ItemsDataTable = ({
onEditItem,
onDeleteItem,
onFetchData,
onSelectedRowsChange,
}) => {
const [initialMount, setInitialMount] = useState(false);
useEffect(() => {
if (!itemsTableLoading) {
setInitialMount(true);
}
}, [itemsTableLoading, setInitialMount]);
const handleEditItem = (item) => () => { onEditItem(item); };
const handleDeleteItem = (item) => () => { onDeleteItem(item); };
@@ -75,7 +83,6 @@ const ItemsDataTable = ({
// accessor: 'inventory_account.name',
// className: "inventory-account",
// },
{
id: 'actions',
Cell: ({ cell }) => (
@@ -98,16 +105,21 @@ const ItemsDataTable = ({
const handleFetchData = useCallback((...args) => {
onFetchData && onFetchData(...args)
}, [onFetchData])
}, [onFetchData]);
const handleSelectedRowsChange = useCallback((selectedRows) => {
onSelectedRowsChange && onSelectedRowsChange(selectedRows.map(s => s.original));
}, [onSelectedRowsChange]);
return (
<LoadingIndicator loading={itemsTableLoading} spinnerSize={30}>
<DataTable
columns={columns}
data={currentPageItems}
selectionColumn={selectionColumn}
onFetchData={handleFetchData} />
</LoadingIndicator>
<DataTable
columns={columns}
data={currentPageItems}
selectionColumn={selectionColumn}
onFetchData={handleFetchData}
loading={itemsTableLoading && !initialMount}
noInitialFetch={true}
onSelectedRowsChange={handleSelectedRowsChange} />
);
};

View File

@@ -31,6 +31,7 @@ function ItemsList({
addItemsTableQueries,
}) {
const [deleteItem, setDeleteItem] = useState(false);
const [selectedRows, setSelectedRows] = useState([]);
useEffect(() => {
changePageTitle('Items List');
@@ -49,16 +50,19 @@ function ItemsList({
])
});
// Handle click delete item.
const handleDeleteItem = useCallback((item) => {
setDeleteItem(item);
}, [setDeleteItem]);
const handleEditItem = () => {};
// Handle cancel delete the item.
const handleCancelDeleteItem = useCallback(() => {
setDeleteItem(false);
}, [setDeleteItem]);
// handle confirm delete item.
const handleConfirmDeleteItem = useCallback(() => {
requestDeleteItem(deleteItem.id).then(() => {
AppToaster.show({ message: 'the_item_has_been_deleted' });
@@ -69,25 +73,33 @@ function ItemsList({
const handleFetchData = useCallback(({ pageIndex, pageSize, sortBy }) => {
addItemsTableQueries({
...(sortBy.length > 0) ? {
column_sort_by: sortBy[0].id,
sort_by: sortBy[0].desc ? 'desc' : 'asc',
column_sort_order: sortBy[0].id,
sort_order: sortBy[0].desc ? 'desc' : 'asc',
} : {},
});
fetchItems.execute();
}, [fetchItems, addItemsTableQueries]);
// Handle filter change to re-fetch the items.
const handleFilterChanged = useCallback(() => {
fetchItems.execute();
}, [fetchItems]);
// Handle custom view change to re-fetch the items.
const handleCustomViewChanged = useCallback(() => {
fetchItems.execute();
}, [fetchItems]);
// Handle selected rows change.
const handleSelectedRowsChange = useCallback((accounts) => {
setSelectedRows(accounts);
}, [setSelectedRows]);
return (
<DashboardInsider isLoading={fetchHook.pending} name={'items-list'}>
<ItemsActionsBar
onFilterChanged={handleFilterChanged}
selectedRows={selectedRows}
views={views} />
<DashboardPageContent>
@@ -98,12 +110,14 @@ function ItemsList({
'/dashboard/items/:custom_view_id/custom_view',
'/dashboard/items'
]}>
<ItemsViewsTabs onViewChanged={handleCustomViewChanged} />
<ItemsViewsTabs
onViewChanged={handleCustomViewChanged} />
<ItemsDataTable
onDeleteItem={handleDeleteItem}
onEditItem={handleEditItem}
onFetchData={handleFetchData} />
onFetchData={handleFetchData}
onSelectedRowsChange={handleSelectedRowsChange} />
<Alert
cancelButtonText="Cancel"

View File

@@ -1,25 +1,24 @@
import React from 'react';
import React, {useCallback} from 'react';
import {
Tabs,
Tab,
Button,
Intent,
} from '@blueprintjs/core';
import { useHistory } from 'react-router-dom';
import PreferencesSubContent from 'components/Preferences/PreferencesSubContent';
import connector from 'connectors/UsersPreferences.connector';
function UsersPreferences({
openDialog,
}) {
const history = useHistory();
const onChangeTabs = (currentTabId) => {
};
const onClickNewUser = () => {
const onClickNewUser = useCallback(() => {
openDialog('user-form');
};
}, [openDialog]);
return (
<div class="preferences__inside-content preferences__inside-content--users-roles">
<div class="preferences__tabs">