diff --git a/src/common/abilityOption.js b/src/common/abilityOption.js index 61c128c5b..7f586f047 100644 --- a/src/common/abilityOption.js +++ b/src/common/abilityOption.js @@ -17,6 +17,8 @@ export const AbilitySubject = { Preferences: 'Preferences', ExchangeRate: 'ExchangeRate', SubscriptionBilling: 'SubscriptionBilling', + CreditNote: 'CreditNote', + VendorCredit: 'VendorCredit', }; export const ItemAction = { @@ -66,6 +68,21 @@ export const PaymentReceiveAction = { NotifyBySms: 'NotifyBySms', }; +export const CreditNoteAction = { + View: 'View', + Create: 'Create', + Edit: 'Edit', + Delete: 'Delete', + Refund: 'Refund' +}; + +export const VendorCreditAction = { + View: 'View', + Create: 'Create', + Edit: 'Edit', + Delete: 'Delete', + Refund: 'Refund' +}; export const BillAction = { View: 'View', Create: 'Create', diff --git a/src/common/permissionsSchema.js b/src/common/permissionsSchema.js new file mode 100644 index 000000000..0ab859a25 --- /dev/null +++ b/src/common/permissionsSchema.js @@ -0,0 +1,288 @@ +import { + AbilitySubject, + AccountAction, + BillAction, + CreditNoteAction, + CustomerAction, + ExpenseAction, + ItemAction, + ManualJournalAction, + PaymentMadeAction, + PaymentReceiveAction, + ReportsAction, + SaleEstimateAction, + SaleInvoiceAction, + SaleReceiptAction, + VendorAction, + VendorCreditAction +} from './abilityOption'; + +export const ModulePermissionsStyle = { + Columns: 'columns', + Vertical: 'vertical', +}; + +const PermissionColumn = { + View: 'view', + Create: 'create', + Delete: 'delete', + Edit: 'edit' +} + +export const permissions = [ + { + label: 'Items & Inventory', + type: ModulePermissionsStyle.Columns, + serviceFullAccess: true, + moduleFullAccess: true, + columns: [ + { label: 'View', key: 'view' }, + { label: 'Create', key: 'create' }, + { label: 'Edit', key: 'edit' }, + { label: 'Delete', key: 'delete' }, + ], + services: [ + { + label: 'Items', + subject: AbilitySubject.Item, + permissions: [ + { label: 'View', key: ItemAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: ItemAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: ItemAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: ItemAction.Delete, relatedColumn: PermissionColumn.Delete }, + ], + }, + { + label: 'Inventory adjustments', + subject: AbilitySubject.InventoryAdjustment, + permissions: [ + { label: 'View', key: ItemAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: ItemAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: ItemAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: ItemAction.Delete, relatedColumn: PermissionColumn.Delete }, + ], + }, + ], + }, + { + label: 'Contacts', + type: ModulePermissionsStyle.Columns, + serviceFullAccess: true, + moduleFullAccess: true, + columns: [ + { label: 'View', key: 'view' }, + { label: 'Create', key: 'create' }, + { label: 'Edit', key: 'edit' }, + { label: 'Delete', key: 'delete' }, + ], + services: [ + { + label: 'Customers', + subject: AbilitySubject.Customer, + permissions: [ + { label: 'View', key: CustomerAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: CustomerAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: CustomerAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: CustomerAction.Delete, relatedColumn: PermissionColumn.Delete }, + ], + }, + { + label: 'Vendors', + subject: AbilitySubject.Customer, + permissions: [ + { label: 'View', key: VendorAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: VendorAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: VendorAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: VendorAction.Delete, relatedColumn: PermissionColumn.Delete }, + ], + }, + ] + }, + { + label: 'Sales', + type: ModulePermissionsStyle.Columns, + serviceFullAccess: true, + moduleFullAccess: true, + columns: [ + { label: 'View', key: 'view' }, + { label: 'Create', key: 'create' }, + { label: 'Edit', key: 'edit' }, + { label: 'Delete', key: 'delete' }, + ], + services: [ + { + label: 'Sale Invoice', + subject: AbilitySubject.Invoice, + permissions: [ + { label: 'View', key: SaleInvoiceAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: SaleInvoiceAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: SaleInvoiceAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: SaleInvoiceAction.Delete, relatedColumn: PermissionColumn.Delete }, + { label: 'Written-off invoice', key: SaleInvoiceAction.Writeoff } + ], + }, + { + label: 'Sale Estimate', + subject: AbilitySubject.Estimate, + permissions: [ + { label: 'View', key: SaleEstimateAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: SaleEstimateAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: SaleEstimateAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: SaleEstimateAction.Delete, relatedColumn: PermissionColumn.Delete }, + ], + }, + { + label: 'Sale Receipt', + subject: AbilitySubject.Receipt, + permissions: [ + { label: 'View', key: SaleReceiptAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: SaleReceiptAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: SaleReceiptAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: SaleReceiptAction.Delete, relatedColumn: PermissionColumn.Delete }, + ], + }, + { + label: 'Credit note', + subject: AbilitySubject.CreditNote, + permissions: [ + { label: 'View', key: CreditNoteAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: CreditNoteAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: CreditNoteAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: CreditNoteAction.Delete, relatedColumn: PermissionColumn.Delete }, + { label: 'Refund credit note', key: CreditNoteAction.Refund } + ], + }, + { + label: 'Payment Receive', + subject: AbilitySubject.PaymentReceive, + permissions: [ + { label: 'View', key: PaymentReceiveAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: PaymentReceiveAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: PaymentReceiveAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: PaymentReceiveAction.Delete, relatedColumn: PermissionColumn.Delete }, + ], + }, + ] + }, + { + label: 'Purchases', + type: ModulePermissionsStyle.Columns, + serviceFullAccess: true, + moduleFullAccess: true, + columns: [ + { label: 'View', key: 'view' }, + { label: 'Create', key: 'create' }, + { label: 'Edit', key: 'edit' }, + { label: 'Delete', key: 'delete' }, + ], + services: [ + { + label: 'Bills', + subject: AbilitySubject.Bill, + permissions: [ + { label: 'View', key: BillAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: BillAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: BillAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: BillAction.Delete, relatedColumn: PermissionColumn.Delete }, + ], + }, + { + label: 'Vendor Credits', + subject: AbilitySubject.VendorCredit, + permissions: [ + { label: 'View', key: VendorCreditAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: VendorCreditAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: VendorCreditAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: VendorCreditAction.Delete, relatedColumn: PermissionColumn.Delete }, + { label: 'Refund vendor credit', key: VendorCreditAction.Refund } + ], + }, + { + label: 'Payment Made', + subject: AbilitySubject.PaymentMade, + permissions: [ + { label: 'View', key: PaymentMadeAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: PaymentMadeAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: PaymentMadeAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: PaymentMadeAction.Delete, relatedColumn: PermissionColumn.Delete }, + ], + }, + ] + }, + { + label: 'Financial Accounting', + type: ModulePermissionsStyle.Columns, + serviceFullAccess: true, + moduleFullAccess: true, + columns: [ + { label: 'View', key: 'view' }, + { label: 'Create', key: 'create' }, + { label: 'Edit', key: 'edit' }, + { label: 'Delete', key: 'delete' }, + ], + services: [ + { + label: 'Manual Journals', + subject: AbilitySubject.ManualJournal, + permissions: [ + { label: 'View', key: ManualJournalAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: ManualJournalAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: ManualJournalAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: ManualJournalAction.Delete, relatedColumn: PermissionColumn.Delete }, + ], + }, + { + label: 'Chart of Accounts', + subject: AbilitySubject.Account, + permissions: [ + { label: 'View', key: AccountAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: AccountAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: AccountAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: AccountAction.Delete, relatedColumn: PermissionColumn.Delete }, + { label: 'Transactions locking', key: AccountAction.TransactionsLocking }, + ], + }, + { + label: 'Expenses', + subject: AbilitySubject.Expense, + permissions: [ + { label: 'View', key: ExpenseAction.View, relatedColumn: PermissionColumn.View }, + { label: 'Create', key: ExpenseAction.Create, relatedColumn: PermissionColumn.Create }, + { label: 'Edit', key: ExpenseAction.Edit, relatedColumn: PermissionColumn.Edit }, + { label: 'Delete', key: ExpenseAction.Delete, relatedColumn: PermissionColumn.Delete }, + ], + }, + ] + }, + { + label: 'Financial Reports', + type: ModulePermissionsStyle.Vertical, + serviceFullAccess: true, + moduleFullAccess: true, + services: [ + { + label: 'Financial reprots', + subject: AbilitySubject.Report, + permissions: [ + { label: 'Balance sheet', key: ReportsAction.READ_BALANCE_SHEET }, + { label: 'Trial Balance sheet', key: ReportsAction.READ_TRIAL_BALANCE_SHEET }, + { label: 'Profit & Loss sheet', key: ReportsAction.READ_PROFIT_LOSS }, + { label: 'Cash flow sheet', key: ReportsAction.READ_CASHFLOW }, + { label: 'Journal sheet', key: ReportsAction.READ_JOURNAL }, + { label: 'General ledger', key: ReportsAction.READ_GENERAL_LEDGET }, + { label: 'A/R Aging Summary report', key: ReportsAction.READ_AR_AGING_SUMMARY }, + { label: 'A/P Aging Summary report', key: ReportsAction.READ_AP_AGING_SUMMARY }, + { label: 'Purchases by items', key: ReportsAction.READ_PURCHASES_BY_ITEMS }, + { label: 'Sales by items', key: ReportsAction.READ_SALES_BY_ITEMS }, + { label: 'Customers transactions', key: ReportsAction.READ_CUSTOMERS_TRANSACTIONS }, + { label: 'Vendors transactions', key: ReportsAction.READ_VENDORS_TRANSACTIONS }, + { label: 'Customers summary balance', key: ReportsAction.READ_CUSTOMERS_SUMMARY_BALANCE }, + { label: 'Vendors summary balance', key: ReportsAction.READ_VENDORS_SUMMARY_BALANCE }, + { label: 'Inventory valuation summary', key: ReportsAction.READ_INVENTORY_VALUATION_SUMMARY }, + { label: 'Inventory items details', key: ReportsAction.READ_INVENTORY_ITEM_DETAILS }, + { label: 'Cashflow account transactions', key: ReportsAction.READ_CASHFLOW_ACCOUNT_TRANSACTION }, + ], + }, + ], + } +]; diff --git a/src/components/Preferences/PreferencesPage.js b/src/components/Preferences/PreferencesPage.js index a0e23dc97..f6be83dda 100644 --- a/src/components/Preferences/PreferencesPage.js +++ b/src/components/Preferences/PreferencesPage.js @@ -1,6 +1,8 @@ import React from 'react'; import { ErrorBoundary } from 'react-error-boundary'; import classNames from 'classnames'; +import * as R from 'ramda'; + import { CLASSES } from 'common/classes'; import PreferencesTopbar from 'components/Preferences/PreferencesTopbar'; @@ -8,18 +10,28 @@ import PreferencesContentRoute from 'components/Preferences/PreferencesContentRo import DashboardErrorBoundary from 'components/Dashboard/DashboardErrorBoundary'; import PreferencesSidebar from 'components/Preferences/PreferencesSidebar'; +import withDashboardActions from 'containers/Dashboard/withDashboardActions'; + import 'style/pages/Preferences/Page.scss'; /** * Preferences page. */ -export default function PreferencesPage() { +function PreferencesPage({ toggleSidebarExpand }) { + // Shrink the dashboard sidebar once open application preferences page. + React.useEffect(() => { + toggleSidebarExpand(false); + }, [toggleSidebarExpand]); + return ( -
+
@@ -32,3 +44,5 @@ export default function PreferencesPage() { ); } + +export default R.compose(withDashboardActions)(PreferencesPage); diff --git a/src/containers/Preferences/Users/Roles/RolesForm/RoleFormFloatingActions.js b/src/containers/Preferences/Users/Roles/RolesForm/RoleFormFloatingActions.js new file mode 100644 index 000000000..322eafce0 --- /dev/null +++ b/src/containers/Preferences/Users/Roles/RolesForm/RoleFormFloatingActions.js @@ -0,0 +1,50 @@ +import React from 'react'; +import { useFormikContext } from 'formik'; +import styled from 'styled-components'; +import { Intent, Button } from '@blueprintjs/core'; +import { useHistory } from 'react-router-dom'; + +import { FormattedMessage as T } from 'components'; + +/** + * Role form floating actions. + * @returns {React.JSX} + */ +export function RoleFormFloatingActions() { + const { isSubmitting } = useFormikContext(); + const history = useHistory(); + + const handleCloseClick = () => { + history.go(-1); + }; + + return ( + + + + + ); +} + +const RoleFormFloatingActionsRoot = styled.div` + position: fixed; + bottom: 0; + width: 100%; + background: #fff; + padding: 14px 18px; + border-top: 1px solid #d2dde2; + box-shadow: 0px -1px 4px 0px rgb(0 0 0 / 5%); + + .bp3-button { + margin-right: 10px; + } +`; diff --git a/src/containers/Preferences/Users/Roles/RolesForm/RolesFormContent.js b/src/containers/Preferences/Users/Roles/RolesForm/RolesFormContent.js index ae2267054..d9a5ab85a 100644 --- a/src/containers/Preferences/Users/Roles/RolesForm/RolesFormContent.js +++ b/src/containers/Preferences/Users/Roles/RolesForm/RolesFormContent.js @@ -1,37 +1,27 @@ import React from 'react'; -import { useHistory } from 'react-router-dom'; -import { ErrorMessage, FastField, Form, useFormikContext } from 'formik'; -import { - Button, - FormGroup, - InputGroup, - Intent, - TextArea, -} from '@blueprintjs/core'; +import { ErrorMessage, FastField, Form } from 'formik'; +import { FormGroup, InputGroup, TextArea } from '@blueprintjs/core'; + import { inputIntent } from 'utils'; -import { FormattedMessage as T, FieldRequiredHint } from 'components'; +import { FormattedMessage as T, FieldRequiredHint, Card } from 'components'; import { useAutofocus } from 'hooks'; import { RolesPermissionList } from './components'; +import { RoleFormFloatingActions } from './RoleFormFloatingActions'; /** - * Preferences - Roles Form content. + * Role form header. + * @returns {React.JSX} */ -export default function RolesFormContent() { - const history = useHistory(); - - const { isSubmitting, values } = useFormikContext(); +function RoleFormHeader() { const roleNameFieldRef = useAutofocus(); - const handleCloseClick = () => { - history.go(-1); - }; return ( -
+ {/* ---------- name ---------- */} {({ field, meta: { error, touched } }) => ( } + label={} labelInfo={} className={'form-group--name'} intent={inputIntent({ error, touched })} @@ -57,20 +47,28 @@ export default function RolesFormContent() { helperText={} inline={true} > -