mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-22 07:40:32 +00:00
feat: add project ability.
This commit is contained in:
@@ -19,6 +19,7 @@ export const AbilitySubject = {
|
|||||||
SubscriptionBilling: 'SubscriptionBilling',
|
SubscriptionBilling: 'SubscriptionBilling',
|
||||||
CreditNote: 'CreditNote',
|
CreditNote: 'CreditNote',
|
||||||
VendorCredit: 'VendorCredit',
|
VendorCredit: 'VendorCredit',
|
||||||
|
Project:'Project'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ItemAction = {
|
export const ItemAction = {
|
||||||
@@ -73,7 +74,7 @@ export const CreditNoteAction = {
|
|||||||
Create: 'Create',
|
Create: 'Create',
|
||||||
Edit: 'Edit',
|
Edit: 'Edit',
|
||||||
Delete: 'Delete',
|
Delete: 'Delete',
|
||||||
Refund: 'Refund'
|
Refund: 'Refund',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const VendorCreditAction = {
|
export const VendorCreditAction = {
|
||||||
@@ -81,7 +82,7 @@ export const VendorCreditAction = {
|
|||||||
Create: 'Create',
|
Create: 'Create',
|
||||||
Edit: 'Edit',
|
Edit: 'Edit',
|
||||||
Delete: 'Delete',
|
Delete: 'Delete',
|
||||||
Refund: 'Refund'
|
Refund: 'Refund',
|
||||||
};
|
};
|
||||||
export const BillAction = {
|
export const BillAction = {
|
||||||
View: 'View',
|
View: 'View',
|
||||||
@@ -141,6 +142,13 @@ export const CashflowAction = {
|
|||||||
Delete: 'Delete',
|
Delete: 'Delete',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ProjectAction = {
|
||||||
|
View: 'View',
|
||||||
|
Create: 'Create',
|
||||||
|
Edit: 'Edit',
|
||||||
|
Delete: 'Delete',
|
||||||
|
};
|
||||||
|
|
||||||
export const ReportsAction = {
|
export const ReportsAction = {
|
||||||
ALL: 'all',
|
ALL: 'all',
|
||||||
READ_BALANCE_SHEET: 'read-balance-sheet',
|
READ_BALANCE_SHEET: 'read-balance-sheet',
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ export const Features = {
|
|||||||
Warehouses: 'warehouses',
|
Warehouses: 'warehouses',
|
||||||
Branches: 'branches',
|
Branches: 'branches',
|
||||||
ManualJournal: 'manualJournal',
|
ManualJournal: 'manualJournal',
|
||||||
|
Projects:'Projects'
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
ManualJournalAction,
|
ManualJournalAction,
|
||||||
ExpenseAction,
|
ExpenseAction,
|
||||||
CashflowAction,
|
CashflowAction,
|
||||||
|
ProjectAction,
|
||||||
PreferencesAbility,
|
PreferencesAbility,
|
||||||
SubscriptionBillingAbility,
|
SubscriptionBillingAbility,
|
||||||
} from '@/constants/abilityOption';
|
} from '@/constants/abilityOption';
|
||||||
@@ -554,6 +555,10 @@ export const SidebarMenu = [
|
|||||||
text: 'Projects',
|
text: 'Projects',
|
||||||
href: '/projects',
|
href: '/projects',
|
||||||
type: ISidebarMenuItemType.Link,
|
type: ISidebarMenuItemType.Link,
|
||||||
|
permission: {
|
||||||
|
subject: AbilitySubject.Project,
|
||||||
|
ability: ProjectAction.View,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -565,6 +570,10 @@ export const SidebarMenu = [
|
|||||||
text: <T id={'projects.label.new_project'} />,
|
text: <T id={'projects.label.new_project'} />,
|
||||||
type: ISidebarMenuItemType.Dialog,
|
type: ISidebarMenuItemType.Dialog,
|
||||||
dialogName: 'project-form',
|
dialogName: 'project-form',
|
||||||
|
permission: {
|
||||||
|
subject: AbilitySubject.Project,
|
||||||
|
ability: ProjectAction.Create,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: <T id={'projects.label.new_time_entry'} />,
|
text: <T id={'projects.label.new_time_entry'} />,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import {
|
import {
|
||||||
Icon,
|
Icon,
|
||||||
|
Can,
|
||||||
AdvancedFilterPopover,
|
AdvancedFilterPopover,
|
||||||
DashboardActionViewsList,
|
DashboardActionViewsList,
|
||||||
DashboardFilterButton,
|
DashboardFilterButton,
|
||||||
@@ -15,6 +16,7 @@ import {
|
|||||||
FormattedMessage as T,
|
FormattedMessage as T,
|
||||||
DashboardActionsBar,
|
DashboardActionsBar,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
|
import { ProjectAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
|
|
||||||
import withProjects from './withProjects';
|
import withProjects from './withProjects';
|
||||||
import withProjectsActions from './withProjectsActions';
|
import withProjectsActions from './withProjectsActions';
|
||||||
@@ -75,12 +77,14 @@ function ProjectsActionsBar({
|
|||||||
onChange={handleTabChange}
|
onChange={handleTabChange}
|
||||||
/>
|
/>
|
||||||
<NavbarDivider />
|
<NavbarDivider />
|
||||||
|
<Can I={ProjectAction.Create} a={AbilitySubject.Project}>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
icon={<Icon icon="plus" />}
|
icon={<Icon icon="plus" />}
|
||||||
text={<T id={'projects.label.new_project'} />}
|
text={<T id={'projects.label.new_project'} />}
|
||||||
onClick={handleNewProjectBtnClick}
|
onClick={handleNewProjectBtnClick}
|
||||||
/>
|
/>
|
||||||
|
</Can>
|
||||||
{/* AdvancedFilterPopover */}
|
{/* AdvancedFilterPopover */}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Button, Intent } from '@blueprintjs/core';
|
import { Button, Intent } from '@blueprintjs/core';
|
||||||
import { EmptyStatus, FormattedMessage as T } from '@/components';
|
import { EmptyStatus, Can, FormattedMessage as T } from '@/components';
|
||||||
|
import { ProjectAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
@@ -24,6 +25,7 @@ function ProjectsEmptyStatus({
|
|||||||
}
|
}
|
||||||
action={
|
action={
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
<Can I={ProjectAction.Create} a={AbilitySubject.Project}>
|
||||||
<Button
|
<Button
|
||||||
intent={Intent.PRIMARY}
|
intent={Intent.PRIMARY}
|
||||||
large={true}
|
large={true}
|
||||||
@@ -34,6 +36,7 @@ function ProjectsEmptyStatus({
|
|||||||
<Button intent={Intent.NONE} large={true}>
|
<Button intent={Intent.NONE} large={true}>
|
||||||
<T id={'learn_more'} />
|
<T id={'learn_more'} />
|
||||||
</Button>
|
</Button>
|
||||||
|
</Can>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ import {
|
|||||||
import {
|
import {
|
||||||
Icon,
|
Icon,
|
||||||
FormatDate,
|
FormatDate,
|
||||||
|
Can,
|
||||||
Choose,
|
Choose,
|
||||||
If,
|
If,
|
||||||
FormattedMessage as T,
|
FormattedMessage as T,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
|
import { ProjectAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
import { safeCallback, firstLettersArgs, calculateStatus } from '@/utils';
|
import { safeCallback, firstLettersArgs, calculateStatus } from '@/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,18 +83,22 @@ export const ActionsMenu = ({
|
|||||||
text={intl.get('view_details')}
|
text={intl.get('view_details')}
|
||||||
onClick={safeCallback(onViewDetails, original)}
|
onClick={safeCallback(onViewDetails, original)}
|
||||||
/>
|
/>
|
||||||
|
<Can I={ProjectAction.Edit} a={AbilitySubject.Project}>
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon={<Icon icon="pen-18" />}
|
icon={<Icon icon="pen-18" />}
|
||||||
text={intl.get('projects.action.edit_project')}
|
text={intl.get('projects.action.edit_project')}
|
||||||
onClick={safeCallback(onEdit, original)}
|
onClick={safeCallback(onEdit, original)}
|
||||||
/>
|
/>
|
||||||
|
</Can>
|
||||||
|
<Can I={ProjectAction.Create} a={AbilitySubject.Project}>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon={<Icon icon="plus" />}
|
icon={<Icon icon="plus" />}
|
||||||
text={intl.get('projects.action.new_task')}
|
text={intl.get('projects.action.new_task')}
|
||||||
onClick={safeCallback(onNewTask, original)}
|
onClick={safeCallback(onNewTask, original)}
|
||||||
/>
|
/>
|
||||||
|
</Can>
|
||||||
|
<Can I={ProjectAction.View} a={AbilitySubject.Project}>
|
||||||
<MenuItem text={'Status'} icon={<Icon icon="plus" />}>
|
<MenuItem text={'Status'} icon={<Icon icon="plus" />}>
|
||||||
<If condition={original.status !== 'InProgress'}>
|
<If condition={original.status !== 'InProgress'}>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@@ -101,10 +107,14 @@ export const ActionsMenu = ({
|
|||||||
/>
|
/>
|
||||||
</If>
|
</If>
|
||||||
<If condition={original.status !== 'Closed'}>
|
<If condition={original.status !== 'Closed'}>
|
||||||
<MenuItem text={'Closed'} onClick={safeCallback(onStatus, original)} />
|
<MenuItem
|
||||||
|
text={'Closed'}
|
||||||
|
onClick={safeCallback(onStatus, original)}
|
||||||
|
/>
|
||||||
</If>
|
</If>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
</Can>
|
||||||
|
<Can I={ProjectAction.Delete} a={AbilitySubject.Project}>
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
text={intl.get('projects.action.delete_project')}
|
text={intl.get('projects.action.delete_project')}
|
||||||
@@ -112,6 +122,7 @@ export const ActionsMenu = ({
|
|||||||
intent={Intent.DANGER}
|
intent={Intent.DANGER}
|
||||||
onClick={safeCallback(onDelete, original)}
|
onClick={safeCallback(onDelete, original)}
|
||||||
/>
|
/>
|
||||||
|
</Can>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user