mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
feat: project detail tabs.
This commit is contained in:
@@ -44,6 +44,7 @@ function ProjectDetailActionsBar({
|
|||||||
<NavbarGroup>
|
<NavbarGroup>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'plus'} />}
|
||||||
text={<T id={'projcet_details.action.new_transaction'} />}
|
text={<T id={'projcet_details.action.new_transaction'} />}
|
||||||
onClick={handleNewTransactionBtnClick}
|
onClick={handleNewTransactionBtnClick}
|
||||||
/>
|
/>
|
||||||
@@ -54,6 +55,7 @@ function ProjectDetailActionsBar({
|
|||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon="pen-18" />}
|
||||||
text={<T id={'projcet_details.action.edit_project'} />}
|
text={<T id={'projcet_details.action.edit_project'} />}
|
||||||
// onClick={}
|
// onClick={}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import DashboardInsider from '../../../../components/Dashboard/DashboardInsider';
|
||||||
|
|
||||||
const ProjectDetailContext = React.createContext();
|
const ProjectDetailContext = React.createContext();
|
||||||
|
|
||||||
@@ -14,9 +15,9 @@ function ProjectDetailProvider({
|
|||||||
// State provider.
|
// State provider.
|
||||||
const provider = {};
|
const provider = {};
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<DashboardInsider class="timesheets">
|
||||||
<ProjectDetailContext.Provider value={provider} {...props} />
|
<ProjectDetailContext.Provider value={provider} {...props} />
|
||||||
</React.Fragment>
|
</DashboardInsider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ 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 TimeSheetDataTable from './TimeSheet/TimeSheetDataTable';
|
import TimeSheetDataTable from './TimeSheetDataTable';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project detail tabs.
|
* Project detail tabs.
|
||||||
@@ -15,7 +15,7 @@ export default function ProjectDetailTabs() {
|
|||||||
animate={true}
|
animate={true}
|
||||||
large={true}
|
large={true}
|
||||||
renderActiveTabPanelOnly={true}
|
renderActiveTabPanelOnly={true}
|
||||||
defaultSelectedTabId={'overview'}
|
defaultSelectedTabId={'timesheet'}
|
||||||
>
|
>
|
||||||
<Tab id="overview" title={intl.get('project_details.label.overview')} />
|
<Tab id="overview" title={intl.get('project_details.label.overview')} />
|
||||||
<Tab
|
<Tab
|
||||||
@@ -37,16 +37,15 @@ export default function ProjectDetailTabs() {
|
|||||||
const ProjectTabsContent = styled.div`
|
const ProjectTabsContent = styled.div`
|
||||||
.bp3-tabs {
|
.bp3-tabs {
|
||||||
.bp3-tab-list {
|
.bp3-tab-list {
|
||||||
position: relative;
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
|
background-color: #fff;
|
||||||
border-bottom: 1px solid #d2dce2;
|
border-bottom: 1px solid #d2dce2;
|
||||||
|
|
||||||
&.bp3-large > .bp3-tab {
|
&.bp3-large > .bp3-tab {
|
||||||
font-size: 14px;
|
font-size: 15px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: #646a7d;
|
color: #7f8596;
|
||||||
margin: 0 1rem;
|
margin: 0 0.9rem;
|
||||||
|
|
||||||
&[aria-selected='true'],
|
&[aria-selected='true'],
|
||||||
&:not([aria-disabled='true']):hover {
|
&:not([aria-disabled='true']):hover {
|
||||||
@@ -59,7 +58,11 @@ const ProjectTabsContent = styled.div`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.bp3-tab-panel {
|
.bp3-tab-panel {
|
||||||
margin-top: 0;
|
border: 2px solid #f0f0f0;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 30px 18px;
|
||||||
|
margin: 30px 15px;
|
||||||
|
background: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import React from 'react';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
import { DataTable, TableFastCell, DashboardContentTable } from 'components';
|
|
||||||
import TableVirtualizedListRows from 'components/Datatable/TableVirtualizedRows';
|
|
||||||
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
|
|
||||||
import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton';
|
|
||||||
import { useTimeSheetColumns, ActionMenu } from './components';
|
|
||||||
import { TableStyle } from '../../../../../common';
|
|
||||||
import withSettings from '../../../../Settings/withSettings';
|
|
||||||
|
|
||||||
import { compose } from 'utils';
|
|
||||||
|
|
||||||
const TimeSheet = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
data: '2020-01-01',
|
|
||||||
task: 'Task 1',
|
|
||||||
user: 'User 1',
|
|
||||||
time: '12:00Am',
|
|
||||||
billingStatus: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
data: '2021-01-01',
|
|
||||||
task: 'Task 2',
|
|
||||||
user: 'User 2',
|
|
||||||
time: '12:00Am',
|
|
||||||
billingStatus: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
data: '2022-01-01',
|
|
||||||
task: 'Task 3',
|
|
||||||
user: 'User 3',
|
|
||||||
time: '12:00Am',
|
|
||||||
billingStatus: '',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TimeSheet DataTable.
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
function TimeSheetDataTable({
|
|
||||||
// #withSettings
|
|
||||||
timeSheetsTableSize,
|
|
||||||
}) {
|
|
||||||
// Retrieve timesheet table columns.
|
|
||||||
const columns = useTimeSheetColumns();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DashboardContentTable>
|
|
||||||
<TimeSheetsTable
|
|
||||||
columns={columns}
|
|
||||||
data={TimeSheet}
|
|
||||||
// loading={}
|
|
||||||
// headerLoading={}
|
|
||||||
noInitialFetch={true}
|
|
||||||
sticky={true}
|
|
||||||
expandColumnSpace={1}
|
|
||||||
expandToggleColumn={2}
|
|
||||||
selectionColumnWidth={45}
|
|
||||||
TableCellRenderer={TableFastCell}
|
|
||||||
TableLoadingRenderer={TableSkeletonRows}
|
|
||||||
TableRowsRenderer={TableVirtualizedListRows}
|
|
||||||
TableHeaderSkeletonRenderer={TableSkeletonHeader}
|
|
||||||
vListrowHeight={timeSheetsTableSize === 'small' ? 32 : 40}
|
|
||||||
vListOverscanRowCount={0}
|
|
||||||
styleName={TableStyle.Constrant}
|
|
||||||
// payload={{}}
|
|
||||||
/>
|
|
||||||
</DashboardContentTable>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default compose(
|
|
||||||
withSettings(({ timeSheetsSettings }) => ({
|
|
||||||
timeSheetsTableSize: timeSheetsSettings?.tableSize,
|
|
||||||
})),
|
|
||||||
)(TimeSheetDataTable);
|
|
||||||
|
|
||||||
const DashboardConstrantTable = styled(DataTable)`
|
|
||||||
.table {
|
|
||||||
.thead {
|
|
||||||
.th {
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tbody {
|
|
||||||
.tr:last-child .td {
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const TimeSheetsTable = styled(DashboardConstrantTable)`
|
|
||||||
.table .tbody {
|
|
||||||
.tbody-inner .tr.no-results {
|
|
||||||
.td {
|
|
||||||
padding: 2rem 0;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #888;
|
|
||||||
font-weight: 400;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tbody-inner {
|
|
||||||
.tr .td:not(:first-child) {
|
|
||||||
border-left: 1px solid #e6e6e6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@@ -1,17 +1,33 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import { FormatDateCell } from 'components';
|
import { FormatDateCell, Icon } from 'components';
|
||||||
import { Menu, MenuDivider, MenuItem, Intent } from '@blueprintjs/core';
|
import { Menu, MenuDivider, MenuItem, Intent } from '@blueprintjs/core';
|
||||||
|
import { safeCallback } from 'utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table actions cell.
|
* Table actions cell.
|
||||||
*/
|
*/
|
||||||
export const ActionMenu = ({ row: { original }, payload: {} }) => <Menu></Menu>;
|
|
||||||
|
export function ActionsMenu({
|
||||||
|
payload: { onDelete, onViewDetails },
|
||||||
|
row: { original },
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
text={'Delete'}
|
||||||
|
intent={Intent.DANGER}
|
||||||
|
onClick={safeCallback(onDelete, original)}
|
||||||
|
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve timesheet list columns columns.
|
* Retrieve timesheet list columns columns.
|
||||||
*/
|
*/
|
||||||
export const useTimeSheetColumns = () => {
|
export function useTimeSheetColumns() {
|
||||||
return React.useMemo(
|
return React.useMemo(
|
||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
@@ -19,7 +35,7 @@ export const useTimeSheetColumns = () => {
|
|||||||
Header: intl.get('timesheets.column.date'),
|
Header: intl.get('timesheets.column.date'),
|
||||||
accessor: 'date',
|
accessor: 'date',
|
||||||
Cell: FormatDateCell,
|
Cell: FormatDateCell,
|
||||||
width: 115,
|
width: 100,
|
||||||
className: 'date',
|
className: 'date',
|
||||||
clickable: true,
|
clickable: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
@@ -28,7 +44,7 @@ export const useTimeSheetColumns = () => {
|
|||||||
id: 'task',
|
id: 'task',
|
||||||
Header: intl.get('timesheets.column.task'),
|
Header: intl.get('timesheets.column.task'),
|
||||||
accessor: 'task',
|
accessor: 'task',
|
||||||
width: 115,
|
width: 100,
|
||||||
className: 'task',
|
className: 'task',
|
||||||
clickable: true,
|
clickable: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
@@ -37,7 +53,7 @@ export const useTimeSheetColumns = () => {
|
|||||||
id: 'user',
|
id: 'user',
|
||||||
Header: intl.get('timesheets.column.user'),
|
Header: intl.get('timesheets.column.user'),
|
||||||
accessor: 'user',
|
accessor: 'user',
|
||||||
width: 115,
|
width: 100,
|
||||||
className: 'user',
|
className: 'user',
|
||||||
clickable: true,
|
clickable: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
@@ -46,7 +62,7 @@ export const useTimeSheetColumns = () => {
|
|||||||
id: 'time',
|
id: 'time',
|
||||||
Header: intl.get('timesheets.column.time'),
|
Header: intl.get('timesheets.column.time'),
|
||||||
accessor: 'time',
|
accessor: 'time',
|
||||||
width: 115,
|
width: 100,
|
||||||
className: 'user',
|
className: 'user',
|
||||||
align: 'right',
|
align: 'right',
|
||||||
clickable: true,
|
clickable: true,
|
||||||
@@ -56,7 +72,7 @@ export const useTimeSheetColumns = () => {
|
|||||||
id: 'billingStatus',
|
id: 'billingStatus',
|
||||||
Header: intl.get('timesheets.column.billing_status'),
|
Header: intl.get('timesheets.column.billing_status'),
|
||||||
accessor: 'billing_status',
|
accessor: 'billing_status',
|
||||||
width: 160,
|
width: 140,
|
||||||
className: 'billingStatus',
|
className: 'billingStatus',
|
||||||
clickable: true,
|
clickable: true,
|
||||||
textOverview: true,
|
textOverview: true,
|
||||||
@@ -64,4 +80,4 @@ export const useTimeSheetColumns = () => {
|
|||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { DataTable, TableFastCell } from 'components';
|
||||||
|
import TableVirtualizedListRows from 'components/Datatable/TableVirtualizedRows';
|
||||||
|
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
|
||||||
|
import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton';
|
||||||
|
import { useTimeSheetColumns, ActionsMenu } from './components';
|
||||||
|
import { TableStyle } from '../../../../../common';
|
||||||
|
import withSettings from '../../../../Settings/withSettings';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
const TimeSheet = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
data: '2020-01-01',
|
||||||
|
task: 'Task 1',
|
||||||
|
user: 'User 1',
|
||||||
|
time: '12:00Am',
|
||||||
|
billingStatus: '',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TimeSheet DataTable.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function TimeSheetDataTable({
|
||||||
|
// #withSettings
|
||||||
|
timeSheetsTableSize,
|
||||||
|
}) {
|
||||||
|
// Retrieve timesheet table columns.
|
||||||
|
const columns = useTimeSheetColumns();
|
||||||
|
|
||||||
|
// Handle delete timesheet.
|
||||||
|
const handleDeleteTimeSheet = () => {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TimeSheetsTable
|
||||||
|
columns={columns}
|
||||||
|
data={TimeSheet}
|
||||||
|
// loading={}
|
||||||
|
// headerLoading={}
|
||||||
|
noInitialFetch={true}
|
||||||
|
sticky={true}
|
||||||
|
expandColumnSpace={1}
|
||||||
|
expandToggleColumn={2}
|
||||||
|
selectionColumnWidth={45}
|
||||||
|
ContextMenu={ActionsMenu}
|
||||||
|
TableCellRenderer={TableFastCell}
|
||||||
|
TableLoadingRenderer={TableSkeletonRows}
|
||||||
|
TableRowsRenderer={TableVirtualizedListRows}
|
||||||
|
TableHeaderSkeletonRenderer={TableSkeletonHeader}
|
||||||
|
vListrowHeight={timeSheetsTableSize === 'small' ? 32 : 40}
|
||||||
|
vListOverscanRowCount={0}
|
||||||
|
styleName={TableStyle.Constrant}
|
||||||
|
payload={{
|
||||||
|
onDelete: handleDeleteTimeSheet,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
withSettings(({ timeSheetsSettings }) => ({
|
||||||
|
timeSheetsTableSize: timeSheetsSettings?.tableSize,
|
||||||
|
})),
|
||||||
|
)(TimeSheetDataTable);
|
||||||
|
|
||||||
|
const TimeSheetsTable = styled(DataTable)`
|
||||||
|
.table .tbody {
|
||||||
|
.tbody-inner .tr.no-results {
|
||||||
|
.td {
|
||||||
|
padding: 2rem 0;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #888;
|
||||||
|
font-weight: 400;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tbody-inner {
|
||||||
|
.tr .td:not(:first-child) {
|
||||||
|
border-left: 1px solid #e6e6e6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
Reference in New Issue
Block a user