diff --git a/src/components/Dashboard/DashboardRowsHeightButton.js b/src/components/Dashboard/DashboardRowsHeightButton.js
deleted file mode 100644
index 85c72f749..000000000
--- a/src/components/Dashboard/DashboardRowsHeightButton.js
+++ /dev/null
@@ -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 (
-
-
-
-
-
- }
- placement="bottom-start"
- modifiers={{
- offset: { offset: '0, 4' },
- }}
- interactionKind={PopoverInteractionKind.CLICK}
- >
- }
- />
-
- );
-}
diff --git a/src/components/Dashboard/DashboardRowsHeightButton/index.js b/src/components/Dashboard/DashboardRowsHeightButton/index.js
new file mode 100644
index 000000000..396ad727a
--- /dev/null
+++ b/src/components/Dashboard/DashboardRowsHeightButton/index.js
@@ -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 (
+
+ } />
+ }
+ />
+ }
+ />
+
+ }
+ placement="bottom-start"
+ modifiers={{
+ offset: { offset: '0, 4' },
+ }}
+ interactionKind={PopoverInteractionKind.CLICK}
+ >
+ }
+ minimal={true}
+ position={Position.BOTTOM}
+ >
+ }
+ />
+
+
+ );
+}
+
+DashboardRowsHeightButton.defaultProps = {
+ initialValue: 'medium',
+};
diff --git a/src/components/Dashboard/DashboardRowsHeightButton/style.module.scss b/src/components/Dashboard/DashboardRowsHeightButton/style.module.scss
new file mode 100644
index 000000000..15f602aab
--- /dev/null
+++ b/src/components/Dashboard/DashboardRowsHeightButton/style.module.scss
@@ -0,0 +1,12 @@
+
+.menu{
+ :global .bp3-heading{
+ font-weight: 400;
+ opacity: 0.5;
+ font-size: 12px;
+ }
+}
+
+.button{
+ min-width: 34px;
+}
\ No newline at end of file
diff --git a/src/components/DataTable.js b/src/components/DataTable.js
index 6512a9839..6a1b76952 100644
--- a/src/components/DataTable.js
+++ b/src/components/DataTable.js
@@ -196,6 +196,7 @@ export default function DataTable(props) {
DataTable.defaultProps = {
pagination: false,
+ size: 'medium',
spinnerProps: { size: 30 },
expandToggleColumn: 1,
diff --git a/src/components/Datatable/TableWrapper.js b/src/components/Datatable/TableWrapper.js
index c12acd167..6b1b74726 100644
--- a/src/components/Datatable/TableWrapper.js
+++ b/src/components/Datatable/TableWrapper.js
@@ -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,
})}
>
diff --git a/src/containers/Accounts/AccountsActionsBar.js b/src/containers/Accounts/AccountsActionsBar.js
index 5798c2a62..3e85b13d5 100644
--- a/src/containers/Accounts/AccountsActionsBar.js
+++ b/src/containers/Accounts/AccountsActionsBar.js
@@ -17,6 +17,7 @@ import {
If,
DashboardActionViewsList,
DashboardFilterButton,
+ DashboardRowsHeightButton
} from 'components';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
@@ -165,6 +166,9 @@ function AccountsActionsBar({
icon={}
text={}
/>
+
+
+
}
defaultChecked={accountsInactiveMode}
diff --git a/src/containers/Items/ItemsActionsBar.js b/src/containers/Items/ItemsActionsBar.js
index 12e502aa4..67e30c732 100644
--- a/src/containers/Items/ItemsActionsBar.js
+++ b/src/containers/Items/ItemsActionsBar.js
@@ -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 (
@@ -131,6 +143,12 @@ function ItemsActionsBar({
icon={}
text={}
/>
+
+
+
}
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);
diff --git a/src/containers/Items/ItemsDataTable.js b/src/containers/Items/ItemsDataTable.js
index bbaf51d11..1874d75b8 100644
--- a/src/containers/Items/ItemsDataTable.js
+++ b/src/containers/Items/ItemsDataTable.js
@@ -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);
diff --git a/src/containers/Settings/withSettingsActions.js b/src/containers/Settings/withSettingsActions.js
index 1c02035f3..3cfe2bb5b 100644
--- a/src/containers/Settings/withSettingsActions.js
+++ b/src/containers/Settings/withSettingsActions.js
@@ -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);
diff --git a/src/static/json/icons.js b/src/static/json/icons.js
index d4fce096f..db7c65052 100644
--- a/src/static/json/icons.js
+++ b/src/static/json/icons.js
@@ -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',
},
diff --git a/src/store/settings/settings.actions.js b/src/store/settings/settings.actions.js
index 3eea4aefa..11c20c4eb 100644
--- a/src/store/settings/settings.actions.js
+++ b/src/store/settings/settings.actions.js
@@ -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 }
+ };
}
\ No newline at end of file
diff --git a/src/store/settings/settings.reducer.js b/src/store/settings/settings.reducer.js
index 3b25af410..29c9c117a 100644
--- a/src/store/settings/settings.reducer.js
+++ b/src/store/settings/settings.reducer.js
@@ -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);
diff --git a/src/store/settings/settings.type.js b/src/store/settings/settings.type.js
index fac8d63a5..50226c5d2 100644
--- a/src/store/settings/settings.type.js
+++ b/src/store/settings/settings.type.js
@@ -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',
};