mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 05:10:31 +00:00
BIG-5: feat switching between compact and medium table row size.
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Button,
|
||||
PopoverInteractionKind,
|
||||
Popover,
|
||||
Menu,
|
||||
MenuItem,
|
||||
MenuDivider,
|
||||
Classes
|
||||
} from '@blueprintjs/core';
|
||||
import { Icon } from 'components';
|
||||
|
||||
export function DashboardRowsHeightButton() {
|
||||
return (
|
||||
<Popover
|
||||
minimal={true}
|
||||
content={
|
||||
<Menu>
|
||||
<MenuDivider title={'Rows height'} />
|
||||
<MenuItem text="Compact" />
|
||||
<MenuItem text="Medium" />
|
||||
</Menu>
|
||||
}
|
||||
placement="bottom-start"
|
||||
modifiers={{
|
||||
offset: { offset: '0, 4' },
|
||||
}}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="rows-height" iconSize={16} />}
|
||||
/>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
70
src/components/Dashboard/DashboardRowsHeightButton/index.js
Normal file
70
src/components/Dashboard/DashboardRowsHeightButton/index.js
Normal file
@@ -0,0 +1,70 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Button,
|
||||
PopoverInteractionKind,
|
||||
Popover,
|
||||
Menu,
|
||||
MenuItem,
|
||||
MenuDivider,
|
||||
Classes,
|
||||
Tooltip,
|
||||
Position,
|
||||
} from '@blueprintjs/core';
|
||||
import clsx from 'classnames';
|
||||
import { Icon, T } from 'components';
|
||||
|
||||
import Style from './style.module.scss';
|
||||
|
||||
/**
|
||||
* Dashboard rows height button control.
|
||||
*/
|
||||
export function DashboardRowsHeightButton({ initialValue, value, onChange }) {
|
||||
const [localSize, setLocalSize] = React.useState(initialValue);
|
||||
|
||||
// Handle menu item click.
|
||||
const handleItemClick = (size) => (event) => {
|
||||
setLocalSize(size);
|
||||
onChange && onChange(size, event);
|
||||
};
|
||||
// Button icon name.
|
||||
const btnIcon = `table-row-${localSize}`;
|
||||
|
||||
return (
|
||||
<Popover
|
||||
minimal={true}
|
||||
content={
|
||||
<Menu className={Style.menu}>
|
||||
<MenuDivider title={<T id={'dashboard.rows_height'} />} />
|
||||
<MenuItem
|
||||
onClick={handleItemClick('small')}
|
||||
text={<T id={'dashboard.row_small'} />}
|
||||
/>
|
||||
<MenuItem
|
||||
onClick={handleItemClick('medium')}
|
||||
text={<T id={'dashboard.row_medium'} />}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
placement="bottom-start"
|
||||
modifiers={{
|
||||
offset: { offset: '0, 4' },
|
||||
}}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
>
|
||||
<Tooltip
|
||||
content={<T id={'dashboard.rows_height'} />}
|
||||
minimal={true}
|
||||
position={Position.BOTTOM}
|
||||
>
|
||||
<Button
|
||||
className={clsx(Classes.MINIMAL, Style.button)}
|
||||
icon={<Icon icon={btnIcon} iconSize={16} />}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
DashboardRowsHeightButton.defaultProps = {
|
||||
initialValue: 'medium',
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
.menu{
|
||||
:global .bp3-heading{
|
||||
font-weight: 400;
|
||||
opacity: 0.5;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.button{
|
||||
min-width: 34px;
|
||||
}
|
||||
@@ -196,6 +196,7 @@ export default function DataTable(props) {
|
||||
|
||||
DataTable.defaultProps = {
|
||||
pagination: false,
|
||||
size: 'medium',
|
||||
spinnerProps: { size: 30 },
|
||||
|
||||
expandToggleColumn: 1,
|
||||
|
||||
@@ -9,7 +9,15 @@ import TableContext from './TableContext';
|
||||
export default function TableWrapper({ children }) {
|
||||
const {
|
||||
table: { getTableProps },
|
||||
props: { sticky, pagination, loading, expandable, virtualizedRows, className },
|
||||
props: {
|
||||
sticky,
|
||||
pagination,
|
||||
loading,
|
||||
expandable,
|
||||
virtualizedRows,
|
||||
className,
|
||||
size,
|
||||
},
|
||||
} = useContext(TableContext);
|
||||
|
||||
return (
|
||||
@@ -20,6 +28,7 @@ export default function TableWrapper({ children }) {
|
||||
'is-expandable': expandable,
|
||||
'is-loading': loading,
|
||||
'has-virtualized-rows': virtualizedRows,
|
||||
[`table-size--${size}`]: size,
|
||||
})}
|
||||
>
|
||||
<ScrollSync>
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
If,
|
||||
DashboardActionViewsList,
|
||||
DashboardFilterButton,
|
||||
DashboardRowsHeightButton
|
||||
} from 'components';
|
||||
|
||||
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
||||
@@ -165,6 +166,9 @@ function AccountsActionsBar({
|
||||
icon={<Icon icon="file-import-16" iconSize={16} />}
|
||||
text={<T id={'import'} />}
|
||||
/>
|
||||
<NavbarDivider />
|
||||
<DashboardRowsHeightButton />
|
||||
<NavbarDivider />
|
||||
<Switch
|
||||
labelElement={<T id={'inactive'} />}
|
||||
defaultChecked={accountsInactiveMode}
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
Switch,
|
||||
Alignment,
|
||||
} from '@blueprintjs/core';
|
||||
import { FormattedMessage as T } from 'components';
|
||||
import { DashboardRowsHeightButton, FormattedMessage as T } from 'components';
|
||||
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
||||
import Icon from 'components/Icon';
|
||||
import {
|
||||
@@ -25,8 +25,10 @@ import { useRefreshItems } from 'hooks/query/items';
|
||||
import withItems from 'containers/Items/withItems';
|
||||
import withItemsActions from './withItemsActions';
|
||||
import withAlertActions from 'containers/Alert/withAlertActions';
|
||||
import withSettings from '../Settings/withSettings';
|
||||
|
||||
import { compose } from 'utils';
|
||||
import withSettingsActions from '../Settings/withSettingsActions';
|
||||
|
||||
/**
|
||||
* Items actions bar.
|
||||
@@ -42,6 +44,12 @@ function ItemsActionsBar({
|
||||
|
||||
// #withAlertActions
|
||||
openAlert,
|
||||
|
||||
// #withSettings
|
||||
itemsTableSize,
|
||||
|
||||
// #withSettingsActions
|
||||
addSetting,
|
||||
}) {
|
||||
// Items list context.
|
||||
const { itemsViews, fields } = useItemsListContext();
|
||||
@@ -72,10 +80,14 @@ function ItemsActionsBar({
|
||||
const checked = event.target.checked;
|
||||
setItemsTableState({ inactiveMode: checked });
|
||||
};
|
||||
|
||||
// Handle refresh button click.
|
||||
const handleRefreshBtnClick = () => {
|
||||
refresh();
|
||||
};
|
||||
// Handle table row size change.
|
||||
const handleTableRowSizeChange = (size) => {
|
||||
addSetting('items', 'tableSize', size);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
@@ -131,6 +143,12 @@ function ItemsActionsBar({
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<NavbarDivider />
|
||||
<DashboardRowsHeightButton
|
||||
initialValue={itemsTableSize}
|
||||
onChange={handleTableRowSizeChange}
|
||||
/>
|
||||
<NavbarDivider />
|
||||
<Switch
|
||||
labelElement={<T id={'inactive'} />}
|
||||
defaultChecked={itemsInactiveMode}
|
||||
@@ -150,11 +168,15 @@ function ItemsActionsBar({
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withSettingsActions,
|
||||
withItems(({ itemsSelectedRows, itemsTableState }) => ({
|
||||
itemsSelectedRows,
|
||||
itemsInactiveMode: itemsTableState.inactiveMode,
|
||||
itemsFilterRoles: itemsTableState.filterRoles,
|
||||
})),
|
||||
withSettings(({ itemsSettings }) => ({
|
||||
itemsTableSize: itemsSettings.tableSize,
|
||||
})),
|
||||
withItemsActions,
|
||||
withAlertActions,
|
||||
)(ItemsActionsBar);
|
||||
|
||||
@@ -10,11 +10,11 @@ import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton';
|
||||
|
||||
import { TABLES } from 'common/tables';
|
||||
|
||||
import withItems from 'containers/Items/withItems';
|
||||
import withItemsActions from 'containers/Items/withItemsActions';
|
||||
import withAlertsActions from 'containers/Alert/withAlertActions';
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import withDrawerActions from 'containers/Drawer/withDrawerActions';
|
||||
import withSettings from '../Settings/withSettings';
|
||||
|
||||
import { useItemsListContext } from './ItemsListProvider';
|
||||
import { useItemsTableColumns, ItemsActionMenuList } from './components';
|
||||
@@ -37,8 +37,8 @@ function ItemsDataTable({
|
||||
// #withDrawerActions
|
||||
openDrawer,
|
||||
|
||||
// #withItems
|
||||
itemsTableState,
|
||||
// #withSettings
|
||||
itemsTableSize,
|
||||
|
||||
// #ownProps
|
||||
tableProps,
|
||||
@@ -146,6 +146,7 @@ function ItemsDataTable({
|
||||
onCellClick={handleCellClick}
|
||||
initialColumnsWidths={initialColumnsWidths}
|
||||
onColumnResizing={handleColumnResizing}
|
||||
size={itemsTableSize}
|
||||
payload={{
|
||||
onDeleteItem: handleDeleteItem,
|
||||
onEditItem: handleEditItem,
|
||||
@@ -167,5 +168,7 @@ export default compose(
|
||||
withAlertsActions,
|
||||
withDrawerActions,
|
||||
withDialogActions,
|
||||
withItems(({ itemsTableState }) => ({ itemsTableState })),
|
||||
withSettings(({ itemsSettings }) => ({
|
||||
itemsTableSize: itemsSettings.tableSize,
|
||||
})),
|
||||
)(ItemsDataTable);
|
||||
|
||||
@@ -2,11 +2,13 @@ import { connect } from 'react-redux';
|
||||
import {
|
||||
FetchOptions,
|
||||
submitOptions,
|
||||
addSettings
|
||||
} from 'store/settings/settings.actions';
|
||||
|
||||
export const mapDispatchToProps = (dispatch) => ({
|
||||
requestSubmitOptions: (form) => dispatch(submitOptions({ form })),
|
||||
requestFetchOptions: () => dispatch(FetchOptions({})),
|
||||
addSetting: (group, key, value) => dispatch(addSettings(group, key, value)),
|
||||
});
|
||||
|
||||
export default connect(null, mapDispatchToProps);
|
||||
|
||||
@@ -446,25 +446,36 @@ export default {
|
||||
},
|
||||
'universal-search': {
|
||||
path: [
|
||||
'M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z'
|
||||
'M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z',
|
||||
],
|
||||
viewBox: '0 0 20 20',
|
||||
},
|
||||
"arrow-down-24": {
|
||||
path: [
|
||||
'M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z',
|
||||
],
|
||||
'arrow-down-24': {
|
||||
path: ['M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z'],
|
||||
viewBox: '0 0 24 24',
|
||||
},
|
||||
"arrow-up-24": {
|
||||
path: [
|
||||
'M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z'
|
||||
],
|
||||
'arrow-up-24': {
|
||||
path: ['M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z'],
|
||||
viewBox: '0 0 24 24',
|
||||
},
|
||||
"caret-right-16": {
|
||||
'caret-right-16': {
|
||||
path: [
|
||||
'M11 8c0-.15-.07-.28-.17-.37l-4-3.5A.495.495 0 006 4.5v7a.495.495 0 00.83.37l4-3.5c.1-.09.17-.22.17-.37z'
|
||||
'M11 8c0-.15-.07-.28-.17-.37l-4-3.5A.495.495 0 006 4.5v7a.495.495 0 00.83.37l4-3.5c.1-.09.17-.22.17-.37z',
|
||||
],
|
||||
viewBox: '0 0 16 16',
|
||||
},
|
||||
'table-row-small': {
|
||||
path: [
|
||||
'M15,2.5v2a.5.5,0,0,1-.5.5h-13a.5.5,0,0,1-.5-.5v-2A.51.51,0,0,1,1.49,2h13A.5.5,0,0,1,15,2.5Z',
|
||||
'M1,7.51A.51.51,0,0,1,1.49,7h13a.51.51,0,0,1,0,1h-13A.51.51,0,0,1,1,7.51Z',
|
||||
'M1,10.5a.5.5,0,0,1,.5-.5h13a.5.5,0,0,1,0,1h-13A.5.5,0,0,1,1,10.5Z',
|
||||
'M15,13.5a.5.5,0,0,1-.5.51h-13a.51.51,0,0,1,0-1h13A.5.5,0,0,1,15,13.5Z',
|
||||
],
|
||||
viewBox: '0 0 16 16',
|
||||
},
|
||||
'table-row-medium': {
|
||||
path: [
|
||||
'M15,3V7a1,1,0,0,1-1,1H2A1,1,0,0,1,1,7V3A1,1,0,0,1,2,2H14A1,1,0,0,1,15,3ZM1.48,11h13a.5.5,0,0,0,0-1h-13a.5.5,0,0,0,0,1Zm13,2h-13a.51.51,0,0,0,0,1h13a.51.51,0,0,0,0-1Z',
|
||||
],
|
||||
viewBox: '0 0 16 16',
|
||||
},
|
||||
|
||||
@@ -36,4 +36,11 @@ export const setSettings = (settings) => {
|
||||
type: t.SETTING_SET,
|
||||
options: settings,
|
||||
};
|
||||
}
|
||||
|
||||
export const addSettings = (group, key, value) => {
|
||||
return {
|
||||
type: t.SETTING_ADD,
|
||||
payload: { group, key, value }
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
import { camelCase } from 'lodash';
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
|
||||
import t from 'store/types';
|
||||
|
||||
const initialState = {
|
||||
@@ -11,10 +14,21 @@ const initialState = {
|
||||
bills: {},
|
||||
billPayments: {},
|
||||
salesEstimates: {},
|
||||
items: {
|
||||
tableSize: 'medium',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
const STORAGE_KEY = 'bigcapital:settings';
|
||||
|
||||
const PRESIST_CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: ['data'],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
[t.SETTING_SET]: (state, action) => {
|
||||
const { options } = action;
|
||||
const _data = {
|
||||
@@ -32,4 +46,19 @@ export default createReducer(initialState, {
|
||||
});
|
||||
state.data = _data;
|
||||
},
|
||||
|
||||
[t.SETTING_ADD]: (state, action) => {
|
||||
const { group, key, value } = action.payload;
|
||||
|
||||
const newData = {
|
||||
...state.data,
|
||||
[group]: {
|
||||
...state.data[group],
|
||||
[key]: value,
|
||||
},
|
||||
};
|
||||
state.data = newData;
|
||||
},
|
||||
});
|
||||
|
||||
export default persistReducer(PRESIST_CONFIG, reducerInstance);
|
||||
|
||||
@@ -2,4 +2,5 @@ export default {
|
||||
SETTING_LIST_SET: 'SETTING_LIST_SET',
|
||||
CLEAR_OPTIONS_FORM_ERRORS: 'CLEAR_OPTIONS_FORM_ERRORS',
|
||||
SETTING_SET: 'SETTING_SET',
|
||||
SETTING_ADD: 'SETTING_ADD',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user