mirror of
https://github.com/linuxserver/budge.git
synced 2026-01-20 20:23:52 +08:00
reworked table headers / titles to place the filter / search field into the buttons row
This commit is contained in:
parent
11b702d410
commit
f0e8f541ba
@ -49,6 +49,17 @@ import Menu from '@mui/material/Menu'
|
||||
import MenuItem from '@mui/material/MenuItem'
|
||||
import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'
|
||||
import CheckBoxIcon from '@mui/icons-material/CheckBox'
|
||||
import { styled } from '@mui/material/styles'
|
||||
|
||||
const StyledMTableToolbar = styled(MTableToolbar)(({ theme }) => ({
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
minHeight: '0 !important',
|
||||
padding: '0 !important',
|
||||
margin: '0',
|
||||
'& .MuiInputBase-input': {
|
||||
padding: '0 !important',
|
||||
},
|
||||
}))
|
||||
|
||||
function StatusIconButton(props) {
|
||||
const handleClick = e => {
|
||||
@ -741,7 +752,7 @@ export default function Account(props) {
|
||||
|
||||
const exportData = () => {
|
||||
const [cols, data] = getTableData()
|
||||
ExportCsv(cols, data, 'download')
|
||||
ExportCsv(cols, data, `${account.name} Transactions`)
|
||||
}
|
||||
|
||||
const onSelectionChange = data => {
|
||||
@ -757,7 +768,114 @@ export default function Account(props) {
|
||||
gridTemplateRows: 'auto 1fr auto',
|
||||
height: '100vh',
|
||||
}}
|
||||
title={<AccountTableHeader accountId={account.id} name={account.name} />}
|
||||
title={
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
sx={
|
||||
{
|
||||
// backgroundColor: theme.palette.action.hover,
|
||||
}
|
||||
}
|
||||
>
|
||||
<ButtonGroup variant="text" aria-label="outlined button group">
|
||||
<Button size="small">
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
<AddCircleIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
|
||||
Add Transaction
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Button>
|
||||
|
||||
<Button size="small" onClick={exportData}>
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
<SaveAltIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
|
||||
Export
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Button>
|
||||
|
||||
<PopupState variant="popover" popupId="demo-popup-menu">
|
||||
{popupState => (
|
||||
<>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={toggleReconciled}
|
||||
{...bindTrigger(popupState)}
|
||||
// disabled={!bulkEnabled}
|
||||
>
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
<EditIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
|
||||
Edit
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Button>
|
||||
<Menu {...bindMenu(popupState)}>
|
||||
<MenuItem
|
||||
// disabled={selectedRows.length === 0}
|
||||
onClick={markSelectedTransactionsCleared}
|
||||
>
|
||||
Mark Cleared
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem
|
||||
// disabled={selectedRows.length === 0}
|
||||
onClick={markSelectedTransactionsUncleared}
|
||||
>
|
||||
Mark Uncleared
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem
|
||||
// disabled={selectedRows.length === 0}
|
||||
onClick={deleteSelected}
|
||||
>
|
||||
Delete Transactions
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</>
|
||||
)}
|
||||
</PopupState>
|
||||
|
||||
<Button size="small" onClick={toggleReconciled}>
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
{showReconciled && (
|
||||
<CheckBoxIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{!showReconciled && (
|
||||
<CheckBoxOutlineBlankIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
|
||||
Reconciled
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</Stack>
|
||||
}
|
||||
options={{
|
||||
padding: 'dense',
|
||||
draggable: false,
|
||||
@ -803,113 +921,18 @@ export default function Account(props) {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
}}
|
||||
>
|
||||
<MTableToolbar {...{ ...props, actions: [] }} showTextRowsSelected={false} />
|
||||
<AccountTableHeader accountId={account.id} name={account.name} />
|
||||
|
||||
<Divider />
|
||||
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
<StyledMTableToolbar
|
||||
{...{ ...props, actions: [] }}
|
||||
showTextRowsSelected={false}
|
||||
localization={{
|
||||
searchPlaceholder: 'Filter transactions',
|
||||
}}
|
||||
>
|
||||
<ButtonGroup variant="text" aria-label="outlined button group">
|
||||
<Button size="small" onClick={props.actions[0].onClick}>
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
<AddCircleIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
|
||||
Add Transaction
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Button>
|
||||
|
||||
<Button size="small" onClick={exportData}>
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
<SaveAltIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
|
||||
Export
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Button>
|
||||
|
||||
<PopupState variant="popover" popupId="demo-popup-menu">
|
||||
{popupState => (
|
||||
<>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={toggleReconciled}
|
||||
{...bindTrigger(popupState)}
|
||||
// disabled={!bulkEnabled}
|
||||
>
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
<EditIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
|
||||
Edit
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Button>
|
||||
<Menu {...bindMenu(popupState)}>
|
||||
<MenuItem
|
||||
// disabled={selectedRows.length === 0}
|
||||
onClick={markSelectedTransactionsCleared}
|
||||
>
|
||||
Mark Cleared
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem
|
||||
// disabled={selectedRows.length === 0}
|
||||
onClick={markSelectedTransactionsUncleared}
|
||||
>
|
||||
Mark Uncleared
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem
|
||||
// disabled={selectedRows.length === 0}
|
||||
onClick={deleteSelected}
|
||||
>
|
||||
Delete Transactions
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</>
|
||||
)}
|
||||
</PopupState>
|
||||
|
||||
<Button size="small" onClick={toggleReconciled}>
|
||||
<Stack direction="row" alignItems="center" spacing={0.5}>
|
||||
{showReconciled && (
|
||||
<CheckBoxIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{!showReconciled && (
|
||||
<CheckBoxOutlineBlankIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
|
||||
Reconciled
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</Stack>
|
||||
searchFieldVariant="outlined"
|
||||
/>
|
||||
|
||||
<Divider />
|
||||
</Box>
|
||||
|
||||
@ -45,123 +45,125 @@ export default function BudgetTableHeader({ accountId, name }) {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Stack direction="row" justifyContent="center" alignItems="center" spacing={2}>
|
||||
<div>
|
||||
<h3 style={{ cursor: 'pointer', display: 'inline-block' }} {...bindTrigger(editAccountPopupState)}>
|
||||
{account.name}
|
||||
</h3>
|
||||
<Popover
|
||||
{...bindPopover(editAccountPopupState)}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'left',
|
||||
}}
|
||||
>
|
||||
<Box sx={{ p: 2 }}>
|
||||
<TextField
|
||||
autoFocus
|
||||
margin="dense"
|
||||
id="account-name"
|
||||
label="Account Name"
|
||||
type="text"
|
||||
fullWidth
|
||||
variant="standard"
|
||||
value={accountName}
|
||||
onChange={e => setAccountName(e.target.value)}
|
||||
/>
|
||||
<Stack direction="row" justifyContent="flex-end" alignItems="center" spacing={2}>
|
||||
<Button size="small" sx={{ p: 1 }} onClick={editAccountName}>
|
||||
Save
|
||||
</Button>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Popover>
|
||||
</div>
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2} sx={{ px: 2 }}>
|
||||
<Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={2}>
|
||||
<div>
|
||||
<h3 style={{ cursor: 'pointer', display: 'inline-block' }} {...bindTrigger(editAccountPopupState)}>
|
||||
{account.name}
|
||||
</h3>
|
||||
<Popover
|
||||
{...bindPopover(editAccountPopupState)}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'left',
|
||||
}}
|
||||
>
|
||||
<Box sx={{ p: 2 }}>
|
||||
<TextField
|
||||
autoFocus
|
||||
margin="dense"
|
||||
id="account-name"
|
||||
label="Account Name"
|
||||
type="text"
|
||||
fullWidth
|
||||
variant="standard"
|
||||
value={accountName}
|
||||
onChange={e => setAccountName(e.target.value)}
|
||||
/>
|
||||
<Stack direction="row" justifyContent="flex-end" alignItems="center" spacing={2}>
|
||||
<Button size="small" sx={{ p: 1 }} onClick={editAccountName}>
|
||||
Save
|
||||
</Button>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Popover>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Stack
|
||||
direction="column"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
// spacing={2}
|
||||
>
|
||||
<Typography
|
||||
style={{
|
||||
color: getBalanceColor(account.cleared, theme),
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{intlFormat(account.cleared)}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
Cleared
|
||||
</Typography>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<div>+</div>
|
||||
|
||||
<div>
|
||||
<Stack
|
||||
direction="column"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
// spacing={2}
|
||||
>
|
||||
<Typography
|
||||
style={{
|
||||
color: getBalanceColor(account.uncleared, theme),
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{intlFormat(account.uncleared)}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
Uncleared
|
||||
</Typography>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<div>=</div>
|
||||
|
||||
<div>
|
||||
<Stack
|
||||
direction="column"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
// spacing={2}
|
||||
>
|
||||
<Typography
|
||||
style={{
|
||||
color: getBalanceColor(account.balance, theme),
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{intlFormat(account.balance)}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
Working Balance
|
||||
</Typography>
|
||||
</Stack>
|
||||
</div>
|
||||
</Stack>
|
||||
|
||||
<div>
|
||||
<Stack
|
||||
direction="column"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
// spacing={2}
|
||||
>
|
||||
<Typography
|
||||
style={{
|
||||
color: getBalanceColor(account.cleared, theme),
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{intlFormat(account.cleared)}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
Cleared
|
||||
</Typography>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<div>+</div>
|
||||
|
||||
<div>
|
||||
<Stack
|
||||
direction="column"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
// spacing={2}
|
||||
>
|
||||
<Typography
|
||||
style={{
|
||||
color: getBalanceColor(account.uncleared, theme),
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{intlFormat(account.uncleared)}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
Uncleared
|
||||
</Typography>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<div>=</div>
|
||||
|
||||
<div>
|
||||
<Stack
|
||||
direction="column"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
// spacing={2}
|
||||
>
|
||||
<Typography
|
||||
style={{
|
||||
color: getBalanceColor(account.balance, theme),
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
{intlFormat(account.balance)}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="caption"
|
||||
sx={{
|
||||
fontWeight: 'bold',
|
||||
}}
|
||||
>
|
||||
Working Balance
|
||||
</Typography>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Button {...bindTrigger(reconcilePopupState)} variant="outlined" size="small">
|
||||
<Button {...bindTrigger(reconcilePopupState)} variant="outlined">
|
||||
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
|
||||
Reconcile
|
||||
</Typography>
|
||||
|
||||
@ -35,6 +35,17 @@ import Button from '@mui/material/Button'
|
||||
import ButtonGroup from '@mui/material/ButtonGroup'
|
||||
import Stack from '@mui/material/Stack'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import { styled } from '@mui/material/styles'
|
||||
|
||||
const StyledMTableToolbar = styled(MTableToolbar)(({ theme }) => ({
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
minHeight: '0 !important',
|
||||
padding: '0 !important',
|
||||
margin: '0',
|
||||
'& .MuiInputBase-input': {
|
||||
padding: '0 !important',
|
||||
},
|
||||
}))
|
||||
|
||||
export default function BudgetTable(props) {
|
||||
let isLoading = false
|
||||
@ -425,7 +436,48 @@ export default function BudgetTable(props) {
|
||||
gridTemplateRows: 'auto 1fr auto',
|
||||
height: '100vh',
|
||||
}}
|
||||
title={<BudgetTableHeader onMonthNavigate={setIsLoading} openCategoryGroupDialog={openCategoryGroupDialog} />}
|
||||
title={
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
sx={
|
||||
{
|
||||
// backgroundColor: theme.palette.action.hover,
|
||||
}
|
||||
}
|
||||
>
|
||||
<ButtonGroup variant="text" aria-label="outlined button group">
|
||||
<PopupState variant="popover" popupId="popover-category-group">
|
||||
{popupState => (
|
||||
<>
|
||||
<Button size="small" {...bindTrigger(popupState)}>
|
||||
<Stack
|
||||
direction="row"
|
||||
// justifyContent="space-between"
|
||||
alignItems="center"
|
||||
spacing={0.5}
|
||||
// sx={{
|
||||
// px: 2,
|
||||
// pb: 1,
|
||||
// }}
|
||||
>
|
||||
<AddCircleIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
|
||||
Category Group
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Button>
|
||||
<CategoryGroupForm popupState={popupState} mode={'create'} order={0} />
|
||||
</>
|
||||
)}
|
||||
</PopupState>
|
||||
</ButtonGroup>
|
||||
</Stack>
|
||||
}
|
||||
components={{
|
||||
Toolbar: props => (
|
||||
<Box
|
||||
@ -433,58 +485,22 @@ export default function BudgetTable(props) {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
}}
|
||||
>
|
||||
<MTableToolbar
|
||||
<BudgetTableHeader onMonthNavigate={setIsLoading} openCategoryGroupDialog={openCategoryGroupDialog} />
|
||||
|
||||
<Divider />
|
||||
|
||||
<StyledMTableToolbar
|
||||
{...props}
|
||||
localization={{
|
||||
searchPlaceholder: 'Filter categories',
|
||||
}}
|
||||
classes={{
|
||||
title: 'budget-table-title',
|
||||
styles={{
|
||||
searchField: {},
|
||||
}}
|
||||
searchFieldVariant="outlined"
|
||||
/>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Stack
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
sx={{
|
||||
backgroundColor: theme.palette.action.hover,
|
||||
}}
|
||||
>
|
||||
<ButtonGroup variant="text" aria-label="outlined button group">
|
||||
<PopupState variant="popover" popupId="popover-category-group">
|
||||
{popupState => (
|
||||
<>
|
||||
<Button size="small" {...bindTrigger(popupState)}>
|
||||
<Stack
|
||||
direction="row"
|
||||
// justifyContent="space-between"
|
||||
alignItems="center"
|
||||
spacing={0.5}
|
||||
// sx={{
|
||||
// px: 2,
|
||||
// pb: 1,
|
||||
// }}
|
||||
>
|
||||
<AddCircleIcon
|
||||
style={{
|
||||
fontSize: theme.typography.subtitle2.fontSize,
|
||||
}}
|
||||
/>
|
||||
<Typography style={{ fontSize: theme.typography.caption.fontSize, fontWeight: 'bold' }}>
|
||||
Category Group
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Button>
|
||||
<CategoryGroupForm popupState={popupState} mode={'create'} order={0} />
|
||||
</>
|
||||
)}
|
||||
</PopupState>
|
||||
</ButtonGroup>
|
||||
</Stack>
|
||||
|
||||
<Divider />
|
||||
</Box>
|
||||
),
|
||||
Row: props => (
|
||||
|
||||
@ -66,7 +66,7 @@ export default function BudgetTableHeader(props) {
|
||||
// backgroundColor: theme.palette.background.default
|
||||
}}
|
||||
>
|
||||
<Stack direction="row" justifyContent="space-around" alignItems="center" spacing={2} sx={{ p: 2 }}>
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2} sx={{ p: 2 }}>
|
||||
<div>
|
||||
<BudgetMonthPicker
|
||||
popupState={monthPickerPopupState}
|
||||
@ -143,7 +143,7 @@ export default function BudgetTableHeader(props) {
|
||||
</Typography>
|
||||
<Typography
|
||||
style={{
|
||||
fontSize: theme.typography.h6.fontSize,
|
||||
fontSize: theme.typography.h5.fontSize,
|
||||
fontWeight: 'bold',
|
||||
color: theme.palette.background.default,
|
||||
}}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user