mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 06:40:31 +00:00
Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop
This commit is contained in:
@@ -17,6 +17,8 @@ export const AbilitySubject = {
|
|||||||
Preferences: 'Preferences',
|
Preferences: 'Preferences',
|
||||||
ExchangeRate: 'ExchangeRate',
|
ExchangeRate: 'ExchangeRate',
|
||||||
SubscriptionBilling: 'SubscriptionBilling',
|
SubscriptionBilling: 'SubscriptionBilling',
|
||||||
|
CreditNote: 'CreditNote',
|
||||||
|
VendorCredit: 'VendorCredit',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ItemAction = {
|
export const ItemAction = {
|
||||||
@@ -66,6 +68,21 @@ export const PaymentReceiveAction = {
|
|||||||
NotifyBySms: 'NotifyBySms',
|
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 = {
|
export const BillAction = {
|
||||||
View: 'View',
|
View: 'View',
|
||||||
Create: 'Create',
|
Create: 'Create',
|
||||||
|
|||||||
288
src/common/permissionsSchema.js
Normal file
288
src/common/permissionsSchema.js
Normal file
@@ -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 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ErrorBoundary } from 'react-error-boundary';
|
import { ErrorBoundary } from 'react-error-boundary';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import * as R from 'ramda';
|
||||||
|
|
||||||
import { CLASSES } from 'common/classes';
|
import { CLASSES } from 'common/classes';
|
||||||
|
|
||||||
import PreferencesTopbar from 'components/Preferences/PreferencesTopbar';
|
import PreferencesTopbar from 'components/Preferences/PreferencesTopbar';
|
||||||
@@ -8,18 +10,28 @@ import PreferencesContentRoute from 'components/Preferences/PreferencesContentRo
|
|||||||
import DashboardErrorBoundary from 'components/Dashboard/DashboardErrorBoundary';
|
import DashboardErrorBoundary from 'components/Dashboard/DashboardErrorBoundary';
|
||||||
import PreferencesSidebar from 'components/Preferences/PreferencesSidebar';
|
import PreferencesSidebar from 'components/Preferences/PreferencesSidebar';
|
||||||
|
|
||||||
|
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||||
|
|
||||||
import 'style/pages/Preferences/Page.scss';
|
import 'style/pages/Preferences/Page.scss';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preferences page.
|
* Preferences page.
|
||||||
*/
|
*/
|
||||||
export default function PreferencesPage() {
|
function PreferencesPage({ toggleSidebarExpand }) {
|
||||||
|
// Shrink the dashboard sidebar once open application preferences page.
|
||||||
|
React.useEffect(() => {
|
||||||
|
toggleSidebarExpand(false);
|
||||||
|
}, [toggleSidebarExpand]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary FallbackComponent={DashboardErrorBoundary}>
|
<ErrorBoundary FallbackComponent={DashboardErrorBoundary}>
|
||||||
<div id={'dashboard'} className={classNames(
|
<div
|
||||||
CLASSES.DASHBOARD_CONTENT,
|
id={'dashboard'}
|
||||||
CLASSES.DASHBOARD_CONTENT_PREFERENCES,
|
className={classNames(
|
||||||
)}>
|
CLASSES.DASHBOARD_CONTENT,
|
||||||
|
CLASSES.DASHBOARD_CONTENT_PREFERENCES,
|
||||||
|
)}
|
||||||
|
>
|
||||||
<div className={classNames(CLASSES.PREFERENCES_PAGE)}>
|
<div className={classNames(CLASSES.PREFERENCES_PAGE)}>
|
||||||
<PreferencesSidebar />
|
<PreferencesSidebar />
|
||||||
|
|
||||||
@@ -32,3 +44,5 @@ export default function PreferencesPage() {
|
|||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default R.compose(withDashboardActions)(PreferencesPage);
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
<RoleFormFloatingActionsRoot>
|
||||||
|
<Button
|
||||||
|
intent={Intent.PRIMARY}
|
||||||
|
loading={isSubmitting}
|
||||||
|
type="submit"
|
||||||
|
style={{ minWidth: '90px' }}
|
||||||
|
>
|
||||||
|
<T id={'save'} />
|
||||||
|
</Button>
|
||||||
|
<Button onClick={handleCloseClick} disabled={isSubmitting}>
|
||||||
|
<T id={'cancel'} />
|
||||||
|
</Button>
|
||||||
|
</RoleFormFloatingActionsRoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
`;
|
||||||
@@ -1,37 +1,27 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { ErrorMessage, FastField, Form } from 'formik';
|
||||||
import { ErrorMessage, FastField, Form, useFormikContext } from 'formik';
|
import { FormGroup, InputGroup, TextArea } from '@blueprintjs/core';
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
FormGroup,
|
|
||||||
InputGroup,
|
|
||||||
Intent,
|
|
||||||
TextArea,
|
|
||||||
} from '@blueprintjs/core';
|
|
||||||
import { inputIntent } from 'utils';
|
import { inputIntent } from 'utils';
|
||||||
import { FormattedMessage as T, FieldRequiredHint } from 'components';
|
import { FormattedMessage as T, FieldRequiredHint, Card } from 'components';
|
||||||
import { useAutofocus } from 'hooks';
|
import { useAutofocus } from 'hooks';
|
||||||
import { RolesPermissionList } from './components';
|
import { RolesPermissionList } from './components';
|
||||||
|
import { RoleFormFloatingActions } from './RoleFormFloatingActions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preferences - Roles Form content.
|
* Role form header.
|
||||||
|
* @returns {React.JSX}
|
||||||
*/
|
*/
|
||||||
export default function RolesFormContent() {
|
function RoleFormHeader() {
|
||||||
const history = useHistory();
|
|
||||||
|
|
||||||
const { isSubmitting, values } = useFormikContext();
|
|
||||||
const roleNameFieldRef = useAutofocus();
|
const roleNameFieldRef = useAutofocus();
|
||||||
|
|
||||||
const handleCloseClick = () => {
|
|
||||||
history.go(-1);
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<Form>
|
<Card>
|
||||||
{/* ---------- name ---------- */}
|
{/* ---------- name ---------- */}
|
||||||
<FastField name={'role_name'}>
|
<FastField name={'role_name'}>
|
||||||
{({ field, meta: { error, touched } }) => (
|
{({ field, meta: { error, touched } }) => (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'name'} />}
|
label={<strong><T id={'role_name'} /></strong>}
|
||||||
labelInfo={<FieldRequiredHint />}
|
labelInfo={<FieldRequiredHint />}
|
||||||
className={'form-group--name'}
|
className={'form-group--name'}
|
||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
@@ -57,20 +47,28 @@ export default function RolesFormContent() {
|
|||||||
helperText={<ErrorMessage name={'role_description'} />}
|
helperText={<ErrorMessage name={'role_description'} />}
|
||||||
inline={true}
|
inline={true}
|
||||||
>
|
>
|
||||||
<TextArea growVertically={true} height={280} {...field} />
|
<TextArea
|
||||||
|
growVertically={true}
|
||||||
|
height={280}
|
||||||
|
{...field}
|
||||||
|
placeholder="Max. 500 characters"
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
<RolesPermissionList />
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
<div className={'card__footer'}>
|
/**
|
||||||
<Button intent={Intent.PRIMARY} loading={isSubmitting} type="submit">
|
* Preferences - Roles Form content.
|
||||||
<T id={'save'} />
|
*/
|
||||||
</Button>
|
export default function RolesFormContent() {
|
||||||
<Button onClick={handleCloseClick} disabled={isSubmitting}>
|
return (
|
||||||
<T id={'cancel'} />
|
<Form>
|
||||||
</Button>
|
<RoleFormHeader />
|
||||||
</div>
|
<RolesPermissionList />
|
||||||
|
<RoleFormFloatingActions />
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { CLASSES } from 'common/classes';
|
import { CLASSES } from 'common/classes';
|
||||||
import _, { isArray } from 'lodash';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
useCreateRolePermissionSchema,
|
useCreateRolePermissionSchema,
|
||||||
@@ -10,7 +9,6 @@ import {
|
|||||||
useRolePermission,
|
useRolePermission,
|
||||||
} from 'hooks/query';
|
} from 'hooks/query';
|
||||||
import PreferencesPageLoader from '../../../PreferencesPageLoader';
|
import PreferencesPageLoader from '../../../PreferencesPageLoader';
|
||||||
import { transformToObject } from './utils';
|
|
||||||
|
|
||||||
const RolesFormContext = React.createContext();
|
const RolesFormContext = React.createContext();
|
||||||
|
|
||||||
@@ -32,10 +30,12 @@ function RolesFormProvider({ roleId, ...props }) {
|
|||||||
isFetching: isPermissionsSchemaFetching,
|
isFetching: isPermissionsSchemaFetching,
|
||||||
} = usePermissionsSchema();
|
} = usePermissionsSchema();
|
||||||
|
|
||||||
const { data: role, isLoading: isPermissionLoading } =
|
const { data: role, isLoading: isPermissionLoading } = useRolePermission(
|
||||||
useRolePermission(roleId, {
|
roleId,
|
||||||
|
{
|
||||||
enabled: !!roleId,
|
enabled: !!roleId,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// Detarmines whether the new or edit mode.
|
// Detarmines whether the new or edit mode.
|
||||||
const isNewMode = !roleId;
|
const isNewMode = !roleId;
|
||||||
@@ -59,13 +59,11 @@ function RolesFormProvider({ roleId, ...props }) {
|
|||||||
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT_ROLES_FORM,
|
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT_ROLES_FORM,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className={classNames(CLASSES.CARD)}>
|
{isPermissionsSchemaLoading || isPermissionLoading ? (
|
||||||
{isPermissionsSchemaLoading || isPermissionLoading ? (
|
<PreferencesPageLoader />
|
||||||
<PreferencesPageLoader />
|
) : (
|
||||||
) : (
|
<RolesFormContext.Provider value={provider} {...props} />
|
||||||
<RolesFormContext.Provider value={provider} {...props} />
|
)}
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,148 +1,496 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Checkbox } from '@blueprintjs/core';
|
import { Checkbox, Switch, Popover } from '@blueprintjs/core';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { castArray } from 'lodash';
|
import { FastField } from 'formik';
|
||||||
|
|
||||||
import { FastField, useFormikContext } from 'formik';
|
import { permissions, ModulePermissionsStyle } from 'common/permissionsSchema';
|
||||||
import { useRolesFormContext } from './RolesFormProvider';
|
import { Card, If, ButtonLink, Choose } from 'components';
|
||||||
|
import {
|
||||||
|
getSerivceColumnPermission,
|
||||||
|
getServiceExtraPermissions,
|
||||||
|
} from './utils';
|
||||||
|
|
||||||
const RoleLabelCheckbox = ({ subject, label, description }) => (
|
// Module permissions context.
|
||||||
<>
|
const ModulePermissionsContext = React.createContext();
|
||||||
<LabelCheckbox>
|
const ModuleServiceContext = React.createContext();
|
||||||
{/*------------- subject checbox ------------- */}
|
|
||||||
<FastField name={subject} type="checkbox">
|
|
||||||
{({ form: { setFieldValue, values }, field }) => (
|
|
||||||
<Checkbox
|
|
||||||
className={'block'}
|
|
||||||
inline={true}
|
|
||||||
label={label}
|
|
||||||
name={subject}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
<p>{description}</p>
|
|
||||||
</LabelCheckbox>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
|
|
||||||
const AbilitiesList = ({ subject, abilities }) => {
|
/**
|
||||||
|
* Retrieves the module permissions provider.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
const useModulePermissionsProvider = () =>
|
||||||
|
React.useContext(ModulePermissionsContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module permissions service context provider.
|
||||||
|
*/
|
||||||
|
const useModulePermissionsServiceProvider = () =>
|
||||||
|
React.useContext(ModuleServiceContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module permissions context state provider.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function ModulePermissionsProvider({ module, children }) {
|
||||||
return (
|
return (
|
||||||
<AbilitieList>
|
<ModulePermissionsContext.Provider value={{ module }}>
|
||||||
{abilities?.map(({ key, label }) => (
|
{children}
|
||||||
<FastField name={`permissions.${subject}/${key}`} type="checkbox">
|
</ModulePermissionsContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module permissions service context state provider.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function ModulePermissionsServiceProvider({ service, children }) {
|
||||||
|
return (
|
||||||
|
<ModuleServiceContext.Provider value={{ service }}>
|
||||||
|
{children}
|
||||||
|
</ModuleServiceContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permissions body columns.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function PermissionBodyColumn({ column }) {
|
||||||
|
// Module permssions service context.
|
||||||
|
const { service } = useModulePermissionsServiceProvider();
|
||||||
|
|
||||||
|
// Retrieve the related permission of the given column key.
|
||||||
|
const permission = getSerivceColumnPermission(service, column.key);
|
||||||
|
|
||||||
|
// Display empty cell if the current column key has no related permissions.
|
||||||
|
if (!permission) {
|
||||||
|
return <td class={'permission-checkbox'}></td>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<td class={'permission-checkbox'}>
|
||||||
|
<FastField
|
||||||
|
name={`permissions.${service.subject}/${permission.key}`}
|
||||||
|
type="checkbox"
|
||||||
|
>
|
||||||
|
{({ field }) => <PermissionCheckbox inline={true} {...field} />}
|
||||||
|
</FastField>
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function ModulePermissionsTableColumns({ columns }) {
|
||||||
|
return columns.map((column) => <PermissionBodyColumn column={column} />);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module columns permissions extra permissions popover.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function ModuleExtraPermissionsPopover() {
|
||||||
|
const { service } = useModulePermissionsServiceProvider();
|
||||||
|
|
||||||
|
// Retrieve the extra permissions of the given service.
|
||||||
|
const extraPermissions = getServiceExtraPermissions(service);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover>
|
||||||
|
<MorePermissionsLink>More Permissions</MorePermissionsLink>
|
||||||
|
|
||||||
|
<ExtraPermissionsRoot>
|
||||||
|
{extraPermissions.map((permission) => (
|
||||||
|
<FastField
|
||||||
|
name={`permissions.${service.subject}/${permission.key}`}
|
||||||
|
type="checkbox"
|
||||||
|
>
|
||||||
|
{({ form: { setFieldValue, values }, field }) => (
|
||||||
|
<PermissionCheckbox
|
||||||
|
inline={true}
|
||||||
|
label={permission.label}
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</FastField>
|
||||||
|
))}
|
||||||
|
</ExtraPermissionsRoot>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module permissions extra permissions.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function ModulePermissionExtraPermissions() {
|
||||||
|
const { service } = useModulePermissionsServiceProvider();
|
||||||
|
|
||||||
|
// Retrieve the extra permissions of the given service.
|
||||||
|
const extraPermissions = getServiceExtraPermissions(service);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<td>
|
||||||
|
<If condition={extraPermissions.length > 0}>
|
||||||
|
<ModuleExtraPermissionsPopover />
|
||||||
|
</If>
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module permissions table head.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function ModulePermissionsTableHead() {
|
||||||
|
const {
|
||||||
|
module: { serviceFullAccess, columns },
|
||||||
|
} = useModulePermissionsProvider();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<If condition={serviceFullAccess}>
|
||||||
|
<th class={'full'}>Full Access</th>
|
||||||
|
</If>
|
||||||
|
{columns.map((column) => (
|
||||||
|
<th class={'permission'}>{column.label}</th>
|
||||||
|
))}
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module permissions service full access.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function ModulePermissionsServiceFullAccess() {
|
||||||
|
// Module permissions provider.
|
||||||
|
const { module } = useModulePermissionsProvider();
|
||||||
|
|
||||||
|
// Module service provider.
|
||||||
|
const { service } = useModulePermissionsServiceProvider();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<If condition={module.serviceFullAccess}>
|
||||||
|
<td class="full-access-permission">
|
||||||
|
<FastField
|
||||||
|
name={`serviceFullAccess.${service.subject}`}
|
||||||
|
type="checkbox"
|
||||||
|
>
|
||||||
{({ form: { setFieldValue, values }, field }) => (
|
{({ form: { setFieldValue, values }, field }) => (
|
||||||
<Checkbox inline={true} label={label} {...field} />
|
<PermissionCheckbox inline={true} />
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
))}
|
</td>
|
||||||
</AbilitieList>
|
</If>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
const ExtraAbilitiesList = ({ subject, extraAbilities }) => {
|
/**
|
||||||
return extraAbilities?.map(({ key, label }) => (
|
* Module permissions table body.
|
||||||
<AbilitieList>
|
* @returns {React.JSX}
|
||||||
<FastField name={`permissions.${subject}/${key}`} type="checkbox">
|
*/
|
||||||
{({ form: { setFieldValue, values }, field }) => (
|
function ModulePermissionsTableBody() {
|
||||||
<Checkbox inline={true} label={label} {...field} />
|
const {
|
||||||
)}
|
module: { services, columns },
|
||||||
</FastField>
|
} = useModulePermissionsProvider();
|
||||||
</AbilitieList>
|
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
export const RolesPermissionList = () => {
|
|
||||||
const { permissionsSchema } = useRolesFormContext();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GroupList>
|
<tbody>
|
||||||
<BoxedGroupList>
|
{services.map((service) => (
|
||||||
{permissionsSchema.map(
|
<ModulePermissionsServiceProvider service={service}>
|
||||||
({
|
<tr>
|
||||||
subject,
|
<td className="service-label">{service.label} </td>
|
||||||
subject_label,
|
|
||||||
description,
|
|
||||||
abilities,
|
|
||||||
extra_abilities,
|
|
||||||
}) => {
|
|
||||||
const extraAbilitiesList = Array.isArray(extra_abilities)
|
|
||||||
? extra_abilities
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const abilitiesList = castArray(abilities) ? abilities : [];
|
<ModulePermissionsServiceFullAccess />
|
||||||
|
<ModulePermissionsTableColumns columns={columns} />
|
||||||
|
<ModulePermissionExtraPermissions />
|
||||||
|
</tr>
|
||||||
|
</ModulePermissionsServiceProvider>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
/**
|
||||||
<React.Fragment>
|
* Module permissions table.
|
||||||
<RoleList>
|
* @returns {React.JSX}
|
||||||
<RoleLabelCheckbox
|
*/
|
||||||
subject={subject}
|
function ModulePermissionsTable() {
|
||||||
label={subject_label}
|
return (
|
||||||
description={description}
|
<ModulePermissionsTableRoot>
|
||||||
/>
|
<ModulePermissionsTableHead />
|
||||||
|
<ModulePermissionsTableBody />
|
||||||
|
</ModulePermissionsTableRoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
<AbilitiesList subject={subject} abilities={abilitiesList} />
|
/**
|
||||||
<ExtraAbilitiesList
|
* Module vertical table cells.
|
||||||
subject={subject}
|
* @returns {React.JSX}
|
||||||
extraAbilities={extraAbilitiesList}
|
*/
|
||||||
/>
|
function ModuleVerticalTableCells() {
|
||||||
</RoleList>
|
const { service } = useModulePermissionsServiceProvider();
|
||||||
</React.Fragment>
|
|
||||||
);
|
return (
|
||||||
},
|
<td class={'permissions'}>
|
||||||
)}
|
{service.permissions.map((permission) => (
|
||||||
</BoxedGroupList>
|
<div>
|
||||||
</GroupList>
|
<FastField
|
||||||
|
name={`permissions.${service.subject}/${permission.key}`}
|
||||||
|
type="checkbox"
|
||||||
|
>
|
||||||
|
{({ form: { setFieldValue, values }, field }) => (
|
||||||
|
<PermissionCheckbox
|
||||||
|
inline={true}
|
||||||
|
label={permission.label}
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</FastField>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module permissions vertical services.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function ModulePermissionsVerticalServices() {
|
||||||
|
const { module } = useModulePermissionsProvider();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModulePermissionsVerticalServicesRoot>
|
||||||
|
<ModulePermissionsVerticalTable>
|
||||||
|
<tbody>
|
||||||
|
{module.services.map((service) => (
|
||||||
|
<ModulePermissionsServiceProvider service={service}>
|
||||||
|
<tr>
|
||||||
|
<td class={'service-label'}>{service.label} </td>
|
||||||
|
<ModuleVerticalTableCells />
|
||||||
|
</tr>
|
||||||
|
</ModulePermissionsServiceProvider>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</ModulePermissionsVerticalTable>
|
||||||
|
</ModulePermissionsVerticalServicesRoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module permissions body.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function ModulePermissionsBody() {
|
||||||
|
const { module } = useModulePermissionsProvider();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModulePermissionBodyRoot>
|
||||||
|
<Choose>
|
||||||
|
<Choose.When
|
||||||
|
condition={module.type === ModulePermissionsStyle.Vertical}
|
||||||
|
>
|
||||||
|
<ModulePermissionsVerticalServices />
|
||||||
|
</Choose.When>
|
||||||
|
|
||||||
|
<Choose.When condition={module.type === ModulePermissionsStyle.Columns}>
|
||||||
|
<ModulePermissionsTable />
|
||||||
|
</Choose.When>
|
||||||
|
</Choose>
|
||||||
|
</ModulePermissionBodyRoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permissions module.
|
||||||
|
* @returns {React.JSX}
|
||||||
|
*/
|
||||||
|
function ModulePermissions({ module }) {
|
||||||
|
return (
|
||||||
|
<ModulePermissionsRoot>
|
||||||
|
<ModulePermissionsProvider module={module}>
|
||||||
|
<ModulePermissionHead>
|
||||||
|
<ModulePermissionTitle>{module.label} </ModulePermissionTitle>
|
||||||
|
|
||||||
|
<If condition={module.moduleFullAccess}>
|
||||||
|
<ModulePermissionFullControlRoot>
|
||||||
|
<Switch />
|
||||||
|
</ModulePermissionFullControlRoot>
|
||||||
|
</If>
|
||||||
|
</ModulePermissionHead>
|
||||||
|
|
||||||
|
<ModulePermissionsBody />
|
||||||
|
</ModulePermissionsProvider>
|
||||||
|
</ModulePermissionsRoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permissions modules list.
|
||||||
|
* @return {React.JSX}
|
||||||
|
*/
|
||||||
|
export const RolesPermissionList = () => {
|
||||||
|
return (
|
||||||
|
<ModulesPermission>
|
||||||
|
{permissions.map((module) => (
|
||||||
|
<ModulePermissions module={module} />
|
||||||
|
))}
|
||||||
|
</ModulesPermission>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const GroupList = styled.div`
|
const PermissionCheckbox = styled(Checkbox)`
|
||||||
list-style: none;
|
&.bp3-control.bp3-checkbox .bp3-control-indicator {
|
||||||
border: 1px solid #d2dce2;
|
border-radius: 2px;
|
||||||
border-radius: 6px;
|
border-color: #555;
|
||||||
font-size: 13px;
|
|
||||||
|
|
||||||
ul:first-child > li:last-child {
|
&,
|
||||||
border-bottom: 0;
|
&:before {
|
||||||
border-top: 0;
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const BoxedGroupList = styled.ul`
|
const ModulesPermission = styled.div``;
|
||||||
margin: 0;
|
|
||||||
list-style: none;
|
const ModulePermissionsRoot = styled(Card)`
|
||||||
|
padding: 0 !important;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const RoleList = styled.li`
|
const ModulePermissionHead = styled.div`
|
||||||
display: block;
|
border-bottom: 1px solid #d9d9d9;
|
||||||
padding: 5px 10px;
|
height: 38px;
|
||||||
margin: 0;
|
padding: 0 15px;
|
||||||
line-height: 20px;
|
display: flex;
|
||||||
border-bottom: 1px solid #e0e0e0;
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const LabelCheckbox = styled.label`
|
const ModulePermissionTitle = styled.div`
|
||||||
> * {
|
font-weight: 500;
|
||||||
display: inline-block;
|
font-size: 16px;
|
||||||
}
|
line-height: 38px;
|
||||||
.block {
|
color: #878787;
|
||||||
width: 220px;
|
`;
|
||||||
padding: 2px 0;
|
|
||||||
font-weight: 500;
|
const ModulePermissionFullControlRoot = styled.div`
|
||||||
|
margin-left: auto;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.bp3-switch {
|
||||||
|
margin: auto;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const AbilitieList = styled.ul`
|
const ModulePermissionBodyRoot = styled.div``;
|
||||||
list-style: none;
|
|
||||||
/* margin-left: 12px; // 10px */
|
|
||||||
margin: 0px 10px 0px;
|
|
||||||
|
|
||||||
> li {
|
const ModulePermissionsTableRoot = styled.table`
|
||||||
display: inline-block;
|
border-spacing: 0;
|
||||||
margin-top: 3px;
|
|
||||||
|
thead {
|
||||||
|
tr th {
|
||||||
|
font-weight: 400;
|
||||||
|
vertical-align: top;
|
||||||
|
|
||||||
|
&.full,
|
||||||
|
&.permission {
|
||||||
|
min-width: 70px;
|
||||||
|
}
|
||||||
|
&.full {
|
||||||
|
background-color: #fcfcfc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thead,
|
||||||
|
tbody {
|
||||||
|
tr td,
|
||||||
|
tr th {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
border-left: 1px solid #eee;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
&:first-of-type {
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:last-of-type td {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr td:last-of-type,
|
||||||
|
tr th:last-of-type {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody {
|
||||||
|
tr td.service-label {
|
||||||
|
min-width: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr td {
|
||||||
|
.bp3-control.bp3-inline {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.full-access-permission {
|
||||||
|
background-color: #fcfcfc;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.full-access-permission,
|
||||||
|
&.permission-checkbox {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const AbilitiesChildList = styled.li`
|
const MorePermissionsLink = styled(ButtonLink)`
|
||||||
display: inline-block;
|
font-size: 12px;
|
||||||
margin-top: 3px;
|
`;
|
||||||
|
|
||||||
|
const ExtraPermissionsRoot = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 15px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const ModulePermissionsVerticalServicesRoot = styled.div``;
|
||||||
|
|
||||||
|
const ModulePermissionsVerticalTable = styled.table`
|
||||||
|
border-spacing: 0;
|
||||||
|
|
||||||
|
tbody {
|
||||||
|
tr td {
|
||||||
|
padding: 10px;
|
||||||
|
vertical-align: top;
|
||||||
|
border-left: 1px solid #eee;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
|
||||||
|
&.service-label {
|
||||||
|
min-width: 250px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-of-type {
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.permissions {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:last-of-type td {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -51,3 +51,15 @@ export const getNewRoleInitialValues = (schema) => {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getSerivceColumnPermission(service, columnKey) {
|
||||||
|
return service.permissions.find((permission) => {
|
||||||
|
return permission.relatedColumn === columnKey;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getServiceExtraPermissions(service) {
|
||||||
|
return service.permissions.filter((permission) => {
|
||||||
|
return !permission.relatedColumn;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -1653,5 +1653,6 @@
|
|||||||
"overview": "Overview",
|
"overview": "Overview",
|
||||||
"transactions": "Transactions",
|
"transactions": "Transactions",
|
||||||
"item.drawer_transactions_by": "Transactions by:",
|
"item.drawer_transactions_by": "Transactions by:",
|
||||||
"item.drawer_quantity_sold": "Quantity Sold"
|
"item.drawer_quantity_sold": "Quantity Sold",
|
||||||
|
"role_name": "Role name"
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
// Objects
|
// Objects
|
||||||
@import 'objects/form';
|
@import 'objects/form';
|
||||||
|
@import 'objects/switch';
|
||||||
@import 'objects/typography';
|
@import 'objects/typography';
|
||||||
@import 'objects/buttons';
|
@import 'objects/buttons';
|
||||||
@import 'objects/Bigcapital';
|
@import 'objects/Bigcapital';
|
||||||
|
|||||||
8
src/style/objects/switch.scss
Normal file
8
src/style/objects/switch.scss
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
.bp3-control.bp3-switch {
|
||||||
|
.bp3-control-indicator {
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,6 +33,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&__inside-content {
|
&__inside-content {
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
.#{$ns}-tab-list {
|
.#{$ns}-tab-list {
|
||||||
border-bottom: 1px solid #e5e5e5;
|
border-bottom: 1px solid #e5e5e5;
|
||||||
padding-left: 15px;
|
padding-left: 15px;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// Roles Form page
|
// Roles Form page
|
||||||
//---------------------------------
|
//---------------------------------
|
||||||
.preferences-page__inside-content--roles-form {
|
.preferences-page__inside-content--roles-form {
|
||||||
|
padding-bottom: 60px;
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
padding: 25px;
|
padding: 25px;
|
||||||
|
|
||||||
@@ -20,17 +22,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bp3-form-group {
|
.bp3-form-group {
|
||||||
max-width: 500px;
|
max-width: 600px;
|
||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
|
|
||||||
&.bp3-inline {
|
&.bp3-inline {
|
||||||
.bp3-label {
|
.bp3-label {
|
||||||
min-width: 100px;
|
min-width: 150px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.bp3-form-content {
|
.bp3-form-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:last-of-type{
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.form-group--description {
|
.form-group--description {
|
||||||
textarea {
|
textarea {
|
||||||
@@ -39,20 +45,4 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.bp3-control.bp3-checkbox {
|
|
||||||
.bp3-control-indicator {
|
|
||||||
border: 1px solid #c2c2c2;
|
|
||||||
cursor: auto;
|
|
||||||
|
|
||||||
&,
|
|
||||||
&:hover {
|
|
||||||
height: 15px;
|
|
||||||
width: 15px;
|
|
||||||
}
|
|
||||||
&:before {
|
|
||||||
width: 15px;
|
|
||||||
height: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// Preferences sidebar.
|
// Preferences sidebar.
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
.preferences-sidebar {
|
.preferences-sidebar {
|
||||||
background: #e5eaee;
|
background: #eaeef6;
|
||||||
border-right: 1px solid #c6d0d9;
|
border-right: 1px solid #c6d0d9;
|
||||||
min-width: 220px;
|
min-width: 220px;
|
||||||
max-width: 220px;
|
max-width: 220px;
|
||||||
@@ -13,13 +13,17 @@
|
|||||||
&__wrapper {
|
&__wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ScrollbarsCustom-Track {
|
.ScrollbarsCustom-Track {
|
||||||
|
|
||||||
&.ScrollbarsCustom-TrackY,
|
&.ScrollbarsCustom-TrackY,
|
||||||
&.ScrollbarsCustom-TrackX {
|
&.ScrollbarsCustom-TrackX {
|
||||||
background: rgba(0, 0, 0, 0);
|
background: rgba(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ScrollbarsCustom-Thumb {
|
.ScrollbarsCustom-Thumb {
|
||||||
|
|
||||||
&.ScrollbarsCustom-ThumbX,
|
&.ScrollbarsCustom-ThumbX,
|
||||||
&.ScrollbarsCustom-ThumbY {
|
&.ScrollbarsCustom-ThumbY {
|
||||||
background: rgba(0, 0, 0, 0);
|
background: rgba(0, 0, 0, 0);
|
||||||
@@ -28,6 +32,7 @@
|
|||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
.ScrollbarsCustom-Thumb {
|
.ScrollbarsCustom-Thumb {
|
||||||
|
|
||||||
&.ScrollbarsCustom-ThumbX,
|
&.ScrollbarsCustom-ThumbX,
|
||||||
&.ScrollbarsCustom-ThumbY {
|
&.ScrollbarsCustom-ThumbY {
|
||||||
background: rgba(0, 0, 0, 0.15);
|
background: rgba(0, 0, 0, 0.15);
|
||||||
@@ -68,4 +73,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user