From 5aae45c8a8a1f0454d5ce6fa069439cd24d3e933 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Tue, 25 Jun 2024 11:57:02 +0200 Subject: [PATCH] feat(webapp): bank rules --- .../Dashboard/DashboardActionsBar.tsx | 10 +- .../webapp/src/constants/abilityOption.tsx | 11 +- packages/webapp/src/constants/sidebarMenu.tsx | 5 + .../Banking/Rules/RuleFormDialog/RuleForm.tsx | 0 .../Rules/RuleFormDialog/RuleFormBoot.tsx | 32 +++++ .../Rules/RuleFormDialog/RuleFormContent.tsx | 19 +++ .../RuleFormContentForm.schema.ts | 13 ++ .../RuleFormDialog/RuleFormContentForm.tsx | 134 ++++++++++++++++++ .../Rules/RuleFormDialog/RuleFormDialog.tsx | 33 +++++ .../RulesList/BankRulesLandingEmptyState.tsx | 39 +++++ .../Banking/Rules/RulesList/RulesList.tsx | 20 +++ .../Rules/RulesList/RulesListActionsBar.tsx | 10 ++ .../Banking/Rules/RulesList/RulesListBoot.tsx | 30 ++++ .../Banking/Rules/RulesList/RulesTable.tsx | 81 +++++++++++ .../Banking/Rules/RulesList/_components.tsx | 38 +++++ .../Banking/Rules/RulesList/hooks.ts | 3 + packages/webapp/src/routes/dashboard.tsx | 8 ++ 17 files changed, 483 insertions(+), 3 deletions(-) create mode 100644 packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleForm.tsx create mode 100644 packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormBoot.tsx create mode 100644 packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContent.tsx create mode 100644 packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.schema.ts create mode 100644 packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.tsx create mode 100644 packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormDialog.tsx create mode 100644 packages/webapp/src/containers/Banking/Rules/RulesList/BankRulesLandingEmptyState.tsx create mode 100644 packages/webapp/src/containers/Banking/Rules/RulesList/RulesList.tsx create mode 100644 packages/webapp/src/containers/Banking/Rules/RulesList/RulesListActionsBar.tsx create mode 100644 packages/webapp/src/containers/Banking/Rules/RulesList/RulesListBoot.tsx create mode 100644 packages/webapp/src/containers/Banking/Rules/RulesList/RulesTable.tsx create mode 100644 packages/webapp/src/containers/Banking/Rules/RulesList/_components.tsx create mode 100644 packages/webapp/src/containers/Banking/Rules/RulesList/hooks.ts diff --git a/packages/webapp/src/components/Dashboard/DashboardActionsBar.tsx b/packages/webapp/src/components/Dashboard/DashboardActionsBar.tsx index 29a2f3bb4..f78398442 100644 --- a/packages/webapp/src/components/Dashboard/DashboardActionsBar.tsx +++ b/packages/webapp/src/components/Dashboard/DashboardActionsBar.tsx @@ -3,7 +3,15 @@ import React from 'react'; import clsx from 'classnames'; import { Navbar } from '@blueprintjs/core'; -export function DashboardActionsBar({ className, children, name }) { +interface DashboardActionsBarProps { + children?: React.ReactNode; +} + +export function DashboardActionsBar({ + className, + children, + name, +}: DashboardActionsBarProps) { return (
( + {} as RuleFormBootValues, +); + +interface RuleFormBootProps { + bankRuleId?: number; + children: React.ReactNode; +} + +function RuleFormBoot({ bankRuleId, ...props }: RuleFormBootProps) { + const provider = {} as RuleFormBootValues; + + return ( + + + + ); +} + +const useRuleFormDialogBoot = () => + React.useContext(RuleFormBootContext); + +export { RuleFormBoot, useRuleFormDialogBoot }; diff --git a/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContent.tsx b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContent.tsx new file mode 100644 index 000000000..e96b1d500 --- /dev/null +++ b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContent.tsx @@ -0,0 +1,19 @@ +import { RuleFormBoot } from "./RuleFormBoot"; + + +interface RuleFormContentProps { + dialogName: string; + bankRuleId?: number; +} +export function RuleFormContent({ + dialogName, + bankRuleId, +}: RuleFormContentProps) { + return ( + + + + ); +} diff --git a/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.schema.ts b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.schema.ts new file mode 100644 index 000000000..3cde8f265 --- /dev/null +++ b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.schema.ts @@ -0,0 +1,13 @@ +// @ts-nocheck +import * as Yup from 'yup'; + +const Schema = Yup.object().shape({ + name: Yup.string().required().label('Rule name'), + applyIfAccountId: Yup.number().required().label(''), + applyIfTransactionType: Yup.string().required().label(''), + conditionsType: Yup.string().required(), + assignCategory: Yup.string().required(), + assignAccountId: Yup.string().required(), +}); + +export const CreateRuleFormSchema = Schema; diff --git a/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.tsx b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.tsx new file mode 100644 index 000000000..a018fe9df --- /dev/null +++ b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormContentForm.tsx @@ -0,0 +1,134 @@ +import { Form, Formik, useFormikContext } from 'formik'; +import { Button, Radio } from '@blueprintjs/core'; +import { CreateRuleFormSchema } from './RuleFormContentForm.schema'; +import { + Box, + FFormGroup, + FInputGroup, + FRadioGroup, + FSelect, + Group, +} from '@/components'; + +const initialValues = { + name: '', + order: 0, + applyIfAccountId: '', + applyIfTransactionType: '', + conditionsType: '', + conditions: [ + { + field: 'description', + comparator: 'contains', + value: 'payment', + }, + ], + assignCategory: '', + assignAccountId: '', +}; + +interface RuleFormValues { + name: string; + order: number; + applyIfAccountId: string; + applyIfTransactionType: string; + conditionsType: string; + conditions: Array<{ + field: string; + comparator: string; + value: string; + }>; + assignCategory: string; + assignAccountId: string; +} + +export function RuleFormContentForm() { + const validationSchema = CreateRuleFormSchema; + const handleSubmit = () => {}; + + return ( + + initialValues={initialValues} + validationSchema={validationSchema} + onSubmit={handleSubmit} + > +
+ + + + + + + + + + + + + + + + + +

Then Assign

+ + + + + + + + + + + + + + + ); +} + +function RuleFormConditions() { + const { values } = useFormikContext(); + + const handleAddConditionBtnClick = () => { + values.conditions.push({ + field: '', + comparator: '', + value: '', + }); + }; + + return ( + + {values?.conditions?.map((condition, index) => ( + + + + + + + + + + + + + + ))} + + + + ); +} diff --git a/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormDialog.tsx b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormDialog.tsx new file mode 100644 index 000000000..5fa6929f7 --- /dev/null +++ b/packages/webapp/src/containers/Banking/Rules/RuleFormDialog/RuleFormDialog.tsx @@ -0,0 +1,33 @@ +// @ts-nocheck +import React from 'react'; +import { Dialog, DialogSuspense } from '@/components'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import { compose } from '@/utils'; + +const RuleFormContent = React.lazy(() => import('./RuleFormContent')); + +/** + * Payment mail dialog. + */ +function RuleFormDialog({ + dialogName, + payload: { bankRuleId = null }, + isOpen, +}) { + return ( + + + + + + ); +} + +export default compose(withDialogRedux())(RuleFormDialog); diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/BankRulesLandingEmptyState.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/BankRulesLandingEmptyState.tsx new file mode 100644 index 000000000..4ad67f0b6 --- /dev/null +++ b/packages/webapp/src/containers/Banking/Rules/RulesList/BankRulesLandingEmptyState.tsx @@ -0,0 +1,39 @@ +// @ts-nocheck +import * as R from 'ramda'; +import { Button, Intent } from '@blueprintjs/core'; +import { EmptyStatus, Can, FormattedMessage as T } from '@/components'; +import { AbilitySubject, BankRuleAction } from '@/constants/abilityOption'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; + +function BankRulesLandingEmptyStateRoot({ + // #withDialogAction + openDialog, +}) { + return ( + + Setup the organization taxes to start tracking taxes on sales + transactions. +

+ } + action={ + <> + + + + + + } + /> + ); +} + +export const BankRulesLandingEmptyState = R.compose(withDialogActions)( + BankRulesLandingEmptyStateRoot, +); diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/RulesList.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesList.tsx new file mode 100644 index 000000000..8c35a99ae --- /dev/null +++ b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesList.tsx @@ -0,0 +1,20 @@ +// @ts-nocheck +import { DashboardPageContent } from '@/components'; +import { RulesListBoot } from './RulesListBoot'; +import { RulesListActionsBar } from './RulesListActionsBar'; +import { BankRulesTable } from './RulesTable'; + +/** + * + */ +export function RulesList() { + return ( + + + + + + + + ); +} diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListActionsBar.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListActionsBar.tsx new file mode 100644 index 000000000..2f538afef --- /dev/null +++ b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListActionsBar.tsx @@ -0,0 +1,10 @@ +import { DashboardActionsBar } from '@/components'; +import { NavbarGroup } from '@blueprintjs/core'; + +export function RulesListActionsBar() { + return ( + + + + ); +} diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListBoot.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListBoot.tsx new file mode 100644 index 000000000..71035fd60 --- /dev/null +++ b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesListBoot.tsx @@ -0,0 +1,30 @@ +import React, { createContext } from 'react'; +import { DialogContent } from '@/components'; + +interface RulesListBootValues { + rules: any; + isRulesLoading: boolean; +} + +const RulesListBootContext = createContext( + {} as RulesListBootValues, +); + +interface RulesListBootProps { + children: React.ReactNode; +} + +function RulesListBoot({ ...props }: RulesListBootProps) { + const provider = {} as RulesListBootValues; + + return ( + + + + ); +} + +const useRulesListBoot = () => + React.useContext(RulesListBootContext); + +export { RulesListBoot, useRulesListBoot }; diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/RulesTable.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesTable.tsx new file mode 100644 index 000000000..966b86bc8 --- /dev/null +++ b/packages/webapp/src/containers/Banking/Rules/RulesList/RulesTable.tsx @@ -0,0 +1,81 @@ +// @ts-nocheck +import * as R from 'ramda'; +import { + DataTable, + DashboardContentTable, + TableSkeletonHeader, + TableSkeletonRows, +} from '@/components'; + +import withAlertsActions from '@/containers/Alert/withAlertActions'; +import withDrawerActions from '@/containers/Drawer/withDrawerActions'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withDashboardActions from '@/containers/Dashboard/withDashboardActions'; + +import { useBankRulesTableColumns } from './hooks'; +import { BankRulesTableActionsMenu } from './_components'; +import { BankRulesLandingEmptyState } from './BankRulesLandingEmptyState'; + +/** + * Invoices datatable. + */ +function RulesTable({ + // #withAlertsActions + openAlert, + + // #withDrawerActions + openDrawer, + + // #withDialogAction + openDialog, +}) { + // Invoices table columns. + const columns = useBankRulesTableColumns(); + + // Handle edit bank rule. + const handleDeleteBankRule = ({ id }) => {}; + + // Handle delete bank rule. + const handleEditBankRule = () => {}; + + // Display invoice empty status instead of the table. + if (isEmptyStatus) { + return ; + } + + return ( + + + + ); +} + +export const BankRulesTable = R.compose( + withDashboardActions, + withAlertsActions, + withDrawerActions, + withDialogActions, +)(RulesTable); diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/_components.tsx b/packages/webapp/src/containers/Banking/Rules/RulesList/_components.tsx new file mode 100644 index 000000000..a33c86dde --- /dev/null +++ b/packages/webapp/src/containers/Banking/Rules/RulesList/_components.tsx @@ -0,0 +1,38 @@ +// @ts-nocheck +import React from 'react'; +import { Intent, Menu, MenuDivider, MenuItem } from '@blueprintjs/core'; +import { Can, Icon } from '@/components'; +import { AbilitySubject, BankRuleAction } from '@/constants/abilityOption'; +import { safeCallback } from '@/utils'; + +/** + * Tax rates table actions menu. + * @returns {JSX.Element} + */ +export function BankRulesTableActionsMenu({ + payload: { onEdit, onDelete }, + row: { original }, +}) { + return ( + + + + } + text={'Edit Rule'} + onClick={safeCallback(onEdit, original)} + /> + + + + + } + /> + + + ); +} diff --git a/packages/webapp/src/containers/Banking/Rules/RulesList/hooks.ts b/packages/webapp/src/containers/Banking/Rules/RulesList/hooks.ts new file mode 100644 index 000000000..3ba4e2106 --- /dev/null +++ b/packages/webapp/src/containers/Banking/Rules/RulesList/hooks.ts @@ -0,0 +1,3 @@ +export const useBankRulesTableColumns = () => { + return []; +}; diff --git a/packages/webapp/src/routes/dashboard.tsx b/packages/webapp/src/routes/dashboard.tsx index 8f1122bae..afd35824d 100644 --- a/packages/webapp/src/routes/dashboard.tsx +++ b/packages/webapp/src/routes/dashboard.tsx @@ -1221,6 +1221,14 @@ export const getDashboardRoutes = () => [ pageTitle: 'Tax Rates', subscriptionActive: [SUBSCRIPTION_TYPE.MAIN], }, + // Bank Rules + { + path: '/bank-rules', + component: lazy( + () => import('@/containers/Banking/Rules/RulesList/RulesList'), + ), + pageTitle: 'Bank Rules', + }, // Homepage { path: `/`,