From afee2e90e024c40f0df537761c29d00b0babdedc Mon Sep 17 00:00:00 2001 From: elforjani13 <39470382+elforjani13@users.noreply.github.com> Date: Tue, 23 Nov 2021 15:24:53 +0200 Subject: [PATCH 01/18] ability. --- src/components/Abilities.js | 10 ++++++++++ src/components/Can.js | 4 ++++ src/components/Config/ability.js | 10 ++++++++++ src/containers/Items/ItemsActionsBar.js | 20 +++++++++++++------- 4 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 src/components/Abilities.js create mode 100644 src/components/Can.js create mode 100644 src/components/Config/ability.js diff --git a/src/components/Abilities.js b/src/components/Abilities.js new file mode 100644 index 000000000..152ea01b0 --- /dev/null +++ b/src/components/Abilities.js @@ -0,0 +1,10 @@ +import { AbilityBuilder, defineAbility } from '@casl/ability'; +import { createContextualCan } from '@casl/react'; +import { createContext } from 'react'; + +export const AbilityContext = createContext(); +export const Can = createContextualCan(AbilityContext.Consumer); + +export const ability = defineAbility((can, cannot) => { + cannot('Item', 'create'); +}); diff --git a/src/components/Can.js b/src/components/Can.js new file mode 100644 index 000000000..9ba7fe434 --- /dev/null +++ b/src/components/Can.js @@ -0,0 +1,4 @@ +import { createCanBoundTo } from '@casl/react'; +import ability from '../components/Config/ability'; + +export default createCanBoundTo(ability); \ No newline at end of file diff --git a/src/components/Config/ability.js b/src/components/Config/ability.js new file mode 100644 index 000000000..72342959f --- /dev/null +++ b/src/components/Config/ability.js @@ -0,0 +1,10 @@ +import { AbilityBuilder } from '@casl/ability'; +// import { AbilitySubject, ItemAbility } from '../../common/abilityOption'; + +export function defineAbilitiesFor(role) { + const { rules, can } = new AbilityBuilder(); + + can('create', 'Item'); + + return new Ability(rules); +} diff --git a/src/containers/Items/ItemsActionsBar.js b/src/containers/Items/ItemsActionsBar.js index 67e30c732..e882ac19d 100644 --- a/src/containers/Items/ItemsActionsBar.js +++ b/src/containers/Items/ItemsActionsBar.js @@ -30,6 +30,9 @@ import withSettings from '../Settings/withSettings'; import { compose } from 'utils'; import withSettingsActions from '../Settings/withSettingsActions'; + +import { Can, AbilityContext } from '../../components/Abilities'; + /** * Items actions bar. */ @@ -57,6 +60,8 @@ function ItemsActionsBar({ // Items refresh action. const { refresh } = useRefreshItems(); + const { ability } = React.useContext(AbilityContext); + // History context. const history = useHistory(); @@ -101,13 +106,14 @@ function ItemsActionsBar({ /> - + - + + } /> diff --git a/src/containers/Customers/CustomersLanding/CustomersEmptyStatus.js b/src/containers/Customers/CustomersLanding/CustomersEmptyStatus.js index 6ef1d135e..d91a3c043 100644 --- a/src/containers/Customers/CustomersLanding/CustomersEmptyStatus.js +++ b/src/containers/Customers/CustomersLanding/CustomersEmptyStatus.js @@ -2,7 +2,11 @@ import React from 'react'; import { Button, Intent } from '@blueprintjs/core'; import { useHistory } from 'react-router-dom'; import { EmptyStatus } from 'components'; -import { FormattedMessage as T } from 'components'; +import { Can, FormattedMessage as T } from 'components'; +import { + AbilitySubject, + Customer_Abilities, +} from '../../../common/abilityOption'; export default function CustomersEmptyStatus() { const history = useHistory(); @@ -17,19 +21,21 @@ export default function CustomersEmptyStatus() { } action={ <> - + + - + + } /> diff --git a/src/containers/Expenses/ExpensesLanding/ExpensesEmptyStatus.js b/src/containers/Expenses/ExpensesLanding/ExpensesEmptyStatus.js index 84ed56b0e..abfc31ada 100644 --- a/src/containers/Expenses/ExpensesLanding/ExpensesEmptyStatus.js +++ b/src/containers/Expenses/ExpensesLanding/ExpensesEmptyStatus.js @@ -2,7 +2,11 @@ import React from 'react'; import { Button, Intent } from '@blueprintjs/core'; import { useHistory } from 'react-router-dom'; import { EmptyStatus } from 'components'; -import { FormattedMessage as T } from 'components'; +import { Can, FormattedMessage as T } from 'components'; +import { + AbilitySubject, + Expense_Abilities, +} from '../../../common/abilityOption'; export default function InvoicesEmptyStatus() { const history = useHistory(); @@ -17,19 +21,21 @@ export default function InvoicesEmptyStatus() { } action={ <> - + + - + + } /> diff --git a/src/containers/Items/ItemsEmptyStatus.js b/src/containers/Items/ItemsEmptyStatus.js index 3a0c53fe3..ba018c705 100644 --- a/src/containers/Items/ItemsEmptyStatus.js +++ b/src/containers/Items/ItemsEmptyStatus.js @@ -2,7 +2,8 @@ import React from 'react'; import { Button, Intent } from '@blueprintjs/core'; import { useHistory } from 'react-router-dom'; import { EmptyStatus } from 'components'; -import { FormattedMessage as T } from 'components'; +import { Can, FormattedMessage as T } from 'components'; +import { Item_Abilities, AbilitySubject } from '../../common/abilityOption'; export default function ItemsEmptyStatus() { const history = useHistory(); @@ -17,19 +18,21 @@ export default function ItemsEmptyStatus() { } action={ <> - + + - + + } /> diff --git a/src/containers/Purchases/Bills/BillsLanding/BillsEmptyStatus.js b/src/containers/Purchases/Bills/BillsLanding/BillsEmptyStatus.js index cecfef2ad..674d228ee 100644 --- a/src/containers/Purchases/Bills/BillsLanding/BillsEmptyStatus.js +++ b/src/containers/Purchases/Bills/BillsLanding/BillsEmptyStatus.js @@ -2,7 +2,11 @@ import React from 'react'; import { Button, Intent } from '@blueprintjs/core'; import { useHistory } from 'react-router-dom'; import { EmptyStatus } from 'components'; -import { FormattedMessage as T } from 'components'; +import { Can, FormattedMessage as T } from 'components'; +import { + Bill_Abilities, + AbilitySubject, +} from '../../../../common/abilityOption'; export default function BillsEmptyStatus() { const history = useHistory(); @@ -17,19 +21,21 @@ export default function BillsEmptyStatus() { } action={ <> - + + - + + } /> diff --git a/src/containers/Purchases/PaymentMades/PaymentsLanding/PaymentMadesEmptyStatus.js b/src/containers/Purchases/PaymentMades/PaymentsLanding/PaymentMadesEmptyStatus.js index ada8352ba..077c2d368 100644 --- a/src/containers/Purchases/PaymentMades/PaymentsLanding/PaymentMadesEmptyStatus.js +++ b/src/containers/Purchases/PaymentMades/PaymentsLanding/PaymentMadesEmptyStatus.js @@ -2,7 +2,11 @@ import React from 'react'; import { Button, Intent } from '@blueprintjs/core'; import { useHistory } from 'react-router-dom'; import { EmptyStatus } from 'components'; -import { FormattedMessage as T } from 'components'; +import { Can, FormattedMessage as T } from 'components'; +import { + Payment_Made_Abilities, + AbilitySubject, +} from '../../../../common/abilityOption'; export default function PaymentMadesEmptyStatus() { const history = useHistory(); @@ -17,19 +21,21 @@ export default function PaymentMadesEmptyStatus() { } action={ <> - + + - + + } /> diff --git a/src/containers/Sales/Estimates/EstimatesLanding/EstimatesEmptyStatus.js b/src/containers/Sales/Estimates/EstimatesLanding/EstimatesEmptyStatus.js index c2e5e92fa..12669d3d6 100644 --- a/src/containers/Sales/Estimates/EstimatesLanding/EstimatesEmptyStatus.js +++ b/src/containers/Sales/Estimates/EstimatesLanding/EstimatesEmptyStatus.js @@ -2,7 +2,11 @@ import React from 'react'; import { Button, Intent } from '@blueprintjs/core'; import { useHistory } from 'react-router-dom'; import { EmptyStatus } from 'components'; -import { FormattedMessage as T } from 'components'; +import { Can, FormattedMessage as T } from 'components'; +import { + Estimate_Abilities, + AbilitySubject, +} from '../../../../common/abilityOption'; export default function EstimatesEmptyStatus() { const history = useHistory(); @@ -16,18 +20,20 @@ export default function EstimatesEmptyStatus() { } action={ <> - - + + + + } /> diff --git a/src/containers/Sales/Invoices/InvoicesLanding/InvoicesEmptyStatus.js b/src/containers/Sales/Invoices/InvoicesLanding/InvoicesEmptyStatus.js index 21212a4c2..268976c00 100644 --- a/src/containers/Sales/Invoices/InvoicesLanding/InvoicesEmptyStatus.js +++ b/src/containers/Sales/Invoices/InvoicesLanding/InvoicesEmptyStatus.js @@ -2,7 +2,11 @@ import React from 'react'; import { Button, Intent } from '@blueprintjs/core'; import { useHistory } from 'react-router-dom'; import { EmptyStatus } from 'components'; -import { FormattedMessage as T } from 'components'; +import { Can, FormattedMessage as T } from 'components'; +import { + Invoice_Abilities, + AbilitySubject, +} from '../../../../common/abilityOption'; export default function EstimatesEmptyStatus() { const history = useHistory(); @@ -17,19 +21,20 @@ export default function EstimatesEmptyStatus() { } action={ <> - - - + + + + } /> diff --git a/src/containers/Sales/PaymentReceives/PaymentsLanding/PaymentReceivesEmptyStatus.js b/src/containers/Sales/PaymentReceives/PaymentsLanding/PaymentReceivesEmptyStatus.js index 6b0df1b31..876602f7d 100644 --- a/src/containers/Sales/PaymentReceives/PaymentsLanding/PaymentReceivesEmptyStatus.js +++ b/src/containers/Sales/PaymentReceives/PaymentsLanding/PaymentReceivesEmptyStatus.js @@ -2,7 +2,11 @@ import React from 'react'; import { Button, Intent } from '@blueprintjs/core'; import { useHistory } from 'react-router-dom'; import { EmptyStatus } from 'components'; -import { FormattedMessage as T } from 'components'; +import { Can, FormattedMessage as T } from 'components'; +import { + Payment_Receive_Abilities, + AbilitySubject, +} from '../../../../common/abilityOption'; export default function PaymentReceivesEmptyStatus() { const history = useHistory(); @@ -12,24 +16,31 @@ export default function PaymentReceivesEmptyStatus() { title={} description={

- +

} action={ <> - + - + + } /> diff --git a/src/containers/Sales/Receipts/ReceiptsLanding/ReceiptsEmptyStatus.js b/src/containers/Sales/Receipts/ReceiptsLanding/ReceiptsEmptyStatus.js index e029ddf9b..612179004 100644 --- a/src/containers/Sales/Receipts/ReceiptsLanding/ReceiptsEmptyStatus.js +++ b/src/containers/Sales/Receipts/ReceiptsLanding/ReceiptsEmptyStatus.js @@ -2,7 +2,11 @@ import React from 'react'; import { Button, Intent } from '@blueprintjs/core'; import { useHistory } from 'react-router-dom'; import { EmptyStatus } from 'components'; -import { FormattedMessage as T } from 'components'; +import { Can, FormattedMessage as T } from 'components'; +import { + Receipt_Abilities, + AbilitySubject, +} from '../../../../common/abilityOption'; export default function ReceiptsEmptyStatus() { const history = useHistory(); @@ -17,19 +21,21 @@ export default function ReceiptsEmptyStatus() { } action={ <> - + + - + + } /> diff --git a/src/containers/Vendors/VendorsLanding/VendorsEmptyStatus.js b/src/containers/Vendors/VendorsLanding/VendorsEmptyStatus.js index 5ce0cdc33..192d2a80c 100644 --- a/src/containers/Vendors/VendorsLanding/VendorsEmptyStatus.js +++ b/src/containers/Vendors/VendorsLanding/VendorsEmptyStatus.js @@ -2,7 +2,11 @@ import React from 'react'; import { Button, Intent } from '@blueprintjs/core'; import { useHistory } from 'react-router-dom'; import { EmptyStatus } from 'components'; -import { FormattedMessage as T } from 'components'; +import { Can, FormattedMessage as T } from 'components'; +import { + Vendor_Abilities, + AbilitySubject, +} from '../../../common/abilityOption'; export default function VendorsEmptyStatus() { const history = useHistory(); @@ -17,19 +21,21 @@ export default function VendorsEmptyStatus() { } action={ <> - + + - + + } /> From 553334f06324b73560f3aad14ddebb9f8a60d574 Mon Sep 17 00:00:00 2001 From: elforjani13 <39470382+elforjani13@users.noreply.github.com> Date: Wed, 24 Nov 2021 14:09:24 +0200 Subject: [PATCH 15/18] feat: ability home page option. --- src/common/homepageOptions.js | 75 +++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/src/common/homepageOptions.js b/src/common/homepageOptions.js index 82972db3a..6f61b7172 100644 --- a/src/common/homepageOptions.js +++ b/src/common/homepageOptions.js @@ -1,5 +1,20 @@ import React from 'react'; import { FormattedMessage as T } from 'components'; +import { + Invoice_Abilities, + Estimate_Abilities, + AbilitySubject, + Receipt_Abilities, + Customer_Abilities, + Payment_Receive_Abilities, + Bill_Abilities, + Vendor_Abilities, + Payment_Made_Abilities, + Account_Abilities, + Manual_Journal_Abilities, + Expense_Abilities, + Item_Abilities, +} from '../common/abilityOption'; export const accountsReceivable = [ { @@ -9,21 +24,29 @@ export const accountsReceivable = [ title: , description: , link: '/invoices', + subject: AbilitySubject.Invoice, + ability: Invoice_Abilities.View, }, { title: , description: , link: '/estimates', + subject: AbilitySubject.Estimate, + ability: Estimate_Abilities.View, }, { title: , description: , link: '/receipts', + subject: AbilitySubject.Receipt, + ability: Receipt_Abilities.View, }, { title: , description: , link: '/customers', + subject: AbilitySubject.Customer, + ability: Customer_Abilities.View, }, { title: , @@ -31,6 +54,8 @@ export const accountsReceivable = [ ), link: '/payment-receives', + subject: AbilitySubject.PaymentReceive, + ability: Payment_Receive_Abilities.View, }, ], }, @@ -46,6 +71,8 @@ export const accountsPayable = [ ), link: '/bills', + subject: AbilitySubject.Bill, + ability: Bill_Abilities.View, }, { title: , @@ -53,11 +80,15 @@ export const accountsPayable = [ ), link: '/vendors', + subject: AbilitySubject.Vendor, + ability: Vendor_Abilities.View, }, { title: , description: , link: '/payment-mades', + subject: AbilitySubject.PaymentMade, + ability: Payment_Made_Abilities.View, }, ], }, @@ -77,20 +108,32 @@ export const financialAccounting = [ /> ), link: '/accounts', + subject: AbilitySubject.Account, + ability: Account_Abilities.View, }, { - title: , - description:, + title: , + description: ( + + ), link: '/manual-journals', + subject: AbilitySubject.ManualJournal, + ability: Manual_Journal_Abilities.View, }, { - title: , - description:, + title: , + description: ( + + ), link: '/expenses', + subject: AbilitySubject.Expense, + ability: Expense_Abilities.View, }, { - title: , - description:, + title: , + description: ( + + ), link: '/financial-reports', }, ], @@ -102,19 +145,27 @@ export const productsServices = [ sectionTitle: , shortcuts: [ { - title: , - description:, + title: , + description: ( + + ), link: '/items', + subject: AbilitySubject.Item, + ability: Item_Abilities.View, }, { - title: , - description:, + title: , + description: , link: 'items/categories', }, { - title: , - description: , + title: , + description: ( + + ), link: '/inventory-adjustments', + subject: AbilitySubject.Inventory_Adjustment, + ability: Invoice_Abilities.View, }, ], }, From 9ceee6d02ea6c689d02ce2cb6dfa597c8f8b61b5 Mon Sep 17 00:00:00 2001 From: elforjani13 <39470382+elforjani13@users.noreply.github.com> Date: Wed, 24 Nov 2021 14:35:38 +0200 Subject: [PATCH 16/18] feat: reports abilities. --- src/common/abilityOption.js | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/common/abilityOption.js b/src/common/abilityOption.js index e1db1296a..9b140a5ff 100644 --- a/src/common/abilityOption.js +++ b/src/common/abilityOption.js @@ -115,21 +115,21 @@ export const Cashflow_Abilities = { }; export const Report_Abilities = { - READ_BALANCE_SHEET = 'read-balance-sheet', - READ_TRIAL_BALANCE_SHEET = 'read-trial-balance-sheet', - READ_PROFIT_LOSS = 'read-profit-loss', - READ_JOURNAL = 'read-journal', - READ_GENERAL_LEDGET = 'read-general-ledger', - READ_CASHFLOW = 'read-cashflow', - READ_AR_AGING_SUMMARY = 'read-ar-aging-summary', - READ_AP_AGING_SUMMARY = 'read-ap-aging-summary', - READ_PURCHASES_BY_ITEMS = 'read-purchases-by-items', - READ_SALES_BY_ITEMS = 'read-sales-by-items', - READ_CUSTOMERS_TRANSACTIONS = 'read-customers-transactions', - READ_VENDORS_TRANSACTIONS = 'read-vendors-transactions', - READ_CUSTOMERS_SUMMARY_BALANCE = 'read-customers-summary-balance', - READ_VENDORS_SUMMARY_BALANCE = 'read-vendors-summary-balance', - READ_INVENTORY_VALUATION_SUMMARY = 'read-inventory-valuation-summary', - READ_INVENTORY_ITEM_DETAILS = 'read-inventory-item-details', - READ_CASHFLOW_ACCOUNT_TRANSACTION = 'read-cashflow-account-transactions' + READ_BALANCE_SHEET: 'read-balance-sheet', + READ_TRIAL_BALANCE_SHEET: 'read-trial-balance-sheet', + READ_PROFIT_LOSS: 'read-profit-loss', + READ_JOURNAL: 'read-journal', + READ_GENERAL_LEDGET: 'read-general-ledger', + READ_CASHFLOW: 'read-cashflow', + READ_AR_AGING_SUMMARY: 'read-ar-aging-summary', + READ_AP_AGING_SUMMARY: 'read-ap-aging-summary', + READ_PURCHASES_BY_ITEMS: 'read-purchases-by-items', + READ_SALES_BY_ITEMS: 'read-sales-by-items', + READ_CUSTOMERS_TRANSACTIONS: 'read-customers-transactions', + READ_VENDORS_TRANSACTIONS: 'read-vendors-transactions', + READ_CUSTOMERS_SUMMARY_BALANCE: 'read-customers-summary-balance', + READ_VENDORS_SUMMARY_BALANCE: 'read-vendors-summary-balance', + READ_INVENTORY_VALUATION_SUMMARY: 'read-inventory-valuation-summary', + READ_INVENTORY_ITEM_DETAILS: 'read-inventory-item-details', + READ_CASHFLOW_ACCOUNT_TRANSACTION: 'read-cashflow-account-transactions', }; From 2630e0235d921abcd5936ac5dd0175d25c17d13d Mon Sep 17 00:00:00 2001 From: elforjani13 <39470382+elforjani13@users.noreply.github.com> Date: Thu, 25 Nov 2021 13:02:09 +0200 Subject: [PATCH 17/18] feat: add cashflow & vendor ability. --- .../AccountTransactions/components.js | 32 ++++--- .../CashFlowAccountsActionsBar.js | 49 ++++++---- .../CashFlowAccounts/CashflowAccountsGrid.js | 92 +++++++++++-------- .../CashflowTransactionDrawerActionBar.js | 31 ++++--- .../VendorsLanding/VendorActionsBar.js | 13 ++- 5 files changed, 127 insertions(+), 90 deletions(-) diff --git a/src/containers/CashFlow/AccountTransactions/components.js b/src/containers/CashFlow/AccountTransactions/components.js index 528d6afe2..78dae22d5 100644 --- a/src/containers/CashFlow/AccountTransactions/components.js +++ b/src/containers/CashFlow/AccountTransactions/components.js @@ -4,9 +4,13 @@ import intl from 'react-intl-universal'; import { Intent, Menu, MenuItem, MenuDivider } from '@blueprintjs/core'; import { MaterialProgressBar } from 'components'; -import { FormatDateCell, If, Icon } from 'components'; +import { Can, FormatDateCell, If, Icon } from 'components'; import { useAccountTransactionsContext } from './AccountTransactionsProvider'; import { TRANSACRIONS_TYPE } from 'common/cashflowOptions'; +import { + AbilitySubject, + Cashflow_Abilities, +} from '../../../common/abilityOption'; import { safeCallback } from 'utils'; export function ActionsMenu({ @@ -20,15 +24,17 @@ export function ActionsMenu({ text={intl.get('view_details')} onClick={safeCallback(onViewDetails, original)} /> - - - } - /> - + + + + } + /> + + ); } @@ -83,7 +89,7 @@ export function useAccountTransactionsColumns() { className: 'deposit', textOverview: true, align: 'right', - clickable: true + clickable: true, }, { id: 'withdrawal', @@ -93,7 +99,7 @@ export function useAccountTransactionsColumns() { width: 150, textOverview: true, align: 'right', - clickable: true + clickable: true, }, { id: 'running_balance', @@ -103,7 +109,7 @@ export function useAccountTransactionsColumns() { width: 150, textOverview: true, align: 'right', - clickable: true + clickable: true, }, { id: 'balance', diff --git a/src/containers/CashFlow/CashFlowAccounts/CashFlowAccountsActionsBar.js b/src/containers/CashFlow/CashFlowAccounts/CashFlowAccountsActionsBar.js index cb9e86b84..68420cfb4 100644 --- a/src/containers/CashFlow/CashFlowAccounts/CashFlowAccountsActionsBar.js +++ b/src/containers/CashFlow/CashFlowAccounts/CashFlowAccountsActionsBar.js @@ -7,8 +7,12 @@ import { Alignment, Switch, } from '@blueprintjs/core'; -import { Icon, FormattedMessage as T } from 'components'; +import { Can, Icon, FormattedMessage as T } from 'components'; import { useRefreshCashflowAccounts } from 'hooks/query'; +import { + Cashflow_Abilities, + AbilitySubject, +} from '../../../common/abilityOption'; import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; @@ -56,19 +60,22 @@ function CashFlowAccountsActionsBar({ return ( -