mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-23 16:19:49 +00:00
feat: add timesheet & project details.
This commit is contained in:
@@ -0,0 +1,99 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Classes,
|
||||||
|
NavbarDivider,
|
||||||
|
NavbarGroup,
|
||||||
|
Alignment,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
||||||
|
import {
|
||||||
|
Icon,
|
||||||
|
FormattedMessage as T,
|
||||||
|
DashboardRowsHeightButton,
|
||||||
|
} from 'components';
|
||||||
|
import withSettings from '../../../Settings/withSettings';
|
||||||
|
import withSettingsActions from '../../../Settings/withSettingsActions';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project detail actions bar.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function ProjectDetailActionsBar({
|
||||||
|
// #withSettings
|
||||||
|
timeSheetsTableSize,
|
||||||
|
|
||||||
|
// #withSettingsActions
|
||||||
|
addSetting,
|
||||||
|
}) {
|
||||||
|
// Handle new transaction button click.
|
||||||
|
const handleNewTransactionBtnClick = () => {};
|
||||||
|
|
||||||
|
// Handle table row size change.
|
||||||
|
const handleTableRowSizeChange = (size) => {
|
||||||
|
addSetting('timeSheets', 'tableSize', size);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle the refresh button click.
|
||||||
|
const handleRefreshBtnClick = () => {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DashboardActionsBar>
|
||||||
|
<NavbarGroup>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
text={<T id={'projcet_details.action.new_transaction'} />}
|
||||||
|
onClick={handleNewTransactionBtnClick}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
text={<T id={'projcet_details.action.log_time'} />}
|
||||||
|
// onClick={}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
text={<T id={'projcet_details.action.edit_project'} />}
|
||||||
|
// onClick={}
|
||||||
|
/>
|
||||||
|
<NavbarDivider />
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'print-16'} iconSize={'16'} />}
|
||||||
|
text={<T id={'print'} />}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'file-import-16'} />}
|
||||||
|
text={<T id={'import'} />}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon={'file-export-16'} iconSize={'16'} />}
|
||||||
|
text={<T id={'export'} />}
|
||||||
|
/>
|
||||||
|
<NavbarDivider />
|
||||||
|
<DashboardRowsHeightButton
|
||||||
|
initialValue={timeSheetsTableSize}
|
||||||
|
onChange={handleTableRowSizeChange}
|
||||||
|
/>
|
||||||
|
<NavbarDivider />
|
||||||
|
<Button icon={<Icon icon="more-vert" iconSize={16} />} minimal={true} />
|
||||||
|
</NavbarGroup>
|
||||||
|
<NavbarGroup align={Alignment.RIGHT}>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
icon={<Icon icon="refresh-16" iconSize={14} />}
|
||||||
|
onClick={handleRefreshBtnClick}
|
||||||
|
/>
|
||||||
|
</NavbarGroup>
|
||||||
|
</DashboardActionsBar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default compose(
|
||||||
|
withSettingsActions,
|
||||||
|
withSettings(({ timeSheetsSettings }) => ({
|
||||||
|
timeSheetsTableSize: timeSheetsSettings?.tableSize,
|
||||||
|
})),
|
||||||
|
)(ProjectDetailActionsBar);
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const ProjectDetailContext = React.createContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project detail provider.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function ProjectDetailProvider({
|
||||||
|
// #ownProps
|
||||||
|
...props
|
||||||
|
}) {
|
||||||
|
// State provider.
|
||||||
|
const provider = {};
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<ProjectDetailContext.Provider value={provider} {...props} />
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const useProjectDetailContext = () => React.useContext(ProjectDetailContext);
|
||||||
|
|
||||||
|
export { ProjectDetailProvider, useProjectDetailContext };
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { Tabs, Tab } from '@blueprintjs/core';
|
||||||
|
import TimeSheetDataTable from './TimeSheet/TimeSheetDataTable';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project detail tabs.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export default function ProjectDetailTabs() {
|
||||||
|
return (
|
||||||
|
<ProjectTabsContent>
|
||||||
|
<Tabs
|
||||||
|
animate={true}
|
||||||
|
large={true}
|
||||||
|
renderActiveTabPanelOnly={true}
|
||||||
|
defaultSelectedTabId={'overview'}
|
||||||
|
>
|
||||||
|
<Tab id="overview" title={intl.get('project_details.label.overview')} />
|
||||||
|
<Tab
|
||||||
|
id="timesheet"
|
||||||
|
title={intl.get('project_details.label.timesheet')}
|
||||||
|
panel={<TimeSheetDataTable />}
|
||||||
|
/>
|
||||||
|
<Tab
|
||||||
|
id="purchases"
|
||||||
|
title={intl.get('project_details.label.purchases')}
|
||||||
|
/>
|
||||||
|
<Tab id="sales" title={intl.get('project_details.label.sales')} />
|
||||||
|
<Tab id="journals" title={intl.get('project_details.label.journals')} />
|
||||||
|
</Tabs>
|
||||||
|
</ProjectTabsContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProjectTabsContent = styled.div`
|
||||||
|
.bp3-tabs {
|
||||||
|
.bp3-tab-list {
|
||||||
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 0 20px;
|
||||||
|
border-bottom: 1px solid #d2dce2;
|
||||||
|
|
||||||
|
&.bp3-large > .bp3-tab {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #646a7d;
|
||||||
|
margin: 0 1rem;
|
||||||
|
|
||||||
|
&[aria-selected='true'],
|
||||||
|
&:not([aria-disabled='true']):hover {
|
||||||
|
color: #0052cc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bp3-tab-indicator-wrapper .bp3-tab-indicator {
|
||||||
|
height: 2px;
|
||||||
|
bottom: -2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bp3-tab-panel {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
// @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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { FormatDateCell } from 'components';
|
||||||
|
import { Menu, MenuDivider, MenuItem, Intent } from '@blueprintjs/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table actions cell.
|
||||||
|
*/
|
||||||
|
export const ActionMenu = ({ row: { original }, payload: {} }) => <Menu></Menu>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve timesheet list columns columns.
|
||||||
|
*/
|
||||||
|
export const useTimeSheetColumns = () => {
|
||||||
|
return React.useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
id: 'date',
|
||||||
|
Header: intl.get('timesheets.column.date'),
|
||||||
|
accessor: 'date',
|
||||||
|
Cell: FormatDateCell,
|
||||||
|
width: 115,
|
||||||
|
className: 'date',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'task',
|
||||||
|
Header: intl.get('timesheets.column.task'),
|
||||||
|
accessor: 'task',
|
||||||
|
width: 115,
|
||||||
|
className: 'task',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'user',
|
||||||
|
Header: intl.get('timesheets.column.user'),
|
||||||
|
accessor: 'user',
|
||||||
|
width: 115,
|
||||||
|
className: 'user',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'time',
|
||||||
|
Header: intl.get('timesheets.column.time'),
|
||||||
|
accessor: 'time',
|
||||||
|
width: 115,
|
||||||
|
className: 'user',
|
||||||
|
align: 'right',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'billingStatus',
|
||||||
|
Header: intl.get('timesheets.column.billing_status'),
|
||||||
|
accessor: 'billing_status',
|
||||||
|
width: 160,
|
||||||
|
className: 'billingStatus',
|
||||||
|
clickable: true,
|
||||||
|
textOverview: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
};
|
||||||
37
src/containers/Projects/containers/ProjectDetails/index.tsx
Normal file
37
src/containers/Projects/containers/ProjectDetails/index.tsx
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
//@ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
|
import ProjectDetailActionsBar from './ProjectDetailActionsBar';
|
||||||
|
import ProjectDetailTabs from './ProjectDetailTabs';
|
||||||
|
import { DashboardPageContent } from 'components';
|
||||||
|
import { ProjectDetailProvider } from './ProjectDetailProvider';
|
||||||
|
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project tabs.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function ProjectTabs({
|
||||||
|
// #withDashboardActions
|
||||||
|
changePageTitle,
|
||||||
|
}) {
|
||||||
|
const {
|
||||||
|
state: { original },
|
||||||
|
} = useLocation();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
changePageTitle(original.name);
|
||||||
|
}, [changePageTitle, original]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ProjectDetailProvider>
|
||||||
|
<ProjectDetailActionsBar />
|
||||||
|
<DashboardPageContent>
|
||||||
|
<ProjectDetailTabs />
|
||||||
|
</DashboardPageContent>
|
||||||
|
</ProjectDetailProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(withDashboardActions)(ProjectTabs);
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
import { DataTable } from 'components';
|
import { DataTable } from 'components';
|
||||||
import { TABLES } from 'common/tables';
|
import { TABLES } from 'common/tables';
|
||||||
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
|
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
|
||||||
@@ -44,11 +45,17 @@ function ProjectsDataTable({
|
|||||||
// #withSettings
|
// #withSettings
|
||||||
projectsTableSize,
|
projectsTableSize,
|
||||||
}) {
|
}) {
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
// Retrieve projects table columns.
|
// Retrieve projects table columns.
|
||||||
const columns = useProjectsListColumns();
|
const columns = useProjectsListColumns();
|
||||||
|
|
||||||
// Handle cell click.
|
// Handle cell click.
|
||||||
const handleCellClick = (cell, event) => {};
|
const handleCellClick = ({ row: { original } }) => {
|
||||||
|
return history.push(`/projects/${original?.id}/details`, {
|
||||||
|
original,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Handle edit project.
|
// Handle edit project.
|
||||||
const handleEditProject = (project) => {
|
const handleEditProject = (project) => {
|
||||||
@@ -66,6 +73,13 @@ function ProjectsDataTable({
|
|||||||
const [initialColumnsWidths, , handleColumnResizing] =
|
const [initialColumnsWidths, , handleColumnResizing] =
|
||||||
useMemorizedColumnsWidths(TABLES.PROJECTS);
|
useMemorizedColumnsWidths(TABLES.PROJECTS);
|
||||||
|
|
||||||
|
// Handle view detail project.
|
||||||
|
const handleViewDetailProject = (project) => {
|
||||||
|
return history.push(`/projects/${project.id}/details`, {
|
||||||
|
original: project.name,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DataTable
|
<DataTable
|
||||||
columns={columns}
|
columns={columns}
|
||||||
@@ -85,6 +99,7 @@ function ProjectsDataTable({
|
|||||||
onColumnResizing={handleColumnResizing}
|
onColumnResizing={handleColumnResizing}
|
||||||
size={projectsTableSize}
|
size={projectsTableSize}
|
||||||
payload={{
|
payload={{
|
||||||
|
onViewDetails: handleViewDetailProject,
|
||||||
onEdit: handleEditProject,
|
onEdit: handleEditProject,
|
||||||
onNewTask: handleNewTaskButtonClick,
|
onNewTask: handleNewTaskButtonClick,
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ export default (mapState) => {
|
|||||||
creditNoteSettings: state.settings.data.creditNote,
|
creditNoteSettings: state.settings.data.creditNote,
|
||||||
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
|
||||||
};
|
};
|
||||||
return mapState ? mapState(mapped, state, props) : mapped;
|
return mapState ? mapState(mapped, state, props) : mapped;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2069,5 +2069,18 @@
|
|||||||
"task.schema.label.task_name": "Task name",
|
"task.schema.label.task_name": "Task name",
|
||||||
"task.schema.label.task_house": "Task house",
|
"task.schema.label.task_house": "Task house",
|
||||||
"task.schema.label.charge": "Charge",
|
"task.schema.label.charge": "Charge",
|
||||||
"task.schema.label.amount": "Amount"
|
"task.schema.label.amount": "Amount",
|
||||||
|
"projcet_details.action.new_transaction": "New Transaction",
|
||||||
|
"projcet_details.action.log_time": "Log Time",
|
||||||
|
"projcet_details.action.edit_project": "Edit Project",
|
||||||
|
"project_details.label.overview": "Overview",
|
||||||
|
"project_details.label.timesheet": "Timesheet",
|
||||||
|
"project_details.label.purchases": "Purchases",
|
||||||
|
"project_details.label.sales": "Sales",
|
||||||
|
"project_details.label.journals": "Journals",
|
||||||
|
"timesheets.column.date": "Date",
|
||||||
|
"timesheets.column.task": "Task",
|
||||||
|
"timesheets.column.user": "User",
|
||||||
|
"timesheets.column.time": "Time",
|
||||||
|
"timesheets.column.billing_status": "Billing Status"
|
||||||
}
|
}
|
||||||
@@ -969,6 +969,15 @@ export const getDashboardRoutes = () => [
|
|||||||
),
|
),
|
||||||
pageTitle: intl.get('sidebar.transactions_locaking'),
|
pageTitle: intl.get('sidebar.transactions_locaking'),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: '/projects/:id/details',
|
||||||
|
component: lazy(() =>
|
||||||
|
import('../containers/Projects/containers/ProjectDetails'),
|
||||||
|
),
|
||||||
|
sidebarExpand: false,
|
||||||
|
backLink: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/projects',
|
path: '/projects',
|
||||||
component: lazy(() =>
|
component: lazy(() =>
|
||||||
@@ -976,6 +985,7 @@ export const getDashboardRoutes = () => [
|
|||||||
),
|
),
|
||||||
pageTitle: intl.get('sidebar.projects'),
|
pageTitle: intl.get('sidebar.projects'),
|
||||||
},
|
},
|
||||||
|
|
||||||
// Homepage
|
// Homepage
|
||||||
{
|
{
|
||||||
path: `/`,
|
path: `/`,
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ const initialState = {
|
|||||||
projects: {
|
projects: {
|
||||||
tableSize: 'medium',
|
tableSize: 'medium',
|
||||||
},
|
},
|
||||||
|
timeSheets: {
|
||||||
|
tableSize: 'medium',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user