mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 14:50:32 +00:00
feat: add purchases & sales tables.
This commit is contained in:
@@ -19,6 +19,8 @@ export const TABLES = {
|
|||||||
WAREHOUSE_TRANSFERS: 'warehouse_transfers',
|
WAREHOUSE_TRANSFERS: 'warehouse_transfers',
|
||||||
PROJECTS: 'projects',
|
PROJECTS: 'projects',
|
||||||
TIMESHEETS: 'timesheets',
|
TIMESHEETS: 'timesheets',
|
||||||
|
PURCHASES: 'purchases',
|
||||||
|
SALES: 'sales',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TABLE_SIZE = {
|
export const TABLE_SIZE = {
|
||||||
|
|||||||
@@ -40,7 +40,13 @@ function ProjectDetailActionsBar({
|
|||||||
|
|
||||||
// Handle new transaction button click.
|
// Handle new transaction button click.
|
||||||
const handleNewTransactionBtnClick = ({ path }) => {
|
const handleNewTransactionBtnClick = ({ path }) => {
|
||||||
history.push(`/${path}`);
|
switch (path) {
|
||||||
|
case 'expense':
|
||||||
|
openDialog('expense-form', { projectId });
|
||||||
|
break;
|
||||||
|
case 'estimatedExpense':
|
||||||
|
openDialog('estimated-expense-form', { projectId });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEditProjectBtnClick = () => {
|
const handleEditProjectBtnClick = () => {
|
||||||
@@ -50,7 +56,9 @@ function ProjectDetailActionsBar({
|
|||||||
};
|
};
|
||||||
// Handle table row size change.
|
// Handle table row size change.
|
||||||
const handleTableRowSizeChange = (size) => {
|
const handleTableRowSizeChange = (size) => {
|
||||||
addSetting('timesheets', 'tableSize', size);
|
addSetting('timesheets', 'tableSize', size) &&
|
||||||
|
addSetting('sales', 'tableSize', size) &&
|
||||||
|
addSetting('purchases', 'tableSize', size);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTimeEntryBtnClick = () => {
|
const handleTimeEntryBtnClick = () => {
|
||||||
@@ -67,8 +75,8 @@ function ProjectDetailActionsBar({
|
|||||||
<NavbarGroup>
|
<NavbarGroup>
|
||||||
<TransactionSelect
|
<TransactionSelect
|
||||||
transactions={[
|
transactions={[
|
||||||
{ name: 'Invoice', path: 'invoices/new' },
|
{ name: 'New Expense', path: 'expense' },
|
||||||
{ name: 'Expenses', path: 'expenses/new' },
|
{ name: 'New Estimated Expense', path: 'estimatedExpense' },
|
||||||
]}
|
]}
|
||||||
onItemSelect={handleNewTransactionBtnClick}
|
onItemSelect={handleNewTransactionBtnClick}
|
||||||
/>
|
/>
|
||||||
@@ -105,8 +113,6 @@ function ProjectDetailActionsBar({
|
|||||||
initialValue={timesheetsTableSize}
|
initialValue={timesheetsTableSize}
|
||||||
onChange={handleTableRowSizeChange}
|
onChange={handleTableRowSizeChange}
|
||||||
/>
|
/>
|
||||||
<NavbarDivider />
|
|
||||||
<Button icon={<Icon icon="more-vert" iconSize={16} />} minimal={true} />
|
|
||||||
</NavbarGroup>
|
</NavbarGroup>
|
||||||
<NavbarGroup align={Alignment.RIGHT}>
|
<NavbarGroup align={Alignment.RIGHT}>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ import React from 'react';
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import { Tabs, Tab } from '@blueprintjs/core';
|
import { Tabs, Tab } from '@blueprintjs/core';
|
||||||
|
import TimeSheets from './Timesheets';
|
||||||
import ProjectTimesheet from './ProjectTimesheet';
|
import Purchases from './Purchases';
|
||||||
|
import Sales from './Sales';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project detail tabs.
|
* Project detail tabs.
|
||||||
@@ -16,19 +17,24 @@ export default function ProjectDetailTabs() {
|
|||||||
animate={true}
|
animate={true}
|
||||||
large={true}
|
large={true}
|
||||||
renderActiveTabPanelOnly={true}
|
renderActiveTabPanelOnly={true}
|
||||||
defaultSelectedTabId={'timesheet'}
|
defaultSelectedTabId={'purchases'}
|
||||||
>
|
>
|
||||||
<Tab id="overview" title={intl.get('project_details.label.overview')} />
|
<Tab id="overview" title={intl.get('project_details.label.overview')} />
|
||||||
<Tab
|
<Tab
|
||||||
id="timesheet"
|
id="timesheet"
|
||||||
title={intl.get('project_details.label.timesheet')}
|
title={intl.get('project_details.label.timesheet')}
|
||||||
panel={<ProjectTimesheet />}
|
panel={<TimeSheets />}
|
||||||
/>
|
/>
|
||||||
<Tab
|
<Tab
|
||||||
id="purchases"
|
id="purchases"
|
||||||
title={intl.get('project_details.label.purchases')}
|
title={intl.get('project_details.label.purchases')}
|
||||||
|
panel={<Purchases />}
|
||||||
|
/>
|
||||||
|
<Tab
|
||||||
|
id="sales"
|
||||||
|
title={intl.get('project_details.label.sales')}
|
||||||
|
panel={<Sales />}
|
||||||
/>
|
/>
|
||||||
<Tab id="sales" title={intl.get('project_details.label.sales')} />
|
|
||||||
<Tab id="journals" title={intl.get('project_details.label.journals')} />
|
<Tab id="journals" title={intl.get('project_details.label.journals')} />
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</ProjectTabsContent>
|
</ProjectTabsContent>
|
||||||
@@ -42,6 +48,10 @@ const ProjectTabsContent = styled.div`
|
|||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-bottom: 1px solid #d2dce2;
|
border-bottom: 1px solid #d2dce2;
|
||||||
|
|
||||||
|
> *:not(:last-child) {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&.bp3-large > .bp3-tab {
|
&.bp3-large > .bp3-tab {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
@@ -59,9 +69,11 @@ const ProjectTabsContent = styled.div`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.bp3-tab-panel {
|
.bp3-tab-panel {
|
||||||
margin-top: 20px;
|
/* margin: 20px 32px; */
|
||||||
|
/* margin: 20px; */
|
||||||
|
/* margin-top: 20px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
padding: 0 25px;
|
padding: 0 25px; */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { DataTable } from 'components';
|
||||||
|
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
|
||||||
|
import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton';
|
||||||
|
import { TABLES } from 'common/tables';
|
||||||
|
import { useMemorizedColumnsWidths } from 'hooks';
|
||||||
|
import { usePurchasesColumns, ActionMenu } from './components';
|
||||||
|
import withSettings from '../../../../Settings/withSettings';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
const Purchases = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
date: '2022-06-08T22:00:00.000Z',
|
||||||
|
type: 'Invoice',
|
||||||
|
transaction_no: 'Inv-12345',
|
||||||
|
due_date: '2022-06-08T22:00:00.000Z',
|
||||||
|
balance: '$100.00',
|
||||||
|
status: 'Paid',
|
||||||
|
total: '$100.00',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
/**
|
||||||
|
* Purchases DataTable.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function PurchasesTable({
|
||||||
|
// #withSettings
|
||||||
|
purchasesTableSize,
|
||||||
|
}) {
|
||||||
|
// Retrieve purchases table columns.
|
||||||
|
const columns = usePurchasesColumns();
|
||||||
|
|
||||||
|
// Handle delete purchase.
|
||||||
|
const handleDeletePurchase = () => {};
|
||||||
|
|
||||||
|
// Local storage memorizing columns widths.
|
||||||
|
const [initialColumnsWidths, , handleColumnResizing] =
|
||||||
|
useMemorizedColumnsWidths(TABLES.PURCHASES);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DataTable
|
||||||
|
columns={columns}
|
||||||
|
data={Purchases}
|
||||||
|
// loading={}
|
||||||
|
// headerLoading={}
|
||||||
|
// progressBarLoading={}
|
||||||
|
manualSortBy={true}
|
||||||
|
selectionColumn={true}
|
||||||
|
noInitialFetch={true}
|
||||||
|
sticky={true}
|
||||||
|
ContextMenu={ActionMenu}
|
||||||
|
TableLoadingRenderer={TableSkeletonRows}
|
||||||
|
TableHeaderSkeletonRenderer={TableSkeletonHeader}
|
||||||
|
initialColumnsWidths={initialColumnsWidths}
|
||||||
|
onColumnResizing={handleColumnResizing}
|
||||||
|
size={purchasesTableSize}
|
||||||
|
payload={{
|
||||||
|
onDelete: handleDeletePurchase,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default compose(
|
||||||
|
withSettings(({ purchasesSettings }) => ({
|
||||||
|
purchasesTableSize: purchasesSettings?.tableSize,
|
||||||
|
})),
|
||||||
|
)(PurchasesTable);
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import clsx from 'classnames';
|
||||||
|
import { CLASSES } from 'common/classes';
|
||||||
|
import { FormatDateCell, Icon, FormattedMessage as T } from 'components';
|
||||||
|
import { Menu, MenuItem, Intent } from '@blueprintjs/core';
|
||||||
|
import { safeCallback } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table actions cell.
|
||||||
|
*/
|
||||||
|
export function ActionMenu({ payload: { onDelete }, row: { original } }) {
|
||||||
|
return (
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
text={intl.get('purchases.action.delete')}
|
||||||
|
intent={Intent.DANGER}
|
||||||
|
onClick={safeCallback(onDelete, original)}
|
||||||
|
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function usePurchasesColumns() {
|
||||||
|
return React.useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
id: 'date',
|
||||||
|
Header: intl.get('purchases.column.date'),
|
||||||
|
accessor: 'date',
|
||||||
|
Cell: FormatDateCell,
|
||||||
|
width: 120,
|
||||||
|
className: 'date',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'type',
|
||||||
|
Header: intl.get('purchases.column.type'),
|
||||||
|
accessor: 'type',
|
||||||
|
width: 120,
|
||||||
|
className: 'type',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'transaction_no',
|
||||||
|
Header: intl.get('purchases.column.transaction_no'),
|
||||||
|
accessor: 'transaction_no',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'due_date',
|
||||||
|
Header: intl.get('purchases.column.due_date'),
|
||||||
|
accessor: 'due_date',
|
||||||
|
Cell: FormatDateCell,
|
||||||
|
width: 120,
|
||||||
|
className: 'due_date',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'balance',
|
||||||
|
Header: intl.get('purchases.column.balance'),
|
||||||
|
accessor: 'balance',
|
||||||
|
width: 120,
|
||||||
|
clickable: true,
|
||||||
|
align: 'right',
|
||||||
|
className: clsx(CLASSES.FONT_BOLD),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'total',
|
||||||
|
Header: intl.get('purchases.column.total'),
|
||||||
|
accessor: 'total',
|
||||||
|
align: 'right',
|
||||||
|
width: 120,
|
||||||
|
className: clsx(CLASSES.FONT_BOLD),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'status',
|
||||||
|
Header: intl.get('purchases.column.status'),
|
||||||
|
accessor: 'status',
|
||||||
|
width: 120,
|
||||||
|
className: 'status',
|
||||||
|
clickable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import PurchasesTable from './PurchasesTable';
|
||||||
|
import { DashboardContentTable } from 'components';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export default function Purchases() {
|
||||||
|
return (
|
||||||
|
<DashboardContentTable>
|
||||||
|
<PurchasesTable />
|
||||||
|
</DashboardContentTable>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PurchasesContentTable = styled.div`
|
||||||
|
margin: 22px 20px;
|
||||||
|
border: 1px solid #d2dce2;
|
||||||
|
background: #fff;
|
||||||
|
/* .bigcapital-datatable {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1 0 0;
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.has-pagination) {
|
||||||
|
padding-bottom: 30px;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
`;
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
//@ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import { DataTable } from 'components';
|
||||||
|
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
|
||||||
|
import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton';
|
||||||
|
import { TABLES } from 'common/tables';
|
||||||
|
import { useMemorizedColumnsWidths } from 'hooks';
|
||||||
|
import { useSalesColumns, ActionMenu } from './components';
|
||||||
|
import withSettings from '../../../../Settings/withSettings';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
const Sales = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
date: '2022-06-08T22:00:00.000Z',
|
||||||
|
type: 'Invoice',
|
||||||
|
transaction_no: 'Inv-12345',
|
||||||
|
due_date: '2022-06-08T22:00:00.000Z',
|
||||||
|
balance: '$100.00',
|
||||||
|
status: 'Paid',
|
||||||
|
total: '$100.00',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sales DataTable.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function SalesTable({
|
||||||
|
// #withSettings
|
||||||
|
salesTableSize,
|
||||||
|
}) {
|
||||||
|
// Retrieve sales table columns.
|
||||||
|
const columns = useSalesColumns();
|
||||||
|
|
||||||
|
// Handle delete sale.
|
||||||
|
const handleDeleteSale = () => {};
|
||||||
|
|
||||||
|
// Local storage memorizing columns widths.
|
||||||
|
const [initialColumnsWidths, , handleColumnResizing] =
|
||||||
|
useMemorizedColumnsWidths(TABLES.SALES);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DataTable
|
||||||
|
columns={columns}
|
||||||
|
data={Sales}
|
||||||
|
// loading={}
|
||||||
|
// headerLoading={}
|
||||||
|
// progressBarLoading={}
|
||||||
|
manualSortBy={true}
|
||||||
|
selectionColumn={true}
|
||||||
|
noInitialFetch={true}
|
||||||
|
sticky={true}
|
||||||
|
ContextMenu={ActionMenu}
|
||||||
|
TableLoadingRenderer={TableSkeletonRows}
|
||||||
|
TableHeaderSkeletonRenderer={TableSkeletonHeader}
|
||||||
|
initialColumnsWidths={initialColumnsWidths}
|
||||||
|
onColumnResizing={handleColumnResizing}
|
||||||
|
size={salesTableSize}
|
||||||
|
payload={{
|
||||||
|
onDelete: handleDeleteSale,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default compose(
|
||||||
|
withSettings(({ salesSettings }) => ({
|
||||||
|
salesTableSize: salesSettings?.tableSize,
|
||||||
|
})),
|
||||||
|
)(SalesTable);
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import clsx from 'classnames';
|
||||||
|
import { CLASSES } from 'common/classes';
|
||||||
|
import { FormatDateCell, Icon, FormattedMessage as T } from 'components';
|
||||||
|
import { Menu, MenuItem, Intent } from '@blueprintjs/core';
|
||||||
|
import { safeCallback } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table actions cell.
|
||||||
|
*/
|
||||||
|
export function ActionMenu({ payload: { onDelete }, row: { original } }) {
|
||||||
|
return (
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
text={intl.get('sales.action.delete')}
|
||||||
|
intent={Intent.DANGER}
|
||||||
|
onClick={safeCallback(onDelete, original)}
|
||||||
|
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSalesColumns() {
|
||||||
|
return React.useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
id: 'date',
|
||||||
|
Header: intl.get('sales.column.date'),
|
||||||
|
accessor: 'date',
|
||||||
|
Cell: FormatDateCell,
|
||||||
|
width: 120,
|
||||||
|
className: 'date',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'type',
|
||||||
|
Header: intl.get('sales.column.type'),
|
||||||
|
accessor: 'type',
|
||||||
|
width: 120,
|
||||||
|
className: 'type',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'transaction_no',
|
||||||
|
Header: intl.get('sales.column.transaction_no'),
|
||||||
|
accessor: 'transaction_no',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'due_date',
|
||||||
|
Header: intl.get('sales.column.due_date'),
|
||||||
|
accessor: 'due_date',
|
||||||
|
Cell: FormatDateCell,
|
||||||
|
width: 120,
|
||||||
|
className: 'due_date',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'balance',
|
||||||
|
Header: intl.get('sales.column.balance'),
|
||||||
|
accessor: 'balance',
|
||||||
|
width: 120,
|
||||||
|
clickable: true,
|
||||||
|
align: 'right',
|
||||||
|
className: clsx(CLASSES.FONT_BOLD),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'total',
|
||||||
|
Header: intl.get('sales.column.total'),
|
||||||
|
accessor: 'total',
|
||||||
|
align: 'right',
|
||||||
|
width: 120,
|
||||||
|
className: clsx(CLASSES.FONT_BOLD),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'status',
|
||||||
|
Header: intl.get('sales.column.status'),
|
||||||
|
accessor: 'status',
|
||||||
|
width: 120,
|
||||||
|
className: 'status',
|
||||||
|
clickable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import SalesTable from './SalesTable';
|
||||||
|
import { DashboardContentTable } from 'components';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export default function Sales() {
|
||||||
|
return (
|
||||||
|
<SalesContentTable>
|
||||||
|
<SalesTable />
|
||||||
|
</SalesContentTable>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SalesContentTable = styled(DashboardContentTable)``;
|
||||||
@@ -87,7 +87,7 @@ const TimesheetDataTable = styled(DataTable)`
|
|||||||
|
|
||||||
.tbody {
|
.tbody {
|
||||||
.tr .td {
|
.tr .td {
|
||||||
padding: 0.5rem 0.8rem;
|
/* padding: 0.5rem 0.8rem; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar.td {
|
.avatar.td {
|
||||||
@@ -114,11 +114,10 @@ const TimesheetDataTable = styled(DataTable)`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.table-size--small {
|
.table-size--small {
|
||||||
.tbody .tr {
|
.tbody .tr {
|
||||||
height: 45px;
|
height: 45px;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@@ -4,12 +4,11 @@ import styled from 'styled-components';
|
|||||||
import { FormatDate, Icon, FormattedMessage as T } from 'components';
|
import { FormatDate, Icon, FormattedMessage as T } from 'components';
|
||||||
import { Menu, MenuItem, Intent } from '@blueprintjs/core';
|
import { Menu, MenuItem, Intent } from '@blueprintjs/core';
|
||||||
import { safeCallback, firstLettersArgs } from 'utils';
|
import { safeCallback, firstLettersArgs } from 'utils';
|
||||||
import { chain } from 'lodash';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table actions cell.
|
* Table actions cell.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function ActionsMenu({
|
export function ActionsMenu({
|
||||||
payload: { onDelete, onViewDetails },
|
payload: { onDelete, onViewDetails },
|
||||||
row: { original },
|
row: { original },
|
||||||
@@ -8,19 +8,19 @@ import TimesheetsHeader from './TimesheetsHeader';
|
|||||||
* Project Timesheet.
|
* Project Timesheet.
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export default function ProjectTimesheet() {
|
export default function TimeSheets() {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<TimesheetsHeader />
|
<TimesheetsHeader />
|
||||||
<ProjectTimesheetTableCard>
|
<TimesheetTableCard>
|
||||||
<TimesheetsTable />
|
<TimesheetsTable />
|
||||||
</ProjectTimesheetTableCard>
|
</TimesheetTableCard>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProjectTimesheetTableCard = styled.div`
|
const TimesheetTableCard = styled.div`
|
||||||
margin: 20px;
|
margin: 22px 32px;
|
||||||
border: 1px solid #c8cad0; // #000a1e33 #f0f0f0
|
border: 1px solid #c8cad0; // #000a1e33 #f0f0f0
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@@ -29,17 +29,17 @@ export const FinancialProgressBar = ({ ...rest }) => {
|
|||||||
|
|
||||||
const FinancialSectionWrap = styled.div`
|
const FinancialSectionWrap = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
/* flex-wrap: wrap; */
|
||||||
margin: 20px 20px 20px;
|
margin: 22px 32px;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const FinancialSectionCard = styled.div`
|
const FinancialSectionCard = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-shrink: 0;
|
flex-shrink: 1;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
width: 220px;
|
width: 230px;
|
||||||
height: 116px;
|
height: 116px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid #c8cad0; // #000a1e33 #f0f0f0
|
border: 1px solid #c8cad0; // #000a1e33 #f0f0f0
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ const ProjectFormDialogRoot = styled(Dialog)`
|
|||||||
.bp3-dialog-body {
|
.bp3-dialog-body {
|
||||||
.bp3-form-group {
|
.bp3-form-group {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
margin-top: 15px;
|
||||||
|
|
||||||
label.bp3-label {
|
label.bp3-label {
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
//@ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
@@ -9,9 +10,8 @@ import {
|
|||||||
Row,
|
Row,
|
||||||
FormattedMessage as T,
|
FormattedMessage as T,
|
||||||
} from 'components';
|
} from 'components';
|
||||||
import { modalChargeOptions } from '../../../../common/modalChargeOptions';
|
import { taskChargeOptions } from 'common/modalChargeOptions';
|
||||||
|
import { ChargeSelect } from '../../components';
|
||||||
import { TaskModalChargeSelect } from './components';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task form fields.
|
* Task form fields.
|
||||||
@@ -45,13 +45,16 @@ function TaskFormFields() {
|
|||||||
label={<T id={'task.dialog.charge'} />}
|
label={<T id={'task.dialog.charge'} />}
|
||||||
>
|
>
|
||||||
<ControlGroup>
|
<ControlGroup>
|
||||||
<TaskModalChargeSelect
|
<ChargeSelect
|
||||||
name="taskCharge"
|
name="taskCharge"
|
||||||
items={modalChargeOptions}
|
items={taskChargeOptions}
|
||||||
popoverProps={{ minimal: true }}
|
popoverProps={{ minimal: true }}
|
||||||
filterable={false}
|
filterable={false}
|
||||||
/>
|
/>
|
||||||
<FInputGroup name="taskamount" />
|
<FInputGroup
|
||||||
|
name="taskamount"
|
||||||
|
disabled={values?.taskCharge === 'Non-chargeable'}
|
||||||
|
/>
|
||||||
</ControlGroup>
|
</ControlGroup>
|
||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ export default (mapState) => {
|
|||||||
vendorsCreditNoteSetting: state.settings.data.vendorCredit,
|
vendorsCreditNoteSetting: state.settings.data.vendorCredit,
|
||||||
warehouseTransferSettings: state.settings.data.warehouseTransfers,
|
warehouseTransferSettings: state.settings.data.warehouseTransfers,
|
||||||
projectSettings:state.settings.data.projects,
|
projectSettings:state.settings.data.projects,
|
||||||
timesheetsSettings:state.settings.data.timesheets
|
timesheetsSettings:state.settings.data.timesheets,
|
||||||
|
purchasesSettings:state.settings.data.purchases,
|
||||||
|
salesSettings:state.settings.data.sales,
|
||||||
};
|
};
|
||||||
return mapState ? mapState(mapped, state, props) : mapped;
|
return mapState ? mapState(mapped, state, props) : mapped;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2062,6 +2062,9 @@
|
|||||||
"task.dialog.estimated_hours": "Estimate Hours",
|
"task.dialog.estimated_hours": "Estimate Hours",
|
||||||
"task.dialog.charge": "Charge",
|
"task.dialog.charge": "Charge",
|
||||||
"task.dialog.estimated_amount": "Estimated Amount",
|
"task.dialog.estimated_amount": "Estimated Amount",
|
||||||
|
"task.dialog.hourly_rate": "Hourly rate",
|
||||||
|
"task.dialog.fixed_price": "Fixed price",
|
||||||
|
"task.dialog.non_chargeable": "Non-chargeable",
|
||||||
"project.schema.label.contact": "Contact",
|
"project.schema.label.contact": "Contact",
|
||||||
"project.schema.label.project_name": "Project name",
|
"project.schema.label.project_name": "Project name",
|
||||||
"project.schema.label.deadline": "Deadline",
|
"project.schema.label.deadline": "Deadline",
|
||||||
@@ -2097,5 +2100,51 @@
|
|||||||
"time_entry.schema.label.duration": "Duration",
|
"time_entry.schema.label.duration": "Duration",
|
||||||
"time_entry.schema.label.date": "Date",
|
"time_entry.schema.label.date": "Date",
|
||||||
"find_or_choose_a_project": "Find or choose a project",
|
"find_or_choose_a_project": "Find or choose a project",
|
||||||
"choose_a_task": "Choose a task"
|
"choose_a_task": "Choose a task",
|
||||||
|
"expenses.dialog.label": "New Expense",
|
||||||
|
"expenses.dialog.expense_name": "Expense Name",
|
||||||
|
"expenses.dialog.expense_date": "Date",
|
||||||
|
"expenses.dialog.quantity": "Quantity",
|
||||||
|
"expenses.dialog.charge": "Charge",
|
||||||
|
"expenses.dialog.track_expense": "Track to Expense",
|
||||||
|
"expenses.dialog.unit_price": "Unit Price",
|
||||||
|
"expenses.dialog.expense_total": "Total",
|
||||||
|
"expenses.dialog.percentage": "Percentage",
|
||||||
|
"expenses.dialog.total":"Total:",
|
||||||
|
"expenses.dialog.markup": "% Markup",
|
||||||
|
"expenses.dialog.pass_cost_on": "Pass cost on",
|
||||||
|
"expenses.dialog.custom_pirce": "Custom Pirce",
|
||||||
|
"expenses.dialog.non_chargeable": "Non-chargeable",
|
||||||
|
"expense.schema.label.expense_name": "Expense name",
|
||||||
|
"expense.schema.label.estimated_expense": "Estimated expense",
|
||||||
|
"expense.schema.label.quantity": "Quantity",
|
||||||
|
"expense.schema.label.unit_price": "Unit price",
|
||||||
|
"choose_an_estimated_expense": "Choose an estimated expense",
|
||||||
|
"estimated_expenses.dialog.label": "New Estimated Expense",
|
||||||
|
"estimated_expenses.dialog.estimated_expense": "Estimated Expense Name",
|
||||||
|
"estimated_expenses.dialog.quantity": "Quantity",
|
||||||
|
"estimated_expenses.dialog.unit_price": "Unit Price",
|
||||||
|
"estimated_expenses.dialog.total": "Total",
|
||||||
|
"estimated_expenses.dialog.charge": "Charge",
|
||||||
|
"estimated_expenses.dialog.percentage": "Percentage",
|
||||||
|
"estimated_expenses.dialog.estimated_amount": "Estimated Amount:",
|
||||||
|
"estimated_expense.schema.label.estimated_expense": "Estimated expense name",
|
||||||
|
"estimated_expense.schema.label.quantity": "Quantity",
|
||||||
|
"estimated_expense.schema.label.unit_price": "Unit price",
|
||||||
|
"purchases.column.date": "Date",
|
||||||
|
"purchases.column.type": "Type",
|
||||||
|
"purchases.column.transaction_no": "Transaction No",
|
||||||
|
"purchases.column.due_date": "Due Date",
|
||||||
|
"purchases.column.balance": "Balance",
|
||||||
|
"purchases.column.total": "Total",
|
||||||
|
"purchases.column.status": "Status",
|
||||||
|
"purchases.action.delete": "Delete",
|
||||||
|
"sales.column.date": "Date",
|
||||||
|
"sales.column.type": "Type",
|
||||||
|
"sales.column.transaction_no": "Transaction No",
|
||||||
|
"sales.column.due_date": "Due Date",
|
||||||
|
"sales.column.balance": "Balance",
|
||||||
|
"sales.column.total": "Total",
|
||||||
|
"sales.column.status": "Status",
|
||||||
|
"sales.action.delete": "Delete"
|
||||||
}
|
}
|
||||||
@@ -67,6 +67,12 @@ const initialState = {
|
|||||||
timesheets: {
|
timesheets: {
|
||||||
tableSize: 'medium',
|
tableSize: 'medium',
|
||||||
},
|
},
|
||||||
|
purchases: {
|
||||||
|
tableSize: 'medium',
|
||||||
|
},
|
||||||
|
sales: {
|
||||||
|
tableSize: 'medium',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user