From 71cc561bb2087087e56cd0c21567e2640d4bd1c3 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Fri, 8 May 2020 04:36:04 +0200 Subject: [PATCH] WIP Version 0.0.1 --- client/package.json | 2 + client/src/components/App.js | 21 ++- client/src/components/Authentication.js | 2 +- client/src/components/Dashboard/Dashboard.js | 2 +- client/src/components/DialogsContainer.js | 10 +- .../src/components/Items/ItemsActionsBar.js | 13 -- .../JournalEntry/MakeJournalEntry.js | 94 ------------ .../src/components/NProgress/AppProgress.js | 16 +- .../Preferences/PreferencesTopbar.js | 4 +- client/src/components/Utils/Choose.js | 33 ++++ client/src/components/Utils/For.js | 11 ++ client/src/components/Utils/If.js | 13 ++ client/src/components/index.js | 9 ++ .../connectors/AccountFormDialog.connector.js | 13 -- client/src/connectors/CustomView.connector.js | 14 -- client/src/connectors/Dashboard.connector.js | 6 +- client/src/connectors/RegisterForm.connect.js | 12 -- client/src/connectors/Resource.connector.js | 14 +- client/src/connectors/View.connector.js | 25 --- .../src/connectors/ViewFormPage.connector.js | 29 ---- .../Accounting/MakeJournalEntriesFooter.js | 0 .../Accounting/MakeJournalEntriesForm.js | 102 +++++++------ .../Accounting/MakeJournalEntriesHeader.js | 0 .../Accounting/MakeJournalEntriesPage.js | 41 +++-- .../Accounting/MakeJournalEntriesTable.js | 9 +- .../Accounting}/ManualJournalActionsBar.js | 26 ++-- .../Accounting}/ManualJournalsDataTable.js | 56 ++++--- .../ManualJournalsList.js} | 61 ++++---- .../Accounting}/ManualJournalsViewTabs.js | 0 .../Accounting/withJournalDetail.js | 10 ++ .../Accounting/withJournalsActions.js | 14 ++ .../Accounting/withManualJournalDetail.js | 9 ++ .../Accounting/withManualJournals.js | 16 ++ .../Accounting/withManualJournalsActions.js | 28 ++++ .../Accounts/AccountsActionsBar.js | 54 ++++--- .../{Dashboard => }/Accounts/AccountsChart.js | 88 +++++++---- .../Accounts/AccountsDataTable.js | 44 +++--- .../Accounts/AccountsViewsTabs.js | 85 +++++++---- .../containers/Accounts/withAccountDetail.js | 10 ++ .../src/containers/Accounts/withAccounts.js | 19 +++ .../Accounts/withAccountsActions.js | 22 +++ .../Accounts/withAccountsTableActions.js | 24 +++ .../containers/Authentication/InviteAccept.js | 7 +- client/src/containers/Authentication/Login.js | 8 +- .../src/containers/Authentication/Register.js | 9 +- .../Authentication/ResetPassword.js | 5 +- .../Authentication/SendResetPassword.js | 12 +- .../withAuthenticationActions.js} | 5 +- .../Dashboard/Items/ItemCategoryList.js | 24 --- .../containers/Dashboard/Items/ItemForm.js | 43 ------ .../Dashboard/Items/ItemsCategoryList.js | 102 ------------- .../Dashboard/Views/ViewFormPage.js | 101 ------------- .../src/containers/Dashboard/withDashboard.js | 27 ++++ .../Dialogs/AccountFormDialog.container.js | 30 ++++ .../Dialogs/AccountFormDialog.js | 89 ++++++----- .../{Dashboard => }/Dialogs/CurrencyDialog.js | 0 .../{Dashboard => }/Dialogs/ExportDialog.js | 0 .../{Dashboard => }/Dialogs/ImportDialog.js | 0 .../Dialogs/InviteUserDialog.js | 0 .../Dialogs/ItemCategoryDialog.js | 82 +++++++--- .../{Dashboard => }/Dialogs/ItemFromDialog.js | 0 .../{Dashboard => }/Dialogs/UserFormDialog.js | 0 .../{Dashboard => }/Expenses/ExpenseForm.js | 3 +- .../{Dashboard => }/Expenses/ExpensesList.js | 0 .../BalanceSheet/BalanceSheet.js | 0 .../BalanceSheet/BalanceSheetActionsBar.js | 0 .../BalanceSheet/BalanceSheetHeader.js | 4 +- .../BalanceSheet/BalanceSheetTable.js | 0 .../FinancialStatementDateRange.js | 0 .../FinancialStatementHeader.js | 0 .../GeneralLedger/GeneralLedger.js | 2 +- .../GeneralLedger/GeneralLedgerActionsBar.js | 0 .../GeneralLedger/GeneralLedgerHeader.js | 4 +- .../GeneralLedger/GeneralLedgerTable.js | 0 .../FinancialStatements/Journal/Journal.js | 2 +- .../Journal/JournalActionsBar.js | 0 .../Journal/JournalHeader.js | 4 +- .../Journal/JournalTable.js | 0 .../FinancialStatements/LedgerSheet.js | 0 .../FinancialStatements/ProfitLossSheet.js | 0 .../ProfitLossSheet/ProfitLossActionsBar.js | 0 .../ProfitLossSheet/ProfitLossSheet.js | 0 .../ProfitLossSheet/ProfitLossSheetHeader.js | 4 +- .../ProfitLossSheet/ProfitLossSheetTable.js | 0 .../RadiosAccountingBasis.js | 0 .../SelectDisplayColumnsBy.js | 0 .../TrialBalanceActionsBar.js | 0 .../TrialBalanceSheet/TrialBalanceSheet.js | 0 .../TrialBalanceSheetHeader.js | 4 +- .../TrialBalanceSheetTable.js | 0 .../{Dashboard => }/GeneralSearch/Search.js | 0 .../{Dashboard => Homepage}/Homepage.js | 1 + .../containers/Items/ItemCategoriesList.js | 53 +++++++ .../Items/ItemCategoriesTable.js} | 0 .../Items/ItemForm.js | 4 +- client/src/containers/Items/ItemFormPage.js | 52 +++++++ .../{Dashboard => }/Items/ItemsActionsBar.js | 40 +++-- .../Items/ItemsCategoryActionsBar.js | 34 +++-- .../{Dashboard => }/Items/ItemsDataTable.js | 31 ++-- .../{Dashboard => }/Items/ItemsList.js | 85 +++++++---- .../{Dashboard => }/Items/ItemsViewsTabs.js | 82 ++++++---- .../containers/Items/withItemCategories.js | 11 ++ .../Items/withItemCategoriesActions.js | 16 ++ .../Items/withItemCategoryDetail.js | 12 ++ client/src/containers/Items/withItems.js | 26 ++++ .../src/containers/Items/withItemsActions.js | 32 ++++ .../{Dashboard => }/Preferences/Accountant.js | 0 .../{Dashboard => }/Preferences/Accounts.js | 0 .../Preferences/AccountsCustomFields.js | 0 .../Preferences/AccountsGeneral.js | 0 .../{Dashboard => }/Preferences/Currencies.js | 0 .../Preferences/CurrenciesActions.js | 0 .../Preferences/CurrenciesList.js | 0 .../{Dashboard => }/Preferences/General.js | 0 .../{Dashboard => }/Preferences/RolesList.js | 0 .../{Dashboard => }/Preferences/Users.js | 0 .../Preferences/UsersActions.js | 0 .../{Dashboard => }/Preferences/UsersList.js | 0 .../src/containers/Preferences/withUsers.js | 9 ++ .../Preferences/withUsersActions.js | 18 +++ .../Resources/withResourceDetails.js | 20 +++ .../Resources/withResourcesActions.js | 12 ++ .../containers/Views/ViewForm.container.js | 23 +++ .../Views/ViewForm.js | 142 ++++++++++-------- client/src/containers/Views/ViewFormPage.js | 112 ++++++++++++++ .../src/containers/Views/withViewDetails.js | 17 +++ .../Views/withViews.js} | 0 .../src/containers/Views/withViewsActions.js | 22 +++ client/src/hooks/useMedia.js | 1 - client/src/routes/dashboard.js | 34 ++--- client/src/routes/preferences.js | 10 +- client/src/routes/preferencesTabs.js | 6 +- .../store/customViews/customViews.actions.js | 20 ++- .../customViews/customViews.selectors.js | 13 +- .../src/store/dashboard/dashboard.reducer.js | 2 +- .../itemCategories/itemsCategory.actions.js | 12 ++ .../itemCategories/itemsCategory.reducer.js | 14 +- .../itemCategories/itemsCategory.type.js | 3 +- .../itemCategories/itemsCateory.reducer.js | 3 +- client/src/store/items/items.reducer.js | 4 + client/src/store/items/items.types.js | 3 +- .../manualJournals/manualJournals.actions.js | 14 +- .../src/store/resources/resources.reducer.js | 21 +++ client/src/style/objects/typography.scss | 2 +- client/src/style/pages/view-form.scss | 2 +- server/src/data/ResourceFieldsKeys.js | 23 +++ .../database/seeds/seed_resources_fields.js | 29 ++++ server/src/database/seeds/seed_views.js | 12 ++ server/src/database/seeds/seed_views_roles.js | 11 ++ server/src/http/controllers/Views.js | 51 ++++++- server/src/models/ExchangeRate.js | 47 +----- 151 files changed, 1742 insertions(+), 1081 deletions(-) delete mode 100644 client/src/components/Items/ItemsActionsBar.js delete mode 100644 client/src/components/JournalEntry/MakeJournalEntry.js create mode 100644 client/src/components/Utils/Choose.js create mode 100644 client/src/components/Utils/For.js create mode 100644 client/src/components/Utils/If.js create mode 100644 client/src/components/index.js delete mode 100644 client/src/connectors/AccountFormDialog.connector.js delete mode 100644 client/src/connectors/CustomView.connector.js delete mode 100644 client/src/connectors/RegisterForm.connect.js delete mode 100644 client/src/connectors/View.connector.js delete mode 100644 client/src/connectors/ViewFormPage.connector.js rename client/src/containers/{Dashboard => }/Accounting/MakeJournalEntriesFooter.js (100%) rename client/src/containers/{Dashboard => }/Accounting/MakeJournalEntriesForm.js (74%) rename client/src/containers/{Dashboard => }/Accounting/MakeJournalEntriesHeader.js (100%) rename client/src/containers/{Dashboard => }/Accounting/MakeJournalEntriesPage.js (52%) rename client/src/containers/{Dashboard => }/Accounting/MakeJournalEntriesTable.js (97%) rename client/src/{components/JournalEntry => containers/Accounting}/ManualJournalActionsBar.js (86%) rename client/src/{components/JournalEntry => containers/Accounting}/ManualJournalsDataTable.js (82%) rename client/src/containers/{Dashboard/Accounting/ManualJournalsTable.js => Accounting/ManualJournalsList.js} (80%) rename client/src/{components/JournalEntry => containers/Accounting}/ManualJournalsViewTabs.js (100%) create mode 100644 client/src/containers/Accounting/withJournalDetail.js create mode 100644 client/src/containers/Accounting/withJournalsActions.js create mode 100644 client/src/containers/Accounting/withManualJournalDetail.js create mode 100644 client/src/containers/Accounting/withManualJournals.js create mode 100644 client/src/containers/Accounting/withManualJournalsActions.js rename client/src/{components => containers}/Accounts/AccountsActionsBar.js (82%) rename client/src/containers/{Dashboard => }/Accounts/AccountsChart.js (79%) rename client/src/{components => containers}/Accounts/AccountsDataTable.js (89%) rename client/src/{components => containers}/Accounts/AccountsViewsTabs.js (66%) create mode 100644 client/src/containers/Accounts/withAccountDetail.js create mode 100644 client/src/containers/Accounts/withAccounts.js create mode 100644 client/src/containers/Accounts/withAccountsActions.js create mode 100644 client/src/containers/Accounts/withAccountsTableActions.js rename client/src/{connectors/Authentication.connect.js => containers/Authentication/withAuthenticationActions.js} (86%) delete mode 100644 client/src/containers/Dashboard/Items/ItemCategoryList.js delete mode 100644 client/src/containers/Dashboard/Items/ItemForm.js delete mode 100644 client/src/containers/Dashboard/Items/ItemsCategoryList.js delete mode 100644 client/src/containers/Dashboard/Views/ViewFormPage.js create mode 100644 client/src/containers/Dashboard/withDashboard.js create mode 100644 client/src/containers/Dialogs/AccountFormDialog.container.js rename client/src/containers/{Dashboard => }/Dialogs/AccountFormDialog.js (86%) rename client/src/containers/{Dashboard => }/Dialogs/CurrencyDialog.js (100%) rename client/src/containers/{Dashboard => }/Dialogs/ExportDialog.js (100%) rename client/src/containers/{Dashboard => }/Dialogs/ImportDialog.js (100%) rename client/src/containers/{Dashboard => }/Dialogs/InviteUserDialog.js (100%) rename client/src/containers/{Dashboard => }/Dialogs/ItemCategoryDialog.js (81%) rename client/src/containers/{Dashboard => }/Dialogs/ItemFromDialog.js (100%) rename client/src/containers/{Dashboard => }/Dialogs/UserFormDialog.js (100%) rename client/src/containers/{Dashboard => }/Expenses/ExpenseForm.js (98%) rename client/src/containers/{Dashboard => }/Expenses/ExpensesList.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/BalanceSheet/BalanceSheet.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/BalanceSheet/BalanceSheetActionsBar.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/BalanceSheet/BalanceSheetHeader.js (93%) rename client/src/containers/{Dashboard => }/FinancialStatements/BalanceSheet/BalanceSheetTable.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/FinancialStatementDateRange.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/FinancialStatementHeader.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/GeneralLedger/GeneralLedger.js (96%) rename client/src/containers/{Dashboard => }/FinancialStatements/GeneralLedger/GeneralLedgerActionsBar.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/GeneralLedger/GeneralLedgerHeader.js (92%) rename client/src/containers/{Dashboard => }/FinancialStatements/GeneralLedger/GeneralLedgerTable.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/Journal/Journal.js (97%) rename client/src/containers/{Dashboard => }/FinancialStatements/Journal/JournalActionsBar.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/Journal/JournalHeader.js (85%) rename client/src/containers/{Dashboard => }/FinancialStatements/Journal/JournalTable.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/LedgerSheet.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/ProfitLossSheet.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/ProfitLossSheet/ProfitLossActionsBar.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/ProfitLossSheet/ProfitLossSheet.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/ProfitLossSheet/ProfitLossSheetHeader.js (90%) rename client/src/containers/{Dashboard => }/FinancialStatements/ProfitLossSheet/ProfitLossSheetTable.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/RadiosAccountingBasis.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/SelectDisplayColumnsBy.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/TrialBalanceSheet/TrialBalanceActionsBar.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/TrialBalanceSheet/TrialBalanceSheet.js (100%) rename client/src/containers/{Dashboard => }/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetHeader.js (87%) rename client/src/containers/{Dashboard => }/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTable.js (100%) rename client/src/containers/{Dashboard => }/GeneralSearch/Search.js (100%) rename client/src/containers/{Dashboard => Homepage}/Homepage.js (99%) create mode 100644 client/src/containers/Items/ItemCategoriesList.js rename client/src/{components/Items/ItemsCategoryList.js => containers/Items/ItemCategoriesTable.js} (100%) rename client/src/{components => containers}/Items/ItemForm.js (99%) create mode 100644 client/src/containers/Items/ItemFormPage.js rename client/src/containers/{Dashboard => }/Items/ItemsActionsBar.js (85%) rename client/src/containers/{Dashboard => }/Items/ItemsCategoryActionsBar.js (79%) rename client/src/containers/{Dashboard => }/Items/ItemsDataTable.js (84%) rename client/src/containers/{Dashboard => }/Items/ItemsList.js (64%) rename client/src/containers/{Dashboard => }/Items/ItemsViewsTabs.js (52%) create mode 100644 client/src/containers/Items/withItemCategories.js create mode 100644 client/src/containers/Items/withItemCategoriesActions.js create mode 100644 client/src/containers/Items/withItemCategoryDetail.js create mode 100644 client/src/containers/Items/withItems.js create mode 100644 client/src/containers/Items/withItemsActions.js rename client/src/containers/{Dashboard => }/Preferences/Accountant.js (100%) rename client/src/containers/{Dashboard => }/Preferences/Accounts.js (100%) rename client/src/containers/{Dashboard => }/Preferences/AccountsCustomFields.js (100%) rename client/src/containers/{Dashboard => }/Preferences/AccountsGeneral.js (100%) rename client/src/containers/{Dashboard => }/Preferences/Currencies.js (100%) rename client/src/containers/{Dashboard => }/Preferences/CurrenciesActions.js (100%) rename client/src/containers/{Dashboard => }/Preferences/CurrenciesList.js (100%) rename client/src/containers/{Dashboard => }/Preferences/General.js (100%) rename client/src/containers/{Dashboard => }/Preferences/RolesList.js (100%) rename client/src/containers/{Dashboard => }/Preferences/Users.js (100%) rename client/src/containers/{Dashboard => }/Preferences/UsersActions.js (100%) rename client/src/containers/{Dashboard => }/Preferences/UsersList.js (100%) create mode 100644 client/src/containers/Preferences/withUsers.js create mode 100644 client/src/containers/Preferences/withUsersActions.js create mode 100644 client/src/containers/Resources/withResourceDetails.js create mode 100644 client/src/containers/Resources/withResourcesActions.js create mode 100644 client/src/containers/Views/ViewForm.container.js rename client/src/{components => containers}/Views/ViewForm.js (80%) create mode 100644 client/src/containers/Views/ViewFormPage.js create mode 100644 client/src/containers/Views/withViewDetails.js rename client/src/{components/Items/ItemsTable.js => containers/Views/withViews.js} (100%) create mode 100644 client/src/containers/Views/withViewsActions.js diff --git a/client/package.json b/client/package.json index 9de51b5ae..c83ffffc4 100644 --- a/client/package.json +++ b/client/package.json @@ -72,6 +72,7 @@ "react-hook-form": "^4.9.4", "react-intl": "^3.12.0", "react-loadable": "^5.5.0", + "react-query": "^1.3.3", "react-redux": "^7.1.3", "react-router-dom": "^5.1.2", "react-scrollbars-custom": "^4.0.21", @@ -121,6 +122,7 @@ "devDependencies": { "@babel/preset-flow": "^7.9.0", "http-proxy-middleware": "^1.0.0", + "react-query-devtools": "^1.1.5", "redux-devtools": "^3.5.0" }, "jest": { diff --git a/client/src/components/App.js b/client/src/components/App.js index 0453ac65e..12345fa04 100644 --- a/client/src/components/App.js +++ b/client/src/components/App.js @@ -8,7 +8,9 @@ import PrivateRoute from 'components/PrivateRoute'; import Authentication from 'components/Authentication'; import Dashboard from 'components/Dashboard/Dashboard'; import { isAuthenticated } from 'store/authentication/authentication.reducer' -import Progress from 'components/NProgress/Progress'; +import { ReactQueryConfigProvider } from 'react-query'; +import { ReactQueryDevtools } from "react-query-devtools"; + import messages from 'lang/en'; import 'style/App.scss'; @@ -22,13 +24,22 @@ function App({ console.log(`new location via ${action}`, location); }); + const queryConfig = { + refetchAllOnWindowFocus: false, + cacheTime: 10000, + staleTime: 10000, + }; return (
- - - - + + + + + + + +
); diff --git a/client/src/components/Authentication.js b/client/src/components/Authentication.js index af80309a5..530855a96 100644 --- a/client/src/components/Authentication.js +++ b/client/src/components/Authentication.js @@ -3,7 +3,7 @@ import { Redirect, Route, Switch, Link } from 'react-router-dom'; import BodyClassName from 'react-body-classname'; import authenticationRoutes from 'routes/authentication'; -export default function({ isAuthenticated =false, ...rest }) { +export default function AuthenticationWrapper({ isAuthenticated =false, ...rest }) { const to = {pathname: '/dashboard/homepage'}; return ( diff --git a/client/src/components/Dashboard/Dashboard.js b/client/src/components/Dashboard/Dashboard.js index 42e498ee8..d4cea68a7 100644 --- a/client/src/components/Dashboard/Dashboard.js +++ b/client/src/components/Dashboard/Dashboard.js @@ -5,7 +5,7 @@ import DashboardContent from 'components/Dashboard/DashboardContent'; import DialogsContainer from 'components/DialogsContainer'; import PreferencesContent from 'components/Preferences/PreferencesContent'; import PreferencesSidebar from 'components/Preferences/PreferencesSidebar'; -import Search from 'containers/Dashboard/GeneralSearch/Search'; +import Search from 'containers/GeneralSearch/Search'; export default function Dashboard() { return ( diff --git a/client/src/components/DialogsContainer.js b/client/src/components/DialogsContainer.js index 69762dd88..d78d3d2a1 100644 --- a/client/src/components/DialogsContainer.js +++ b/client/src/components/DialogsContainer.js @@ -1,9 +1,9 @@ import React from 'react'; -import AccountFormDialog from 'containers/Dashboard/Dialogs/AccountFormDialog'; -import UserFormDialog from 'containers/Dashboard/Dialogs/UserFormDialog'; -import ItemCategoryDialog from 'containers/Dashboard/Dialogs/ItemCategoryDialog'; -import CurrencyDialog from 'containers/Dashboard/Dialogs/CurrencyDialog'; -import InviteUserDialog from 'containers/Dashboard/Dialogs/InviteUserDialog'; +import AccountFormDialog from 'containers/Dialogs/AccountFormDialog'; +import UserFormDialog from 'containers/Dialogs/UserFormDialog'; +import ItemCategoryDialog from 'containers/Dialogs/ItemCategoryDialog'; +import CurrencyDialog from 'containers/Dialogs/CurrencyDialog'; +import InviteUserDialog from 'containers/Dialogs/InviteUserDialog'; export default function DialogsContainer() { return ( diff --git a/client/src/components/Items/ItemsActionsBar.js b/client/src/components/Items/ItemsActionsBar.js deleted file mode 100644 index 373dd5e0a..000000000 --- a/client/src/components/Items/ItemsActionsBar.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import { Button, AnchorButton, Classes, Icon } from '@blueprintjs/core'; - -const ItemsActionsBar = () => { - - return ( -
- ItemsActionsBar 22 -
- ); -}; - -export default ItemsActionsBar; diff --git a/client/src/components/JournalEntry/MakeJournalEntry.js b/client/src/components/JournalEntry/MakeJournalEntry.js deleted file mode 100644 index 0364d7bdc..000000000 --- a/client/src/components/JournalEntry/MakeJournalEntry.js +++ /dev/null @@ -1,94 +0,0 @@ -import React from 'react'; -import { - FormGroup, - MenuItem, - Intent, - InputGroup, - Position, - Button, -} from '@blueprintjs/core'; -import { DateInput, TimePrecision } from "@blueprintjs/datetime"; -import { - GridComponent, - ColumnsDirective, - ColumnDirective, - Inject, - Sort, -} from '@syncfusion/ej2-react-grids'; -import {momentFormatter} from 'utils'; - -export default function MakeJournalEntry({ - accounts, - currencies, -}) { - - const handleDateChange = () => { - - }; - - const handleClose = () => { - - }; - - const columns = [ - { - headerText: 'Account', - }, - { - headerText: 'Description', - }, - { - headerText: 'Account', - }, - { - headerText: 'Debit', - }, - { - headerText: 'Credit', - } - ]; - - return ( -
-
- - - - - - - - {columns.map((column) => { - return (); - })} - - - - - -
-
- ) -} \ No newline at end of file diff --git a/client/src/components/NProgress/AppProgress.js b/client/src/components/NProgress/AppProgress.js index 5009f0f4e..39f9e4093 100644 --- a/client/src/components/NProgress/AppProgress.js +++ b/client/src/components/NProgress/AppProgress.js @@ -1,18 +1,16 @@ import React from 'react'; -import {connect} from 'react-redux'; import Progress from './Progress'; +import {queryCache, useIsFetching} from 'react-query'; function AppProgress({ - isAnimating, + }) { + const isFetching = useIsFetching(); + return ( - + ); }; - -const mapStateToProps = (state) => ({ - isAnimating: state.dashboard.requestsLoading > 0, -}); - -export default connect(mapStateToProps)(AppProgress); \ No newline at end of file + +export default AppProgress; \ No newline at end of file diff --git a/client/src/components/Preferences/PreferencesTopbar.js b/client/src/components/Preferences/PreferencesTopbar.js index 9c588273d..829d170e7 100644 --- a/client/src/components/Preferences/PreferencesTopbar.js +++ b/client/src/components/Preferences/PreferencesTopbar.js @@ -1,8 +1,8 @@ import React from 'react'; import { Route, Switch } from 'react-router-dom'; import DashboardTopbarUser from 'components/Dashboard/TopbarUser'; -import UsersActions from 'containers/Dashboard/Preferences/UsersActions'; -import CurrenciesActions from 'containers/Dashboard/Preferences/CurrenciesActions'; +import UsersActions from 'containers/Preferences/UsersActions'; +import CurrenciesActions from 'containers/Preferences/CurrenciesActions'; export default function PreferencesTopbar() { diff --git a/client/src/components/Utils/Choose.js b/client/src/components/Utils/Choose.js new file mode 100644 index 000000000..8ac7ad134 --- /dev/null +++ b/client/src/components/Utils/Choose.js @@ -0,0 +1,33 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import If from './if'; + +const Choose = props => { + let when = null; + let otherwise = null; + + React.Children.forEach(props.children, children => { + if (children.props.condition === undefined) { + otherwise = children; + } else if (!when && children.props.condition === true) { + when = children; + } + }); + + return when || otherwise; +}; + +Choose.propTypes = { + children: PropTypes.node +}; + +Choose.When = If; + +Choose.Otherwise = ({render, children}) => render ? render() : children; + +Choose.Otherwise.propTypes = { + children: PropTypes.node, + render: PropTypes.func +}; + +export default Choose; \ No newline at end of file diff --git a/client/src/components/Utils/For.js b/client/src/components/Utils/For.js new file mode 100644 index 000000000..ef3e99f95 --- /dev/null +++ b/client/src/components/Utils/For.js @@ -0,0 +1,11 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +const For = ({render, of}) => of.map((item, index) => render(item, index)); + +For.propTypes = { + of: PropTypes.array.isRequired, + render: PropTypes.func.isRequired +}; + +export default For; \ No newline at end of file diff --git a/client/src/components/Utils/If.js b/client/src/components/Utils/If.js new file mode 100644 index 000000000..f6ae2c418 --- /dev/null +++ b/client/src/components/Utils/If.js @@ -0,0 +1,13 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +const If = props => props.condition + ? (props.render ? props.render() : props.children) : null; + +If.propTypes = { + condition: PropTypes.bool.isRequired, + children: PropTypes.node, + render: PropTypes.func +}; + +export default If; \ No newline at end of file diff --git a/client/src/components/index.js b/client/src/components/index.js new file mode 100644 index 000000000..9cedc0cd1 --- /dev/null +++ b/client/src/components/index.js @@ -0,0 +1,9 @@ +import If from './Utils/If'; +// import Choose from './Utils/Choose'; +// import For from './Utils/For'; + +export { + If, + // Choose, + // For, +}; \ No newline at end of file diff --git a/client/src/connectors/AccountFormDialog.connector.js b/client/src/connectors/AccountFormDialog.connector.js deleted file mode 100644 index b3f1e0a7d..000000000 --- a/client/src/connectors/AccountFormDialog.connector.js +++ /dev/null @@ -1,13 +0,0 @@ -import {connect} from 'react-redux'; -import {getDialogPayload} from 'store/dashboard/dashboard.reducer'; - -export const mapStateToProps = (state, props) => { - const dialogPayload = getDialogPayload(state, 'account-form'); - - return { - name: 'account-form', - payload: {action: 'new', id: null, ...dialogPayload}, - }; -}; - -export default connect(mapStateToProps); \ No newline at end of file diff --git a/client/src/connectors/CustomView.connector.js b/client/src/connectors/CustomView.connector.js deleted file mode 100644 index cadc8e4cc..000000000 --- a/client/src/connectors/CustomView.connector.js +++ /dev/null @@ -1,14 +0,0 @@ -import { connect } from 'react-redux'; -import { - fetchResourceViews, -} from 'store/customViews/customViews.actions'; - -const mapStateToProps = (state) => ({ - -}); - -const mapActionsToProps = (dispatch) => ({ - fetchResourceViews: (resourceSlug) => dispatch(fetchResourceViews({ resourceSlug })), -}); - -export default connect(mapStateToProps, mapActionsToProps); \ No newline at end of file diff --git a/client/src/connectors/Dashboard.connector.js b/client/src/connectors/Dashboard.connector.js index b4f29a4d3..6c3ce2bf9 100644 --- a/client/src/connectors/Dashboard.connector.js +++ b/client/src/connectors/Dashboard.connector.js @@ -2,10 +2,6 @@ import { connect } from 'react-redux'; import t from 'store/types'; -const mapStateToProps = (state) => ({ - -}); - const mapActionsToProps = (dispatch) => ({ changePageTitle: (pageTitle) => dispatch({ type: t.CHANGE_DASHBOARD_PAGE_TITLE, pageTitle @@ -28,4 +24,4 @@ const mapActionsToProps = (dispatch) => ({ }), }); -export default connect(mapStateToProps, mapActionsToProps); \ No newline at end of file +export default connect(null, mapActionsToProps); \ No newline at end of file diff --git a/client/src/connectors/RegisterForm.connect.js b/client/src/connectors/RegisterForm.connect.js deleted file mode 100644 index a82e601ac..000000000 --- a/client/src/connectors/RegisterForm.connect.js +++ /dev/null @@ -1,12 +0,0 @@ -import { connect } from 'react-redux'; -import { submitRegister } from 'store/registers/register.action'; - -export const mapStateToProps = (state, props) => { - return {}; -}; - -export const mapDispatchToProps = (dispatch) => ({ - requestSubmitRegister: (form) => dispatch(submitRegister({ form })), -}); - -export default connect(mapStateToProps, mapDispatchToProps); diff --git a/client/src/connectors/Resource.connector.js b/client/src/connectors/Resource.connector.js index 51575cbd0..b6fb00d56 100644 --- a/client/src/connectors/Resource.connector.js +++ b/client/src/connectors/Resource.connector.js @@ -8,19 +8,21 @@ import { getResourceFields, getResourceColumn, getResourceField, + getResourceMetadata, } from 'store/resources/resources.reducer'; export const mapStateToProps = (state, props) => ({ - getResourceColumns: (resourceSlug) => getResourceColumns(state, resourceSlug), - getResourceFields: (resourceSlug) => getResourceFields(state, resourceSlug), + // getResourceColumns: (resourceSlug) => getResourceColumns(state, resourceSlug), + // getResourceFields: (resourceSlug) => getResourceFields(state, resourceSlug), + // getResourceMetadata: (resourceSlug) => getResourceMetadata(state, resourceSlug), - getResourceColumn: (columnId) => getResourceColumn(state, columnId), - getResourceField: (fieldId) => getResourceField(state, fieldId), + // getResourceColumn: (columnId) => getResourceColumn(state, columnId), + // getResourceField: (fieldId) => getResourceField(state, fieldId), }); export const mapDispatchToProps = (dispatch) => ({ - fetchResourceFields: (resourceSlug) => dispatch(fetchResourceFields({ resourceSlug })), - fetchResourceColumns: (resourceSlug) => dispatch(fetchResourceColumns({ resourceSlug })), + requestFetchResourceFields: (resourceSlug) => dispatch(fetchResourceFields({ resourceSlug })), + requestFetchResourceColumns: (resourceSlug) => dispatch(fetchResourceColumns({ resourceSlug })), }); export default connect(mapStateToProps, mapDispatchToProps); \ No newline at end of file diff --git a/client/src/connectors/View.connector.js b/client/src/connectors/View.connector.js deleted file mode 100644 index b12dd0455..000000000 --- a/client/src/connectors/View.connector.js +++ /dev/null @@ -1,25 +0,0 @@ -import {connect} from 'react-redux'; -import { - fetchView, - submitView, - deleteView, - editView, -} from 'store/customViews/customViews.actions'; -import { - getViewMeta, - getViewItem, -} from 'store/customViews/customViews.selectors'; - -export const mapStateToProps = (state) => ({ - getViewMeta: (viewId) => getViewMeta(state, viewId), - getViewItem: (viewId) => getViewItem(state, viewId), -}); - -export const mapDispatchToProps = (dispatch) => ({ - fetchView: (id) => dispatch(fetchView({ id })), - submitView: (form) => dispatch(submitView({ form })), - editView: (id, form) => dispatch(editView({ id, form })), - deleteView: (id) => dispatch(deleteView({ id })), -}); - -export default connect(mapStateToProps, mapDispatchToProps); \ No newline at end of file diff --git a/client/src/connectors/ViewFormPage.connector.js b/client/src/connectors/ViewFormPage.connector.js deleted file mode 100644 index c8d44d3af..000000000 --- a/client/src/connectors/ViewFormPage.connector.js +++ /dev/null @@ -1,29 +0,0 @@ -import {connect} from 'react-redux'; -import { - fetchResourceColumns, - fetchResourceFields, -} from 'store/resources/resources.actions'; -import { - getResourceColumns, - getResourceFields, -} from 'store/resources/resources.reducer'; -import { - fetchView, - submitView, - editView, -} from 'store/customViews/customViews.actions'; -import t from 'store/types'; - -export const mapStateToProps = (state, props) => { - return { - - }; -}; - -export const mapDispatchToProps = (dispatch) => ({ - fetchView: (id) => dispatch(fetchView({ id })), - submitView: (form) => dispatch(submitView({ form })), - editView: (id, form) => dispatch(editView({ id, form })), -}); - -export default connect(mapStateToProps, mapDispatchToProps); \ No newline at end of file diff --git a/client/src/containers/Dashboard/Accounting/MakeJournalEntriesFooter.js b/client/src/containers/Accounting/MakeJournalEntriesFooter.js similarity index 100% rename from client/src/containers/Dashboard/Accounting/MakeJournalEntriesFooter.js rename to client/src/containers/Accounting/MakeJournalEntriesFooter.js diff --git a/client/src/containers/Dashboard/Accounting/MakeJournalEntriesForm.js b/client/src/containers/Accounting/MakeJournalEntriesForm.js similarity index 74% rename from client/src/containers/Dashboard/Accounting/MakeJournalEntriesForm.js rename to client/src/containers/Accounting/MakeJournalEntriesForm.js index 7240aeeba..94af85555 100644 --- a/client/src/containers/Dashboard/Accounting/MakeJournalEntriesForm.js +++ b/client/src/containers/Accounting/MakeJournalEntriesForm.js @@ -1,39 +1,41 @@ import React, {useMemo, useState, useEffect, useRef, useCallback} from 'react'; import * as Yup from 'yup'; -import { - ProgressBar, - Classes, - Intent, -} from '@blueprintjs/core'; +import {useFormik} from "formik"; +import moment from 'moment'; +import { Intent } from '@blueprintjs/core'; + import MakeJournalEntriesHeader from './MakeJournalEntriesHeader'; import MakeJournalEntriesFooter from './MakeJournalEntriesFooter'; import MakeJournalEntriesTable from './MakeJournalEntriesTable'; -import {useFormik} from "formik"; -import MakeJournalEntriesConnect from 'connectors/MakeJournalEntries.connect'; -import AccountsConnect from 'connectors/Accounts.connector'; -import DashboardConnect from 'connectors/Dashboard.connector'; -import {compose, saveFilesInAsync} from 'utils'; -import moment from 'moment'; + +import withJournalsActions from 'containers/Accounting/withJournalsActions'; +import withManualJournalDetail from 'containers/Accounting/withManualJournalDetail'; +import withAccountsActions from 'containers/Accounts/withAccountsActions'; +import withDashboardActions from 'containers/Dashboard/withDashboard'; + import AppToaster from 'components/AppToaster'; import {pick} from 'lodash'; import Dragzone from 'components/Dragzone'; import MediaConnect from 'connectors/Media.connect'; -import classNames from 'classnames'; -import ManualJournalsConnect from 'connectors/ManualJournals.connect'; + import useMedia from 'hooks/useMedia'; +import {compose} from 'utils'; + function MakeJournalEntriesForm({ requestSubmitMedia, + requestDeleteMedia, + requestMakeJournalEntries, requestEditManualJournal, + changePageTitle, changePageSubtitle, - editJournal, - onFormSubmit, - onCancelForm, - requestDeleteMedia, - manualJournalsItems + manualJournalId, + manualJournal, + onFormSubmit, + onCancelForm, }) { const { setFiles, saveMedia, deletedFiles, setDeletedFiles, deleteMedia } = useMedia({ saveCallback: requestSubmitMedia, @@ -47,13 +49,13 @@ function MakeJournalEntriesForm({ const clearSavedMediaIds = () => { savedMediaIds.current = []; } useEffect(() => { - if (editJournal && editJournal.id) { + if (manualJournal && manualJournal.id) { changePageTitle('Edit Journal'); - changePageSubtitle(`No. ${editJournal.journal_number}`); + changePageSubtitle(`No. ${manualJournal.journal_number}`); } else { changePageTitle('New Journal'); } - }, [changePageTitle, changePageSubtitle, editJournal]); + }, [changePageTitle, changePageSubtitle, manualJournal]); const validationSchema = Yup.object().shape({ journal_number: Yup.string().required(), @@ -100,24 +102,24 @@ function MakeJournalEntriesForm({ }), [defaultEntry]); const initialValues = useMemo(() => ({ - ...(editJournal) ? { - ...pick(editJournal, Object.keys(defaultInitialValues)), - entries: editJournal.entries.map((entry) => ({ + ...(manualJournal) ? { + ...pick(manualJournal, Object.keys(defaultInitialValues)), + entries: manualJournal.entries.map((entry) => ({ ...pick(entry, Object.keys(defaultEntry)), })), } : { ...defaultInitialValues, } - }), [editJournal, defaultInitialValues, defaultEntry]); + }), [manualJournal, defaultInitialValues, defaultEntry]); const initialAttachmentFiles = useMemo(() => { - return editJournal && editJournal.media - ? editJournal.media.map((attach) => ({ + return manualJournal && manualJournal.media + ? manualJournal.media.map((attach) => ({ preview: attach.attachment_file, uploaded: true, metadata: { ...attach }, })) : []; - }, [editJournal]); + }, [manualJournal]); const formik = useFormik({ enableReinitialize: true, @@ -125,7 +127,7 @@ function MakeJournalEntriesForm({ initialValues: { ...initialValues, }, - onSubmit: async (values, actions) => { + onSubmit: async (values, { setErrors, setSubmitting }) => { const entries = values.entries.filter((entry) => ( (entry.credit || entry.debit) )); @@ -142,7 +144,7 @@ function MakeJournalEntriesForm({ AppToaster.show({ message: 'credit_and_debit_not_equal', }); - actions.setSubmitting(false); + setSubmitting(false); return; } const form = { ...values, status: payload.publish, entries }; @@ -150,33 +152,43 @@ function MakeJournalEntriesForm({ const saveJournal = (mediaIds) => new Promise((resolve, reject) => { const requestForm = { ...form, media_ids: mediaIds }; - if (editJournal && editJournal.id) { - requestEditManualJournal(editJournal.id, requestForm) + if (manualJournal && manualJournal.id) { + requestEditManualJournal(manualJournal.id, requestForm) .then((response) => { AppToaster.show({ message: 'manual_journal_has_been_edited', + intent: Intent.SUCCESS, }); - actions.setSubmitting(false); + setSubmitting(false); saveInvokeSubmit({ action: 'update', ...payload }); clearSavedMediaIds([]); resolve(response); - }).catch((error) => { - actions.setSubmitting(false); - reject(error); + }).catch((errors) => { + if (errors.find(e => e.type === 'JOURNAL.NUMBER.ALREADY.EXISTS')) { + setErrors({ + journal_number: 'Journal number is already used.', + }); + } + setSubmitting(false); }); } else { requestMakeJournalEntries(requestForm) .then((response) => { AppToaster.show({ message: 'manual_journal_has_been_submit', + intent: Intent.SUCCESS, }); - actions.setSubmitting(false); + setSubmitting(false); saveInvokeSubmit({ action: 'new', ...payload }); clearSavedMediaIds(); resolve(response); - }).catch((error) => { - actions.setSubmitting(false); - reject(error); + }).catch((errors) => { + if (errors.find(e => e.type === 'JOURNAL.NUMBER.ALREADY.EXISTS')) { + setErrors({ + journal_number: 'Journal number is already used.', + }); + } + setSubmitting(false); }); } }); @@ -240,9 +252,11 @@ function MakeJournalEntriesForm({ } export default compose( - ManualJournalsConnect, - MakeJournalEntriesConnect, - AccountsConnect, - DashboardConnect, + // ManualJournalsConnect, + // MakeJournalEntriesConnect, + withJournalsActions, + withManualJournalDetail, + withAccountsActions, + withDashboardActions, MediaConnect, )(MakeJournalEntriesForm); \ No newline at end of file diff --git a/client/src/containers/Dashboard/Accounting/MakeJournalEntriesHeader.js b/client/src/containers/Accounting/MakeJournalEntriesHeader.js similarity index 100% rename from client/src/containers/Dashboard/Accounting/MakeJournalEntriesHeader.js rename to client/src/containers/Accounting/MakeJournalEntriesHeader.js diff --git a/client/src/containers/Dashboard/Accounting/MakeJournalEntriesPage.js b/client/src/containers/Accounting/MakeJournalEntriesPage.js similarity index 52% rename from client/src/containers/Dashboard/Accounting/MakeJournalEntriesPage.js rename to client/src/containers/Accounting/MakeJournalEntriesPage.js index bd58923e9..df46bc486 100644 --- a/client/src/containers/Dashboard/Accounting/MakeJournalEntriesPage.js +++ b/client/src/containers/Accounting/MakeJournalEntriesPage.js @@ -1,31 +1,28 @@ -import React, {useMemo, useCallback} from 'react'; +import React, { useCallback } from 'react'; import { useParams, useHistory } from 'react-router-dom'; -import useAsync from 'hooks/async'; +import { useQuery } from 'react-query'; import MakeJournalEntriesForm from './MakeJournalEntriesForm'; import DashboardInsider from 'components/Dashboard/DashboardInsider'; -import DashboardConnect from 'connectors/Dashboard.connector'; + +import withAccountsActions from 'containers/Accounts/withAccountsActions'; +import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions'; + import {compose} from 'utils'; -import MakeJournalEntriesConnect from 'connectors/MakeJournalEntries.connect'; -import AccountsConnect from 'connectors/Accounts.connector'; + function MakeJournalEntriesPage({ - fetchManualJournal, - getManualJournal, + requestFetchManualJournal, requestFetchAccounts, }) { const history = useHistory(); const { id } = useParams(); - const fetchJournal = useAsync(() => { - return Promise.all([ - requestFetchAccounts(), - (id) && fetchManualJournal(id), - ]); - }); + const fetchAccounts = useQuery('accounts-list', + (key) => requestFetchAccounts()); - const editJournal = useMemo(() => - getManualJournal(id) || null, - [getManualJournal, id]); + const fetchJournal = useQuery( + id && ['manual-journal', id], + (key, journalId) => requestFetchManualJournal(journalId)); const handleFormSubmit = useCallback((payload) => { payload.redirect && @@ -37,17 +34,19 @@ function MakeJournalEntriesPage({ }, [history]); return ( - + ); } export default compose( - DashboardConnect, - AccountsConnect, - MakeJournalEntriesConnect, + // DashboardConnect, + withAccountsActions, + withManualJournalsActions, )(MakeJournalEntriesPage); \ No newline at end of file diff --git a/client/src/containers/Dashboard/Accounting/MakeJournalEntriesTable.js b/client/src/containers/Accounting/MakeJournalEntriesTable.js similarity index 97% rename from client/src/containers/Dashboard/Accounting/MakeJournalEntriesTable.js rename to client/src/containers/Accounting/MakeJournalEntriesTable.js index 396a704a2..d0d3dcc56 100644 --- a/client/src/containers/Dashboard/Accounting/MakeJournalEntriesTable.js +++ b/client/src/containers/Accounting/MakeJournalEntriesTable.js @@ -5,8 +5,7 @@ import { } from '@blueprintjs/core'; import DataTable from 'components/DataTable'; import Icon from 'components/Icon'; -import AccountsConnect from 'connectors/Accounts.connector.js'; -import {compose, formattedAmount} from 'utils'; +import { compose, formattedAmount} from 'utils'; import { AccountsListFieldCell, MoneyFieldCell, @@ -14,6 +13,9 @@ import { } from 'components/DataTableCells'; import { omit } from 'lodash'; +import withAccounts from 'containers/Accounts/withAccounts'; + + // Actions cell renderer. const ActionsCellRenderer = ({ row: { index }, @@ -70,6 +72,7 @@ const NoteCellRenderer = (chainedComponent) => (props) => { return chainedComponent(props); }; + /** * Make journal entries table component. */ @@ -223,5 +226,5 @@ function MakeJournalEntriesTable({ } export default compose( - AccountsConnect, + withAccounts, )(MakeJournalEntriesTable); \ No newline at end of file diff --git a/client/src/components/JournalEntry/ManualJournalActionsBar.js b/client/src/containers/Accounting/ManualJournalActionsBar.js similarity index 86% rename from client/src/components/JournalEntry/ManualJournalActionsBar.js rename to client/src/containers/Accounting/ManualJournalActionsBar.js index c07a7593f..1c52c0c2b 100644 --- a/client/src/components/JournalEntry/ManualJournalActionsBar.js +++ b/client/src/containers/Accounting/ManualJournalActionsBar.js @@ -18,13 +18,19 @@ import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; import DialogConnect from 'connectors/Dialog.connector'; import { compose } from 'utils'; import FilterDropdown from 'components/FilterDropdown'; -import ManualJournalsConnect from 'connectors/ManualJournals.connect'; -import ResourceConnect from 'connectors/Resource.connector'; -function ManualJournalActionsBar({ - views, - getResourceFields, +import withResourceDetail from 'containers/Resources/withResourceDetails'; +import withManualJournals from 'containers/Accounting/withManualJournals'; +import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions'; + + +function ManualJournalActionsBar({ + resourceName = 'manual_journal', + resourceFields, + + manualJournalsViews, addManualJournalsTableQueries, + onFilterChanged, selectedRows, onBulkDelete @@ -32,8 +38,7 @@ function ManualJournalActionsBar({ const { path } = useRouteMatch(); const history = useHistory(); - const manualJournalFields = getResourceFields('manual_journals'); - const viewsMenuItems = views.map(view => { + const viewsMenuItems = manualJournalsViews.map(view => { return ( ); @@ -44,7 +49,7 @@ function ManualJournalActionsBar({ }, [history]); const filterDropdown = FilterDropdown({ - fields: manualJournalFields, + fields: resourceFields, onFilterChange: filterConditions => { addManualJournalsTableQueries({ filter_roles: filterConditions || '' @@ -120,6 +125,7 @@ function ManualJournalActionsBar({ export default compose( DialogConnect, - ManualJournalsConnect, - ResourceConnect + withResourceDetail, + withManualJournals, + withManualJournalsActions, )(ManualJournalActionsBar); diff --git a/client/src/components/JournalEntry/ManualJournalsDataTable.js b/client/src/containers/Accounting/ManualJournalsDataTable.js similarity index 82% rename from client/src/components/JournalEntry/ManualJournalsDataTable.js rename to client/src/containers/Accounting/ManualJournalsDataTable.js index e1aabf129..f24f36095 100644 --- a/client/src/components/JournalEntry/ManualJournalsDataTable.js +++ b/client/src/containers/Accounting/ManualJournalsDataTable.js @@ -12,21 +12,33 @@ import { useParams } from 'react-router-dom'; import Icon from 'components/Icon'; import { compose } from 'utils'; import moment from 'moment'; -import ManualJournalsConnect from 'connectors/ManualJournals.connect'; + +import LoadingIndicator from 'components/LoadingIndicator'; import DialogConnect from 'connectors/Dialog.connector'; -import DashboardConnect from 'connectors/Dashboard.connector'; -import ViewConnect from 'connectors/View.connector'; + import { useUpdateEffect } from 'hooks'; import DataTable from 'components/DataTable'; import Money from 'components/Money'; +import withDashboardActions from 'containers/Dashboard/withDashboard'; +import withViewDetails from 'containers/Views/withViewDetails'; +import withManualJournals from 'containers/Accounting/withManualJournals'; +import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions'; + + function ManualJournalsDataTable({ + loading, + manualJournals, + manualJournalsLoading, + changeCurrentView, changePageSubtitle, - getViewItem, + + viewId, + viewMeta, setTopbarEditView, - manualJournalsLoading, + onFetchData, onEditJournal, onDeleteJournal, @@ -43,8 +55,6 @@ function ManualJournalsDataTable({ }, [manualJournalsLoading, setInitialMount]); useEffect(() => { - const viewMeta = getViewItem(customViewId); - if (customViewId) { changeCurrentView(customViewId); setTopbarEditView(customViewId); @@ -55,7 +65,7 @@ function ManualJournalsDataTable({ changeCurrentView, changePageSubtitle, setTopbarEditView, - getViewItem, + viewMeta, ]); const handlePublishJournal = useCallback((journal) => () => { @@ -172,22 +182,26 @@ function ManualJournalsDataTable({ }, [onSelectedRowsChange]); return ( - + + + ); } export default compose( DialogConnect, - DashboardConnect, - ViewConnect, - ManualJournalsConnect, + withDashboardActions, + // withViewsActions, + withManualJournalsActions, + withManualJournals, + withViewDetails, )(ManualJournalsDataTable); diff --git a/client/src/containers/Dashboard/Accounting/ManualJournalsTable.js b/client/src/containers/Accounting/ManualJournalsList.js similarity index 80% rename from client/src/containers/Dashboard/Accounting/ManualJournalsTable.js rename to client/src/containers/Accounting/ManualJournalsList.js index 60162e675..b0db5a109 100644 --- a/client/src/containers/Dashboard/Accounting/ManualJournalsTable.js +++ b/client/src/containers/Accounting/ManualJournalsList.js @@ -1,45 +1,49 @@ import React, { useEffect, useState, useCallback } from 'react'; import { Route, Switch, useHistory } from 'react-router-dom'; -import useAsync from 'hooks/async'; +import { useQuery } from 'react-query'; import { Alert, Intent } from '@blueprintjs/core'; import AppToaster from 'components/AppToaster'; + 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 ManualJournalsActionsBar from 'components/JournalEntry/ManualJournalActionsBar'; -import ManualJournalsConnect from 'connectors/ManualJournals.connect'; -import DashboardConnect from 'connectors/Dashboard.connector'; -import CustomViewConnect from 'connectors/CustomView.connector'; -import ResourceConnect from 'connectors/Resource.connector'; + +import ManualJournalsViewTabs from 'containers/Accounting/ManualJournalsViewTabs'; +import ManualJournalsDataTable from 'containers/Accounting/ManualJournalsDataTable'; +import ManualJournalsActionsBar from 'containers/Accounting/ManualJournalActionsBar'; + +import withDashboardActions from 'containers/Dashboard/withDashboard'; +import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions'; +import withViewsActions from 'containers/Views/withViewsActions'; + import { compose } from 'utils'; + +/** + * Manual journals table. + */ function ManualJournalsTable({ changePageTitle, - fetchResourceViews, - fetchManualJournalsTable, + requestFetchResourceViews, + requestFetchManualJournalsTable, requestDeleteManualJournal, requestPublishManualJournal, requestDeleteBulkManualJournals, - addManualJournalsTableQueries + 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([ - fetchResourceViews('manual_journals'), - ]); + const fetchViews = useQuery('journals-resource-views', () => { + return requestFetchResourceViews('manual_journals'); }); - const fetchManualJournalsHook = useAsync(async () => { - return fetchManualJournalsTable(); - }); + const fetchManualJournals = useQuery('manual-journals-table', () => + requestFetchManualJournalsTable()); useEffect(() => { changePageTitle('Manual Journals'); @@ -89,13 +93,13 @@ function ManualJournalsTable({ // Handle filter change to re-fetch data-table. const handleFilterChanged = useCallback(() => { - fetchManualJournalsHook.execute(); - }, [fetchManualJournalsHook]); + fetchManualJournals.refetch(); + }, [fetchManualJournals]); // Handle view change to re-fetch data table. const handleViewChanged = useCallback(() => { - fetchManualJournalsHook.execute(); - }, [fetchManualJournalsHook]); + fetchManualJournals.refetch(); + }, [fetchManualJournals]); // Handle fetch data of manual jouranls datatable. const handleFetchData = useCallback(({ pageIndex, pageSize, sortBy }) => { @@ -105,9 +109,7 @@ function ManualJournalsTable({ sort_order: sortBy[0].desc ? 'desc' : 'asc', } : {}, }); - fetchManualJournalsHook.execute(); }, [ - fetchManualJournalsHook, addManualJournalsTableQueries, ]); @@ -123,7 +125,9 @@ function ManualJournalsTable({ }, [setSelectedRows]); return ( - + ({ + manualJournal: getManualJournal(state, props.manualJournalId), +}); + +export default connect(mapStateToProps); \ No newline at end of file diff --git a/client/src/containers/Accounting/withJournalsActions.js b/client/src/containers/Accounting/withJournalsActions.js new file mode 100644 index 000000000..b4b66c000 --- /dev/null +++ b/client/src/containers/Accounting/withJournalsActions.js @@ -0,0 +1,14 @@ +import {connect} from 'react-redux'; +import { + makeJournalEntries, + fetchManualJournal, + editManualJournal, +} from 'store/manualJournals/manualJournals.actions'; + +export const mapDispatchToProps = (dispatch) => ({ + requestMakeJournalEntries: (form) => dispatch(makeJournalEntries({ form })), + requestFetchManualJournal: (id) => dispatch(fetchManualJournal({ id })), + requestEditManualJournal: (id, form) => dispatch(editManualJournal({ id, form })) +}); + +export default connect(null, mapDispatchToProps); \ No newline at end of file diff --git a/client/src/containers/Accounting/withManualJournalDetail.js b/client/src/containers/Accounting/withManualJournalDetail.js new file mode 100644 index 000000000..94f633ec9 --- /dev/null +++ b/client/src/containers/Accounting/withManualJournalDetail.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; +import t from 'store/types'; +import { getManualJournal } from 'store/manualJournals/manualJournals.reducers'; + +const mapStateToProps = (state, props) => ({ + manualJournal: getManualJournal(state, props.manualJournalId), +}); + +export default connect(mapStateToProps); diff --git a/client/src/containers/Accounting/withManualJournals.js b/client/src/containers/Accounting/withManualJournals.js new file mode 100644 index 000000000..083b82133 --- /dev/null +++ b/client/src/containers/Accounting/withManualJournals.js @@ -0,0 +1,16 @@ +import { connect } from 'react-redux'; +import { getResourceViews } from 'store/customViews/customViews.selectors'; +import { + getManualJournalsItems, +} from 'store/manualJournals/manualJournals.selectors' + + +const mapStateToProps = (state, props) => ({ + manualJournals: getManualJournalsItems(state, state.manualJournals.currentViewId), + manualJournalsViews: getResourceViews(state, 'manual_journals'), + manualJournalsItems: state.manualJournals.items, + manualJournalsTableQuery: state.manualJournals.tableQuery, + manualJournalsLoading: state.manualJournals.loading, +}); + +export default connect(mapStateToProps); diff --git a/client/src/containers/Accounting/withManualJournalsActions.js b/client/src/containers/Accounting/withManualJournalsActions.js new file mode 100644 index 000000000..207a48adb --- /dev/null +++ b/client/src/containers/Accounting/withManualJournalsActions.js @@ -0,0 +1,28 @@ +import { connect } from 'react-redux'; +import t from 'store/types'; +import { + deleteManualJournal, + fetchManualJournalsTable, + publishManualJournal, + deleteBulkManualJournals, + fetchManualJournal, +} from 'store/manualJournals/manualJournals.actions'; + +const mapActionsToProps = (dispatch) => ({ + requestDeleteManualJournal: (id) => dispatch(deleteManualJournal({ id })), + requestFetchManualJournalsTable: (query = {}) => dispatch(fetchManualJournalsTable({ query: { ...query } })), + requestFetchManualJournal: (id) => dispatch(fetchManualJournal({ id })), + requestPublishManualJournal: (id) => dispatch(publishManualJournal({ id })), + requestDeleteBulkManualJournals: (ids) => dispatch(deleteBulkManualJournals({ ids })), + + changeCurrentView: (id) => dispatch({ + type: t.MANUAL_JOURNALS_SET_CURRENT_VIEW, + currentViewId: parseInt(id, 10), + }), + addManualJournalsTableQueries: (queries) => dispatch({ + type: t.MANUAL_JOURNALS_TABLE_QUERIES_ADD, + queries, + }), +}); + +export default connect(null, mapActionsToProps); diff --git a/client/src/components/Accounts/AccountsActionsBar.js b/client/src/containers/Accounts/AccountsActionsBar.js similarity index 82% rename from client/src/components/Accounts/AccountsActionsBar.js rename to client/src/containers/Accounts/AccountsActionsBar.js index d8f716746..ff1214ece 100644 --- a/client/src/components/Accounts/AccountsActionsBar.js +++ b/client/src/containers/Accounts/AccountsActionsBar.js @@ -13,45 +13,50 @@ import { Intent, } from '@blueprintjs/core'; import classNames from 'classnames'; +import { useHistory } from 'react-router-dom'; import { connect } from 'react-redux'; -import { useRouteMatch, useHistory } from 'react-router-dom'; +import { If } from 'components'; + import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; import DialogConnect from 'connectors/Dialog.connector'; -import AccountsConnect from 'connectors/Accounts.connector'; -import {compose} from 'utils'; + import FilterDropdown from 'components/FilterDropdown'; -import ResourceConnect from 'connectors/Resource.connector'; + +import withResourceDetail from 'containers/Resources/withResourceDetails'; +import withAccountsTableActions from 'containers/Accounts/withAccountsTableActions'; +import withAccounts from 'containers/Accounts/withAccounts'; + +import {compose} from 'utils'; + function AccountsActionsBar({ openDialog, - views, - selectedRows = [], - getResourceFields, + accountsViews, + + resourceFields, addAccountsTableQueries, + + selectedRows = [], onFilterChanged, onBulkDelete, onBulkArchive, }) { const history = useHistory(); - - const onClickNewAccount = () => { openDialog('account-form', {}); }; - - const accountsFields = getResourceFields('accounts'); const [filterCount, setFilterCount] = useState(0); + const onClickNewAccount = () => { openDialog('account-form', {}); }; const onClickViewItem = (view) => { history.push(view - ? `/dashboard/accounts/${view.id}/custom_view` : - '/dashboard/accounts'); + ? `/dashboard/accounts/${view.id}/custom_view` : '/dashboard/accounts'); }; - const viewsMenuItems = views.map((view) => { + const viewsMenuItems = accountsViews.map((view) => { return ( onClickViewItem(view)} text={view.name} />); }); const hasSelectedRows = useMemo(() => selectedRows.length > 0, [selectedRows]); const filterDropdown = FilterDropdown({ - fields: accountsFields, + fields: resourceFields, onFilterChange: (filterConditions) => { setFilterCount(filterConditions.length || 0); addAccountsTableQueries({ @@ -106,15 +111,13 @@ function AccountsActionsBar({ icon={ }/> - {hasSelectedRows && ( +