diff --git a/src/config/sidebarMenu.js b/src/config/sidebarMenu.js index bf82e5fe2..480fa72e8 100644 --- a/src/config/sidebarMenu.js +++ b/src/config/sidebarMenu.js @@ -645,6 +645,10 @@ export default [ text: , href: '/financial-reports/realized-gain-loss', }, + { + text: , + href: '/financial-reports/unrealized-gain-loss', + }, { text: , label: true, diff --git a/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLoss.js b/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLoss.js new file mode 100644 index 000000000..a8f20c4ed --- /dev/null +++ b/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLoss.js @@ -0,0 +1,65 @@ +import React from 'react'; + +import { FinancialStatement } from 'components'; +import DashboardPageContent from 'components/Dashboard/DashboardPageContent'; + +import UnrealizedGainOrLossHeader from './UnrealizedGainOrLossHeader'; +import UnrealizedGainOrLossTable from './UnrealizedGainOrLossTable'; +import UnrealizedGainOrLossActionsBar from './UnrealizedGainOrLossActionsBar'; + +import withCurrentOrganization from '../../Organization/withCurrentOrganization'; +import withUnrealizedGainOrLossActions from './withUnrealizedGainOrLossActions'; +import { UnrealizedGainOrLossProvider } from './UnrealizedGainOrLossProvider'; +import { UnrealizedGainOrLossLoadingBar } from './components'; + +import { compose } from 'utils'; + +/** + * Unrealized Gain or Loss + */ +function UnrealizedGainOrLoss({ + // #withPreferences + organizationName, + + //#withUnrealizedGainOrLossActions + toggleUnrealizedGainOrLossFilterDrawer, +}) { + // Handle refetch unrealized Gain or Loss after filter change. + const handleFilterSubmit = (filter) => {}; + + // Handle format number submit. + const handleNumberFormatSubmit = (values) => {}; + + React.useEffect( + () => () => { + toggleUnrealizedGainOrLossFilterDrawer(false); + }, + [toggleUnrealizedGainOrLossFilterDrawer], + ); + + return ( + + + + + + + +
+ +
+
+
+
+ ); +} + +export default compose( + withCurrentOrganization(({ organization }) => ({ + organizationName: organization.name, + })), + withUnrealizedGainOrLossActions, +)(UnrealizedGainOrLoss); diff --git a/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLossActionsBar.js b/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLossActionsBar.js new file mode 100644 index 000000000..7e342ce3e --- /dev/null +++ b/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLossActionsBar.js @@ -0,0 +1,122 @@ +import React from 'react'; +import { + NavbarGroup, + NavbarDivider, + Button, + Classes, + Popover, + PopoverInteractionKind, + Position, +} from '@blueprintjs/core'; +import { FormattedMessage as T, Icon } from 'components'; +import classNames from 'classnames'; + +import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; +import NumberFormatDropdown from 'components/NumberFormatDropdown'; + +import { useUnrealizedGainOrLossContext } from './UnrealizedGainOrLossProvider'; +import withUnrealizedGainOrLoss from './withUnrealizedGainOrLoss'; +import withUnrealizedGainOrLossActions from './withUnrealizedGainOrLossActions'; + +import { compose, saveInvoke } from 'utils'; + +/** + * unrealized Gain or Loss actions bar. + */ +function UnrealizedGainOrLossActionsBar({ + //#withRealizedGainOrLoss + isFilterDrawerOpen, + + //#withRealizedGainOrLossActions + toggleUnrealizedGainOrLossFilterDrawer, + + //#ownProps + numberFormat, + onNumberFormatSubmit, +}) { + // Handle filter toggle click. + const handleFilterToggleClick = () => { + toggleUnrealizedGainOrLossFilterDrawer(); + }; + + // Handle recalculate report button. + const handleRecalculateReport = () => {}; + + // handle number format form submit. + const handleNumberFormatSubmit = (values) => + saveInvoke(onNumberFormatSubmit, values); + + return ( + + + + + + + + + ); +} + +export default compose( + withUnrealizedGainOrLoss(({ unrealizedGainOrLossDrawerFilter }) => ({ + isFilterDrawerOpen: unrealizedGainOrLossDrawerFilter, + })), + withUnrealizedGainOrLossActions, +)(UnrealizedGainOrLossHeader); diff --git a/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLossProvider.js b/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLossProvider.js new file mode 100644 index 000000000..a9400489a --- /dev/null +++ b/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLossProvider.js @@ -0,0 +1,22 @@ +import React from 'react'; + +import FinancialReportPage from '../FinancialReportPage'; + +const UnrealizedGainOrLossContext = React.createContext(); + +/** + * Unrealized Gain or Loss provider. + */ +function UnrealizedGainOrLossProvider({ filter, ...props }) { + const provider = {}; + return ( + + + + ); +} + +const useUnrealizedGainOrLossContext = () => + React.useContext(UnrealizedGainOrLossContext); + +export { UnrealizedGainOrLossProvider, useUnrealizedGainOrLossContext }; diff --git a/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLossTable.js b/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLossTable.js new file mode 100644 index 000000000..a5a99558c --- /dev/null +++ b/src/containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLossTable.js @@ -0,0 +1,21 @@ +import React from 'react'; +import intl from 'react-intl-universal'; + +import { DataTable } from 'components'; +import FinancialSheet from 'components/FinancialSheet'; + +/** + * Unrealized Gain or Loss table. + */ +export default function UnrealizedGainOrLossTable({ + // #ownProps + companyName, +}) { + return ( + + ); +} diff --git a/src/containers/FinancialStatements/UnrealizedGainOrLoss/components.js b/src/containers/FinancialStatements/UnrealizedGainOrLoss/components.js new file mode 100644 index 000000000..25d754b58 --- /dev/null +++ b/src/containers/FinancialStatements/UnrealizedGainOrLoss/components.js @@ -0,0 +1,18 @@ +import React from 'react'; +import { Button } from '@blueprintjs/core'; +import { Icon, If } from 'components'; +import { FormattedMessage as T } from 'components'; + +import { useUnrealizedGainOrLossContext } from './UnrealizedGainOrLossProvider'; +import FinancialLoadingBar from '../FinancialLoadingBar'; + +/** + * Unrealized Gain or Loss loading bar. + */ +export function UnrealizedGainOrLossLoadingBar() { + return ( + + + + ); +} diff --git a/src/containers/FinancialStatements/UnrealizedGainOrLoss/withUnrealizedGainOrLoss.js b/src/containers/FinancialStatements/UnrealizedGainOrLoss/withUnrealizedGainOrLoss.js new file mode 100644 index 000000000..4017486dd --- /dev/null +++ b/src/containers/FinancialStatements/UnrealizedGainOrLoss/withUnrealizedGainOrLoss.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux'; +import { getUnrealizedGainOrLossFilterDrawer } from '../../../store/financialStatement/financialStatements.selectors'; + +export default (mapState) => { + const mapStateToProps = (state, props) => { + const mapped = { + unrealizedGainOrLossDrawerFilter: getUnrealizedGainOrLossFilterDrawer(state), + }; + return mapState ? mapState(mapped, state, props) : mapped; + }; + return connect(mapStateToProps); +}; diff --git a/src/containers/FinancialStatements/UnrealizedGainOrLoss/withUnrealizedGainOrLossActions.js b/src/containers/FinancialStatements/UnrealizedGainOrLoss/withUnrealizedGainOrLossActions.js new file mode 100644 index 000000000..4c51a85dc --- /dev/null +++ b/src/containers/FinancialStatements/UnrealizedGainOrLoss/withUnrealizedGainOrLossActions.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; +import { toggleUnrealizedGainOrLossFilterDrawer } from '../../../store/financialStatement/financialStatements.actions'; + +const mapDispatchToProps = (dispatch) => ({ + toggleUnrealizedGainOrLossFilterDrawer: (toggle) => + dispatch(toggleUnrealizedGainOrLossFilterDrawer(toggle)), +}); + +export default connect(null, mapDispatchToProps); diff --git a/src/hooks/query/types.js b/src/hooks/query/types.js index cad5be4d3..85c9c26f1 100644 --- a/src/hooks/query/types.js +++ b/src/hooks/query/types.js @@ -25,6 +25,7 @@ const FINANCIAL_REPORTS = { INVENTORY_ITEM_DETAILS: 'INVENTORY_ITEM_DETAILS', TRANSACTIONS_BY_REFERENCE: 'TRANSACTIONS_BY_REFERENCE', REALIZED_GAIN_OR_LOSS: 'REALIZED_GAIN_OR_LOSS', + UNREALIZED_GAIN_OR_LOSS: 'UNREALIZED_GAIN_OR_LOSS', }; const BILLS = { diff --git a/src/lang/en/index.json b/src/lang/en/index.json index dc1d99646..51c53548b 100644 --- a/src/lang/en/index.json +++ b/src/lang/en/index.json @@ -1846,5 +1846,7 @@ "branch.dialog.label.website": "Website", "branch.dialog.success_message": "The branch has been created successfully.", "branch.alert.delete_message":"The branch has been deleted successfully", - "branch.once_delete_this_branch":"Once you delete this branch, you won't be able to restore it later. Are you sure you want to delete this branch?" + "branch.once_delete_this_branch":"Once you delete this branch, you won't be able to restore it later. Are you sure you want to delete this branch?", + "realized_gain_or_loss.label":"Realized Gain or Loss", + "unrealized_gain_or_loss.label":"Unrealized Gain or Loss" } \ No newline at end of file diff --git a/src/routes/dashboard.js b/src/routes/dashboard.js index 866c6d30a..b68457202 100644 --- a/src/routes/dashboard.js +++ b/src/routes/dashboard.js @@ -383,13 +383,25 @@ export const getDashboardRoutes = () => [ '../containers/FinancialStatements/RealizedGainOrLoss/RealizedGainOrLoss' ), ), - breadcrumb: intl.get('realized_gain_or_loss.label'), pageTitle: intl.get('realized_gain_or_loss.label'), backLink: true, sidebarExpand: false, subscriptionActive: [SUBSCRIPTION_TYPE.MAIN], }, + { + path: `/financial-reports/unrealized-gain-loss`, + component: lazy(() => + import( + '../containers/FinancialStatements/UnrealizedGainOrLoss/UnrealizedGainOrLoss' + ), + ), + breadcrumb: intl.get('unrealized_gain_or_loss.label'), + pageTitle: intl.get('unrealized_gain_or_loss.label'), + backLink: true, + sidebarExpand: false, + subscriptionActive: [SUBSCRIPTION_TYPE.MAIN], + }, { path: '/financial-reports', component: lazy(() => diff --git a/src/store/financialStatement/financialStatements.actions.js b/src/store/financialStatement/financialStatements.actions.js index b1229fd9e..7e6abef03 100644 --- a/src/store/financialStatement/financialStatements.actions.js +++ b/src/store/financialStatement/financialStatements.actions.js @@ -209,7 +209,7 @@ export function toggleInventoryItemDetailsFilterDrawer(toggle) { * Toggle display of the Realized Gain or Loss filter drawer. * @param {boolean} toggle */ -export function toggleRealizedGainOrLossCilterDrawer(toggle) { +export function toggleRealizedGainOrLossFilterDrawer(toggle) { return { type: `${t.REALIZED_GAIN_OR_LOSS}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`, payload: { @@ -217,3 +217,16 @@ export function toggleRealizedGainOrLossCilterDrawer(toggle) { }, }; } + +/** + * Toggle display of the Unrealized Gain or Loss filter drawer. + * @param {boolean} toggle + */ +export function toggleUnrealizedGainOrLossFilterDrawer(toggle) { + return { + type: `${t.UNREALIZED_GAIN_OR_LOSS}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`, + payload: { + toggle, + }, + }; +} diff --git a/src/store/financialStatement/financialStatements.reducer.js b/src/store/financialStatement/financialStatements.reducer.js index 9c6e0a1ff..8f206db6c 100644 --- a/src/store/financialStatement/financialStatements.reducer.js +++ b/src/store/financialStatement/financialStatements.reducer.js @@ -54,6 +54,9 @@ const initialState = { realizedGainOrLoss: { displayFilterDrawer: false, }, + unrealizedGainOrLoss: { + displayFilterDrawer: false, + }, }; /** @@ -106,5 +109,6 @@ export default createReducer(initialState, { 'inventoryItemDetails', ), ...financialStatementFilterToggle(t.REALIZED_GAIN_OR_LOSS, 'realizedGainOrLoss'), + ...financialStatementFilterToggle(t.UNREALIZED_GAIN_OR_LOSS, 'unrealizedGainOrLoss'), }); diff --git a/src/store/financialStatement/financialStatements.selectors.js b/src/store/financialStatement/financialStatements.selectors.js index 83de44342..a554ebb37 100644 --- a/src/store/financialStatement/financialStatements.selectors.js +++ b/src/store/financialStatement/financialStatements.selectors.js @@ -77,6 +77,10 @@ export const realizedGainOrLossFilterDrawerSelector = (state) => { return filterDrawerByTypeSelector('realizedGainOrLoss')(state); }; +export const unrealizedGainOrLossFilterDrawerSelector = (state) => { + return filterDrawerByTypeSelector('unrealizedGainOrLoss')(state); +}; + /** * Retrieve balance sheet filter drawer. */ @@ -253,3 +257,12 @@ export const getRealizedGainOrLossFilterDrawer = createSelector( return isOpen; }, ); +/** + * Retrieve Unrealized Gain or Loss filter drawer. + */ +export const getUnrealizedGainOrLossFilterDrawer = createSelector( + unrealizedGainOrLossFilterDrawerSelector, + (isOpen) => { + return isOpen; + }, +); diff --git a/src/store/financialStatement/financialStatements.types.js b/src/store/financialStatement/financialStatements.types.js index cdda1f369..98d37a1d5 100644 --- a/src/store/financialStatement/financialStatements.types.js +++ b/src/store/financialStatement/financialStatements.types.js @@ -17,4 +17,5 @@ export default { CASH_FLOW_STATEMENT: 'CASH FLOW STATEMENT', INVENTORY_ITEM_DETAILS: 'INVENTORY ITEM DETAILS', REALIZED_GAIN_OR_LOSS: 'REALIZED GAIN OR LOSS', + UNREALIZED_GAIN_OR_LOSS: 'UNREALIZED GAIN OR LOSS', };