mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
chrone: sperate client and server to different repos.
This commit is contained in:
15
src/store/Bills/bills.actions.js
Normal file
15
src/store/Bills/bills.actions.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export const setBillsTableState = (queries) => {
|
||||
return {
|
||||
type: t.BILLS_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
export const resetBillsTableState = () => {
|
||||
return {
|
||||
type: t.BILLS_TABLE_STATE_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
34
src/store/Bills/bills.reducer.js
Normal file
34
src/store/Bills/bills.reducer.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import { createTableStateReducers } from 'store/tableState.reducer';
|
||||
import t from 'store/types';
|
||||
|
||||
export const defaultTableQuery = {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
filterRoles: [],
|
||||
viewSlug: null,
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
tableState: defaultTableQuery,
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:bills';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('BILLS', defaultTableQuery),
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
},
|
||||
});
|
||||
|
||||
export default persistReducer(CONFIG, reducerInstance);
|
||||
25
src/store/Bills/bills.selectors.js
Normal file
25
src/store/Bills/bills.selectors.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
import { defaultTableQuery } from './bills.reducer';
|
||||
|
||||
const billsTableStateSelector = (state) => state.bills.tableState;
|
||||
|
||||
// Get bills table state marged with location query.
|
||||
export const getBillsTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
billsTableStateSelector,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const billsTableStateChangedFactory = () =>
|
||||
createDeepEqualSelector(billsTableStateSelector, (tableState) => {
|
||||
return !isEqual(tableState, defaultTableQuery);
|
||||
});
|
||||
5
src/store/Bills/bills.type.js
Normal file
5
src/store/Bills/bills.type.js
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
export default {
|
||||
BILLS_TABLE_STATE_SET: 'BILLS/TABLE_STATE_SET',
|
||||
BILLS_TABLE_STATE_RESET: 'BILLS/TABLE_STATE_RESET',
|
||||
};
|
||||
14
src/store/Estimate/estimates.actions.js
Normal file
14
src/store/Estimate/estimates.actions.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export const setEstimatesTableState = (queries) => {
|
||||
return {
|
||||
type: t.ESTIMATES_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
export const resetEstimatesTableState = () => {
|
||||
return {
|
||||
type: t.ESTIMATES_TABLE_STATE_RESET,
|
||||
};
|
||||
}
|
||||
39
src/store/Estimate/estimates.reducer.js
Normal file
39
src/store/Estimate/estimates.reducer.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import {
|
||||
createTableStateReducers,
|
||||
} from 'store/tableState.reducer';
|
||||
import t from 'store/types';
|
||||
|
||||
export const defaultTableQuery = {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
filterRoles: [],
|
||||
viewSlug: null,
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
tableState: defaultTableQuery,
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:estimates';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('ESTIMATES', defaultTableQuery),
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
},
|
||||
});
|
||||
|
||||
export default persistReducer(
|
||||
CONFIG,
|
||||
reducerInstance,
|
||||
);
|
||||
24
src/store/Estimate/estimates.selectors.js
Normal file
24
src/store/Estimate/estimates.selectors.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import { isEqual } from 'lodash';
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
import { defaultTableQuery } from './estimates.reducer';
|
||||
|
||||
const estimatesTableState = (state) => state.salesEstimates.tableState;
|
||||
|
||||
// Retrieve estimates table query.
|
||||
export const getEstimatesTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
estimatesTableState,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const isEstimatesTableStateChangedFactory = () =>
|
||||
createDeepEqualSelector(estimatesTableState, (tableState) => {
|
||||
return !isEqual(tableState, defaultTableQuery);
|
||||
});
|
||||
4
src/store/Estimate/estimates.types.js
Normal file
4
src/store/Estimate/estimates.types.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
ESTIMATES_TABLE_STATE_SET: 'ESTIMATES/TABLE_STATE_SET',
|
||||
ESTIMATES_TABLE_STATE_RESET: 'ESTIMATES/TABLE_STATE_RESET',
|
||||
};
|
||||
8
src/store/ExchangeRate/exchange.actions.js
Normal file
8
src/store/ExchangeRate/exchange.actions.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export const setExchangeRateTableState = (queries) => {
|
||||
return {
|
||||
type: t.EXCHANGE_RATES_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
13
src/store/ExchangeRate/exchange.reducer.js
Normal file
13
src/store/ExchangeRate/exchange.reducer.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { createTableStateReducers } from 'store/tableState.reducer';
|
||||
|
||||
const initialState = {
|
||||
tableState: {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
},
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
...createTableStateReducers('EXCHANGE_RATES'),
|
||||
});
|
||||
18
src/store/ExchangeRate/exchange.selector.js
Normal file
18
src/store/ExchangeRate/exchange.selector.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
|
||||
const exchangeRateTableState = (state) => {
|
||||
return state.exchangeRates.tableState;
|
||||
};
|
||||
|
||||
export const getExchangeRatesTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
exchangeRateTableState,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
3
src/store/ExchangeRate/exchange.type.js
Normal file
3
src/store/ExchangeRate/exchange.type.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
EXCHANGE_RATES_TABLE_STATE_SET: 'EXCHANGE_RATES/TABLE_STATE_SET',
|
||||
};
|
||||
16
src/store/Invoice/invoices.actions.js
Normal file
16
src/store/Invoice/invoices.actions.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export const setInvoicesTableState = (queries) => {
|
||||
return {
|
||||
type: t.INVOICES_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
export const resetInvoicesTableState= () => {
|
||||
return {
|
||||
type: t.INVOICES_TABLE_STATE_RESET,
|
||||
};
|
||||
}
|
||||
|
||||
export const setSelectedRowsItems = () => {};
|
||||
39
src/store/Invoice/invoices.reducer.js
Normal file
39
src/store/Invoice/invoices.reducer.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import {
|
||||
createTableStateReducers,
|
||||
} from 'store/tableState.reducer';
|
||||
import t from 'store/types';
|
||||
|
||||
export const defaultTableQuery = {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
filterRoles: [],
|
||||
viewSlug: null,
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
tableState: defaultTableQuery,
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:invoices';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('INVOICES', defaultTableQuery),
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
}
|
||||
});
|
||||
|
||||
export default persistReducer(
|
||||
CONFIG,
|
||||
reducerInstance,
|
||||
);
|
||||
32
src/store/Invoice/invoices.selector.js
Normal file
32
src/store/Invoice/invoices.selector.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import { isEqual } from 'lodash';
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
import { defaultTableQuery } from './invoices.reducer';
|
||||
|
||||
const invoicesTableStateSelector = (state) => state.salesInvoices.tableState;
|
||||
|
||||
/**
|
||||
* Retrieve invoices table state.
|
||||
*/
|
||||
export const getInvoicesTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
invoicesTableStateSelector,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve invoices table state.
|
||||
*/
|
||||
export const isInvoicesTableStateChangedFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
invoicesTableStateSelector,
|
||||
(tableState) => {
|
||||
return !isEqual(tableState, defaultTableQuery);
|
||||
},
|
||||
);
|
||||
5
src/store/Invoice/invoices.types.js
Normal file
5
src/store/Invoice/invoices.types.js
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
export default {
|
||||
INVOICES_TABLE_STATE_SET: 'INVOICES/TABLE_STATE_SET',
|
||||
INVOICES_TABLE_STATE_RESET: 'INVOICES/TABLE_STATE_RESET',
|
||||
};
|
||||
16
src/store/PaymentMades/paymentMades.actions.js
Normal file
16
src/store/PaymentMades/paymentMades.actions.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export const setPaymentMadesTableState = (queries) => {
|
||||
return {
|
||||
type: t.PAYMENT_MADES_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
export const resetPaymentMadesTableState = (queries) => {
|
||||
return {
|
||||
type: t.PAYMENT_MADES_TABLE_STATE_RESET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
35
src/store/PaymentMades/paymentMades.reducer.js
Normal file
35
src/store/PaymentMades/paymentMades.reducer.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import { createTableStateReducers } from 'store/tableState.reducer';
|
||||
import t from 'store/types';
|
||||
|
||||
export const defaultTableQuery = {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
filterRoles: [],
|
||||
sortBy: [],
|
||||
viewSlug: null,
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
tableState: defaultTableQuery,
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:paymentMades';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('PAYMENT_MADES', defaultTableQuery),
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
},
|
||||
});
|
||||
|
||||
export default persistReducer(CONFIG, reducerInstance);
|
||||
25
src/store/PaymentMades/paymentMades.selector.js
Normal file
25
src/store/PaymentMades/paymentMades.selector.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
import { defaultTableQuery } from './paymentMades.reducer';
|
||||
|
||||
const paymentMadesTableStateSelector = (state) => state.paymentMades.tableState;
|
||||
|
||||
// Get payment mades table state marged with location query.
|
||||
export const getPaymentMadesTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
paymentMadesTableStateSelector,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const paymentsTableStateChangedFactory = () =>
|
||||
createDeepEqualSelector(paymentMadesTableStateSelector, (tableState) => {
|
||||
return !isEqual(tableState, defaultTableQuery);
|
||||
});
|
||||
4
src/store/PaymentMades/paymentMades.type.js
Normal file
4
src/store/PaymentMades/paymentMades.type.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
PAYMENT_MADES_TABLE_STATE_SET: 'PAYMENT_MADES/TABLE_STATE_SET',
|
||||
PAYMENT_MADES_TABLE_STATE_RESET: 'PAYMENT_MADES/TABLE_STATE_RESET',
|
||||
};
|
||||
14
src/store/PaymentReceives/paymentReceives.actions.js
Normal file
14
src/store/PaymentReceives/paymentReceives.actions.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export const setPaymentReceivesTableState = (queries) => {
|
||||
return {
|
||||
type: t.PAYMENT_RECEIVES_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
export const resetPaymentReceivesTableState = () => {
|
||||
return {
|
||||
type: t.PAYMENT_RECEIVES_TABLE_STATE_RESET
|
||||
};
|
||||
}
|
||||
39
src/store/PaymentReceives/paymentReceives.reducer.js
Normal file
39
src/store/PaymentReceives/paymentReceives.reducer.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import {
|
||||
createTableStateReducers,
|
||||
} from 'store/tableState.reducer';
|
||||
import t from 'store/types';
|
||||
|
||||
export const defaultTableQuery = {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
filterRoles: [],
|
||||
viewSlug: null,
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
tableState: defaultTableQuery,
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:paymentReceives';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('PAYMENT_RECEIVES', defaultTableQuery),
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
},
|
||||
});
|
||||
|
||||
export default persistReducer(
|
||||
CONFIG,
|
||||
reducerInstance,
|
||||
);
|
||||
26
src/store/PaymentReceives/paymentReceives.selector.js
Normal file
26
src/store/PaymentReceives/paymentReceives.selector.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import {
|
||||
paginationLocationQuery,
|
||||
} from 'store/selectors';
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
import { defaultTableQuery } from './paymentReceives.reducer';
|
||||
|
||||
const paymentReceiveTableState = (state) => state.paymentReceives.tableState;
|
||||
|
||||
// Retrieve payment receives table fetch query.
|
||||
export const getPaymentReceiveTableStateFactory = () => createSelector(
|
||||
paginationLocationQuery,
|
||||
paymentReceiveTableState,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
export const paymentsTableStateChangedFactory = () =>
|
||||
createDeepEqualSelector(paymentReceiveTableState, (tableState) => {
|
||||
return !isEqual(tableState, defaultTableQuery);
|
||||
});
|
||||
4
src/store/PaymentReceives/paymentReceives.type.js
Normal file
4
src/store/PaymentReceives/paymentReceives.type.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
PAYMENT_RECEIVES_TABLE_STATE_SET: 'PAYMENT_RECEIVES/TABLE_STATE_SET',
|
||||
PAYMENT_RECEIVES_TABLE_STATE_RESET: 'PAYMENT_RECEIVES/TABLE_STATE_RESET',
|
||||
};
|
||||
13
src/store/ResetMiddleware.js
Normal file
13
src/store/ResetMiddleware.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export default (next) => (reducer, initialState, enhancer) => {
|
||||
let resetType = 'RESET'
|
||||
let resetData = 'state'
|
||||
|
||||
const enhanceReducer = (state, action) => {
|
||||
if (action.type === resetType) {
|
||||
state = action[resetData]
|
||||
}
|
||||
return reducer(state, action)
|
||||
}
|
||||
|
||||
return next(enhanceReducer, initialState, enhancer)
|
||||
}
|
||||
17
src/store/accounts/accounts.actions.js
Normal file
17
src/store/accounts/accounts.actions.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export const setAccountsTableState = (queries) => {
|
||||
return {
|
||||
type: t.ACCOUNTS_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets the accounts table state.
|
||||
*/
|
||||
export const resetAccountsTableState = () => {
|
||||
return {
|
||||
type: t.ACCOUNTS_TABLE_STATE_RESET,
|
||||
};
|
||||
};
|
||||
34
src/store/accounts/accounts.reducer.js
Normal file
34
src/store/accounts/accounts.reducer.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import { createTableStateReducers } from 'store/tableState.reducer';
|
||||
import t from 'store/types';
|
||||
|
||||
|
||||
export const defaultTableQuery = {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
filterRoles: [],
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
tableState: defaultTableQuery,
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:accounts';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('ACCOUNTS', defaultTableQuery),
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
}
|
||||
});
|
||||
|
||||
export default persistReducer(CONFIG, reducerInstance);
|
||||
26
src/store/accounts/accounts.selectors.js
Normal file
26
src/store/accounts/accounts.selectors.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
import { defaultTableQuery } from './accounts.reducer';
|
||||
|
||||
// Accounts table state selector
|
||||
const accountsTableStateSelector = (state, props) => state.accounts.tableState;
|
||||
|
||||
// Get accounts table state marged with location query.
|
||||
export const getAccountsTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
accountsTableStateSelector,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const accountsTableStateChangedFactory = () =>
|
||||
createDeepEqualSelector(accountsTableStateSelector, (tableState) => {
|
||||
return !isEqual(tableState, defaultTableQuery);
|
||||
});
|
||||
5
src/store/accounts/accounts.types.js
Normal file
5
src/store/accounts/accounts.types.js
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
export default {
|
||||
ACCOUNTS_TABLE_STATE_SET: 'ACCOUNTS/TABLE_STATE_SET',
|
||||
ACCOUNTS_TABLE_STATE_RESET: 'ACCOUNTS/TABLE_STATE_RESET',
|
||||
};
|
||||
5
src/store/authentication/authentication.actions.js
Normal file
5
src/store/authentication/authentication.actions.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export const setLogin = () => ({ type: t.LOGIN_SUCCESS });
|
||||
export const setLogout = () => ({ type: t.LOGOUT });
|
||||
export const setStoreReset = () => ({ type: t.RESET });
|
||||
51
src/store/authentication/authentication.reducer.js
Normal file
51
src/store/authentication/authentication.reducer.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer } from 'redux-persist';
|
||||
import purgeStoredState from 'redux-persist/es/purgeStoredState';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import { getCookie, setCookie } from 'utils';
|
||||
import t from 'store/types';
|
||||
import { removeCookie } from '../../utils';
|
||||
|
||||
// Read stored data in cookies and merge it with the initial state.
|
||||
const initialState = {
|
||||
token: getCookie('token'),
|
||||
organizationId: getCookie('organization_id'),
|
||||
tenantId: getCookie('tenant_id'),
|
||||
userId: getCookie('authenticated_user_id'),
|
||||
locale: getCookie('locale'),
|
||||
errors: [],
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:authentication';
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
[t.LOGIN_FAILURE]: (state, action) => {
|
||||
state.errors = action.errors;
|
||||
},
|
||||
|
||||
[t.LOGIN_CLEAR_ERRORS]: (state) => {
|
||||
state.errors = [];
|
||||
},
|
||||
|
||||
[t.RESET]: (state) => {
|
||||
purgeStoredState(CONFIG);
|
||||
},
|
||||
});
|
||||
|
||||
export default persistReducer(CONFIG, reducerInstance);
|
||||
|
||||
export const isAuthenticated = (state) => !!state.authentication.token;
|
||||
export const hasErrorType = (state, errorType) => {
|
||||
return state.authentication.errors.find((e) => e.type === errorType);
|
||||
};
|
||||
|
||||
export const isTenantSeeded = (state) => !!state.tenant.seeded_at;
|
||||
export const isTenantBuilt = (state) => !!state.tenant.initialized_at;
|
||||
|
||||
export const isTenantHasSubscription = () => false;
|
||||
export const isTenantSubscriptionExpired = () => false;
|
||||
24
src/store/authentication/authentication.selectors.js
Normal file
24
src/store/authentication/authentication.selectors.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import { defaultTo } from 'lodash';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
|
||||
const getCurrentOrganizationId = (state) => state.authentication.organizationId;
|
||||
const getCurrentTenantId = (state) => state.authentication.tenantId;
|
||||
const getOrganizationsMap = (state) => state.organizations.data;
|
||||
|
||||
// Retrieve organization tenant id.
|
||||
export const getOrganizationTenantIdFactory = () =>
|
||||
createSelector(getCurrentTenantId, (tenantId) => tenantId);
|
||||
|
||||
// Retrieve organization id.
|
||||
export const getOrganizationIdFactory = () =>
|
||||
createSelector(getCurrentOrganizationId, (tenantId) => tenantId);
|
||||
|
||||
// Retrieve current organization meta object.
|
||||
export const getCurrentOrganizationFactory = () =>
|
||||
createSelector(
|
||||
getCurrentTenantId,
|
||||
getOrganizationsMap,
|
||||
(tenantId, organizationsMap) => {
|
||||
return defaultTo(organizationsMap[tenantId], {});
|
||||
},
|
||||
);
|
||||
9
src/store/authentication/authentication.types.js
Normal file
9
src/store/authentication/authentication.types.js
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
export default {
|
||||
LOGIN_REQUEST: 'LOGIN_REQUEST',
|
||||
LOGIN_SUCCESS: 'LOGIN_SUCCESS',
|
||||
LOGIN_FAILURE: 'LOGIN_FAILURE',
|
||||
LOGOUT: 'LOGOUT',
|
||||
LOGIN_CLEAR_ERRORS: 'LOGIN_CLEAR_ERRORS',
|
||||
RESET: 'RESET',
|
||||
};
|
||||
18
src/store/billing/Billing.action.js
Normal file
18
src/store/billing/Billing.action.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import ApiService from 'services/ApiService';
|
||||
import t from 'store/types';
|
||||
|
||||
export const submitBilling = ({ form }) => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.post('subscription/license/payment', form)
|
||||
.then((response) => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
const { response } = error;
|
||||
const { data } = response;
|
||||
|
||||
reject(data?.errors);
|
||||
});
|
||||
});
|
||||
};
|
||||
0
src/store/billing/Billing.type.js
Normal file
0
src/store/billing/Billing.type.js
Normal file
52
src/store/createStore.js
Normal file
52
src/store/createStore.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import {
|
||||
createStore as createReduxStore,
|
||||
applyMiddleware,
|
||||
compose,
|
||||
} from 'redux';
|
||||
import thunkMiddleware from 'redux-thunk';
|
||||
import { persistStore } from 'redux-persist';
|
||||
import monitorReducerEnhancer from 'store/enhancers/monitorReducer';
|
||||
import loggerMiddleware from 'middleware/logger';
|
||||
import rootReducer from 'store/reducers';
|
||||
import ResetMiddleware from './ResetMiddleware';
|
||||
|
||||
|
||||
const createStoreFactory = (initialState = {}) => {
|
||||
/**
|
||||
|--------------------------------------------------
|
||||
| Middleware Configuration
|
||||
|--------------------------------------------------
|
||||
*/
|
||||
const middleware = [thunkMiddleware, loggerMiddleware];
|
||||
|
||||
/**
|
||||
|--------------------------------------------------
|
||||
| Store Enhancers
|
||||
|--------------------------------------------------
|
||||
*/
|
||||
const enhancers = [monitorReducerEnhancer, ResetMiddleware];
|
||||
let composeEnhancers = compose;
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
if (typeof window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ === 'function') {
|
||||
composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|--------------------------------------------------
|
||||
| Store Instantiation and HMR Setup
|
||||
|--------------------------------------------------
|
||||
*/
|
||||
const store = createReduxStore(
|
||||
rootReducer,
|
||||
initialState,
|
||||
composeEnhancers(applyMiddleware(...middleware), ...enhancers),
|
||||
);
|
||||
store.asyncReducers = {};
|
||||
return store;
|
||||
};
|
||||
|
||||
export const createStore = createStoreFactory;
|
||||
export const store = createStoreFactory();
|
||||
export const persistor = persistStore(store);
|
||||
69
src/store/currencies/currencies.actions.js
Normal file
69
src/store/currencies/currencies.actions.js
Normal file
@@ -0,0 +1,69 @@
|
||||
import ApiService from 'services/ApiService';
|
||||
import t from 'store/types';
|
||||
|
||||
export const submitCurrencies = ({ form }) => {
|
||||
return (dispatch) => {
|
||||
return ApiService.post('currencies', form);
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteCurrency = ({ currency_code }) => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.delete(`currencies/${currency_code}`)
|
||||
.then((response) => {
|
||||
dispatch({ type: t.CURRENCY_CODE_DELETE, currency_code });
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error.response.data.errors || []);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const editCurrency = ({ id, form }) => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.post(`currencies/${id}`, form)
|
||||
.then((response) => {
|
||||
dispatch({ type: t.CLEAR_CURRENCY_FORM_ERRORS });
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
const { response } = error;
|
||||
const { data } = response;
|
||||
const { errors } = data;
|
||||
|
||||
dispatch({ type: t.CLEAR_CURRENCY_FORM_ERRORS });
|
||||
if (errors) {
|
||||
dispatch({ type: t.CLEAR_CURRENCY_FORM_ERRORS, errors });
|
||||
}
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const fetchCurrencies = () => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
dispatch({
|
||||
type: t.CURRENCIES_TABLE_LOADING,
|
||||
loading: true,
|
||||
});
|
||||
ApiService.get('currencies')
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
type: t.CURRENCIES_REGISTERED_SET,
|
||||
currencies: response.data.currencies,
|
||||
});
|
||||
dispatch({
|
||||
type: t.CURRENCIES_TABLE_LOADING,
|
||||
loading: false,
|
||||
});
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
29
src/store/currencies/currencies.reducer.js
Normal file
29
src/store/currencies/currencies.reducer.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import t from 'store/types';
|
||||
|
||||
const initialState = {
|
||||
data: {},
|
||||
loading: false,
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
[t.CURRENCIES_REGISTERED_SET]: (state, action) => {
|
||||
const _currencies = {};
|
||||
|
||||
action.currencies.forEach((currency) => {
|
||||
_currencies[currency.currency_code] = currency;
|
||||
});
|
||||
state.data = {
|
||||
...state.data,
|
||||
..._currencies,
|
||||
};
|
||||
},
|
||||
[t.CURRENCIES_TABLE_LOADING]: (state, action) => {
|
||||
state.loading = action.loading;
|
||||
},
|
||||
[t.CURRENCY_CODE_DELETE]: (state, action) => {
|
||||
if (typeof state.data[action.currency_code] !== 'undefined') {
|
||||
delete state.data[action.currency_code];
|
||||
}
|
||||
},
|
||||
});
|
||||
22
src/store/currencies/currencies.selector.js
Normal file
22
src/store/currencies/currencies.selector.js
Normal file
@@ -0,0 +1,22 @@
|
||||
// @flow
|
||||
import { createSelector } from 'reselect';
|
||||
import { getItemById } from 'store/selectors';
|
||||
|
||||
const currenciesItemsSelector = (state) => state.currencies.data;
|
||||
const currenciesCodePropSelector = (state, props) => props.currencyId;
|
||||
|
||||
export const getCurrenciesList = createSelector(
|
||||
currenciesItemsSelector,
|
||||
(currencies) => {
|
||||
return Object.values(currencies);
|
||||
},
|
||||
);
|
||||
|
||||
export const getCurrencyByCode = createSelector(
|
||||
currenciesItemsSelector,
|
||||
currenciesCodePropSelector,
|
||||
(currencies, currencyCode) => {
|
||||
return getItemById(currencies, currencyCode);
|
||||
},
|
||||
);
|
||||
|
||||
6
src/store/currencies/currencies.types.js
Normal file
6
src/store/currencies/currencies.types.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
CURRENCIES_REGISTERED_SET: 'CURRENCIES_REGISTERED_SET',
|
||||
CLEAR_CURRENCY_FORM_ERRORS: 'CLEAR_CURRENCY_FORM_ERRORS',
|
||||
CURRENCIES_TABLE_LOADING: 'CURRENCIES_TABLE_LOADING',
|
||||
CURRENCY_CODE_DELETE: 'CURRENCY_CODE_DELETE',
|
||||
};
|
||||
15
src/store/customFields/customFields.actions.js
Normal file
15
src/store/customFields/customFields.actions.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import ApiService from 'services/ApiService';
|
||||
import t from 'store/types';
|
||||
|
||||
export const fetchResourceFields = ({ resourceSlug }) => {
|
||||
return (dispatch) => new Promise((resolve, reject) => {
|
||||
ApiService.get(`fields/resource/${resourceSlug}`).then((response) => {
|
||||
dispatch({
|
||||
type: t.CUSTOM_FIELDS_RESOURCE_SET,
|
||||
resourceSlug: resourceSlug,
|
||||
fields: response.data.fields,
|
||||
});
|
||||
resolve(response);
|
||||
}).catch(error => { reject(error); });
|
||||
});
|
||||
}
|
||||
24
src/store/customFields/customFields.reducer.js
Normal file
24
src/store/customFields/customFields.reducer.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import {createReducer} from '@reduxjs/toolkit';
|
||||
import t from 'store/types';
|
||||
|
||||
const initialState = {
|
||||
custom_fields: {
|
||||
accounts: [{
|
||||
label_name: 'Label',
|
||||
predefined: true,
|
||||
data_type: 'text',
|
||||
help_text: '123sdasd',
|
||||
active: true,
|
||||
}]
|
||||
},
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
[t.CUSTOM_FIELDS_RESOURCE_SET]: (state, action) => {
|
||||
state.fields.custom_fields[action.resource_slug] = action.custom_field;
|
||||
}
|
||||
});
|
||||
|
||||
export const getCustomFieldsByResource = (state, resourceSlug) => {
|
||||
return state.fields.custom_fields[resourceSlug];
|
||||
}
|
||||
4
src/store/customFields/customFields.types.js
Normal file
4
src/store/customFields/customFields.types.js
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
export default {
|
||||
CUSTOM_FIELDS_RESOURCE_SET: 'CUSTOM_FIELDS_RESOURCE_SET',
|
||||
};
|
||||
63
src/store/customViews/customViews.actions.js
Normal file
63
src/store/customViews/customViews.actions.js
Normal file
@@ -0,0 +1,63 @@
|
||||
import ApiService from "services/ApiService";
|
||||
import t from 'store/types';
|
||||
|
||||
export const submitView = ({ form }) => {
|
||||
return (dispatch) => ApiService.post('views', form);
|
||||
};
|
||||
|
||||
export const editView = ({ id, form }) => {
|
||||
return (dispatch) => ApiService.post(`views/${id}`, form);
|
||||
};
|
||||
|
||||
export const deleteView = ({ id }) => {
|
||||
return (dispatch) => ApiService.delete(`views/${id}`);
|
||||
};
|
||||
|
||||
export const fetchView = ({ id }) => {
|
||||
return (dispatch) => new Promise((resolve, reject) => {
|
||||
ApiService.get(`views/${id}`).then((response) => {
|
||||
dispatch({
|
||||
type: t.VIEW_META_SET,
|
||||
view: response.data.view,
|
||||
});
|
||||
resolve(response);
|
||||
}).catch(error => { reject(error); });
|
||||
});
|
||||
};
|
||||
|
||||
export const fetchResourceViews = ({ resourceSlug }) => {
|
||||
return (dispatch) => new Promise((resolve, reject) => {
|
||||
ApiService.get(`views/resource/${resourceSlug}`)
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
type: t.RESOURCE_VIEWS_SET,
|
||||
resource: resourceSlug,
|
||||
views: response.data.views,
|
||||
});
|
||||
dispatch({
|
||||
type: t.VIEW_ITEMS_SET,
|
||||
views: response.data.views,
|
||||
});
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => { reject(error); });
|
||||
});
|
||||
};
|
||||
|
||||
export const fetchViewResource = ({ id }) => {
|
||||
return (dispatch) => new Promise((resolve, reject) => {
|
||||
ApiService.get(`views/${id}/resource`).then((response) => {
|
||||
dispatch({
|
||||
type: t.RESOURCE_COLUMNS_SET,
|
||||
columns: response.data.resource_columns,
|
||||
resource_slug: response.data.resource_slug
|
||||
});
|
||||
dispatch({
|
||||
type: t.RESOURCE_FIELDS_SET,
|
||||
fields: response.data.resource_fields,
|
||||
resource_slug: response.data.resource_slug,
|
||||
});
|
||||
resolve(response);
|
||||
}).catch((error) => { reject(error); });
|
||||
});
|
||||
}
|
||||
30
src/store/customViews/customViews.reducer.js
Normal file
30
src/store/customViews/customViews.reducer.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { createReducer } from "@reduxjs/toolkit";
|
||||
import t from 'store/types';
|
||||
|
||||
const initialState = {
|
||||
views: {},
|
||||
resourceViews: {
|
||||
'accounts': [],
|
||||
'expenses': [],
|
||||
},
|
||||
viewsMeta: {},
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
[t.VIEW_META_SET]: (state, action) => {
|
||||
state.viewsMeta[action.view.id] = action.view;
|
||||
},
|
||||
|
||||
[t.RESOURCE_VIEWS_SET]: (state, action) => {
|
||||
state.resourceViews[action.resource] = action.views.map(v => v.id);
|
||||
},
|
||||
|
||||
[t.VIEW_ITEMS_SET]: (state, action) => {
|
||||
const _views = {};
|
||||
|
||||
action.views.forEach((view) => {
|
||||
_views[view.id] = view;
|
||||
});
|
||||
state.views = { ...state.views, ..._views };
|
||||
},
|
||||
})
|
||||
42
src/store/customViews/customViews.selectors.js
Normal file
42
src/store/customViews/customViews.selectors.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import { createSelector } from 'reselect';
|
||||
import { pickItemsFromIds } from 'store/selectors';
|
||||
import { getResourceColumn } from 'store/resources/resources.reducer';
|
||||
|
||||
const resourceViewsIdsSelector = (state, props, resourceName) =>
|
||||
state.views.resourceViews[resourceName];
|
||||
|
||||
const viewsSelector = (state) => state.views.views;
|
||||
const viewByIdSelector = (state, props) => state.views.views[props.viewId];
|
||||
|
||||
const viewColumnsSelector = (state, props) => {
|
||||
};
|
||||
|
||||
export const getResourceViews = createSelector(
|
||||
resourceViewsIdsSelector,
|
||||
viewsSelector,
|
||||
(resourceViewsIds, views) => {
|
||||
return pickItemsFromIds(views, resourceViewsIds);
|
||||
},
|
||||
);
|
||||
|
||||
export const getViewMetaFactory = () => createSelector(
|
||||
viewByIdSelector,
|
||||
// viewColumnsSelector,
|
||||
(view, viewColumns) => {
|
||||
return view;
|
||||
}
|
||||
);
|
||||
|
||||
export const getViewItemFactory = () => createSelector(
|
||||
viewByIdSelector,
|
||||
// viewColumnsSelector,
|
||||
(view, viewColumns) => {
|
||||
return view;
|
||||
}
|
||||
);
|
||||
|
||||
export const getViewPages = (resourceViews, viewId) => {
|
||||
return typeof resourceViews[viewId] === 'undefined'
|
||||
? {}
|
||||
: resourceViews[viewId].pages;
|
||||
};
|
||||
6
src/store/customViews/customViews.types.js
Normal file
6
src/store/customViews/customViews.types.js
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
export default {
|
||||
VIEW_META_SET: 'VIEW_META_SET',
|
||||
VIEW_ITEMS_SET: 'VIEW_ITEMS_SET',
|
||||
RESOURCE_VIEWS_SET: 'RESOURCE_VIEWS_SET',
|
||||
};
|
||||
17
src/store/customers/customers.actions.js
Normal file
17
src/store/customers/customers.actions.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import t from 'store/types';
|
||||
|
||||
/**
|
||||
* Sets the customers table state.
|
||||
*/
|
||||
export const setCustomersTableState = (queries) => {
|
||||
return {
|
||||
type: t.CUSTOMERS_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
export const resetCustomersTableState = () => {
|
||||
return {
|
||||
type: t.CUSTOMERS_TABLE_STATE_RESET,
|
||||
};
|
||||
}
|
||||
33
src/store/customers/customers.reducer.js
Normal file
33
src/store/customers/customers.reducer.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import { createTableStateReducers } from 'store/tableState.reducer';
|
||||
|
||||
// Default table query state.
|
||||
export const defaultTableQueryState = {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
inactiveMode: false,
|
||||
filterRoles: [],
|
||||
viewSlug: null,
|
||||
};
|
||||
|
||||
// initial data.
|
||||
const initialState = {
|
||||
tableState: defaultTableQueryState,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('CUSTOMERS', defaultTableQueryState),
|
||||
});
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:estimates';
|
||||
|
||||
export default persistReducer(
|
||||
{
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
},
|
||||
reducerInstance,
|
||||
);
|
||||
25
src/store/customers/customers.selectors.js
Normal file
25
src/store/customers/customers.selectors.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
import { defaultTableQueryState } from './customers.reducer';
|
||||
|
||||
const customerTableStateSelector = (state) => state.customers.tableState;
|
||||
|
||||
export const getCustomersTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
customerTableStateSelector,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const customersTableStateChangedFactory = () =>
|
||||
createDeepEqualSelector(customerTableStateSelector, (tableState) => {
|
||||
return !isEqual(tableState, defaultTableQueryState);
|
||||
});
|
||||
|
||||
4
src/store/customers/customers.type.js
Normal file
4
src/store/customers/customers.type.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
CUSTOMERS_TABLE_STATE_SET: 'CUSTOMERS/TABLE_STATE_SET',
|
||||
CUSTOMERS_TABLE_STATE_RESET: 'CUSTOMERS/TABLE_STATE_RESET'
|
||||
};
|
||||
87
src/store/dashboard/dashboard.actions.js
Normal file
87
src/store/dashboard/dashboard.actions.js
Normal file
@@ -0,0 +1,87 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export function dashboardPageTitle(pageTitle) {
|
||||
return {
|
||||
type: t.CHANGE_DASHBOARD_PAGE_TITLE,
|
||||
pageTitle,
|
||||
};
|
||||
}
|
||||
|
||||
export function dashboardPageHint(pageHint) {
|
||||
return {
|
||||
type: t.CHANGE_DASHBOARD_PAGE_HINT,
|
||||
pageHint,
|
||||
};
|
||||
}
|
||||
|
||||
export function openDialog(name, payload) {
|
||||
return {
|
||||
type: t.OPEN_DIALOG,
|
||||
name: name,
|
||||
payload: payload,
|
||||
};
|
||||
}
|
||||
|
||||
export function closeDialog(name, payload) {
|
||||
return {
|
||||
type: t.CLOSE_DIALOG,
|
||||
name: name,
|
||||
payload: payload,
|
||||
};
|
||||
}
|
||||
|
||||
export function openAlert(name, payload) {
|
||||
return {
|
||||
type: t.OPEN_ALERT,
|
||||
name,
|
||||
payload,
|
||||
};
|
||||
}
|
||||
|
||||
export function closeAlert(name, payload) {
|
||||
return {
|
||||
type: t.CLOSE_ALERT,
|
||||
name,
|
||||
payload,
|
||||
};
|
||||
}
|
||||
|
||||
export function openDrawer(name, payload) {
|
||||
return {
|
||||
type: t.OPEN_DRAWER,
|
||||
name,
|
||||
payload,
|
||||
};
|
||||
}
|
||||
export function closeDrawer(name, payload) {
|
||||
return {
|
||||
type: t.CLOSE_DRAWER,
|
||||
name,
|
||||
payload,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the sidebar expend.
|
||||
*/
|
||||
export function toggleExpendSidebar(toggle) {
|
||||
return {
|
||||
type: t.SIDEBAR_EXPEND_TOGGLE,
|
||||
payload: { toggle }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export function appIsLoading(toggle) {
|
||||
return {
|
||||
type: t.APP_IS_LOADING,
|
||||
payload: { isLoading: toggle },
|
||||
};
|
||||
}
|
||||
|
||||
export function appIntlIsLoading(toggle) {
|
||||
return {
|
||||
type: t.APP_INTL_IS_LOADING,
|
||||
payload: { isLoading: toggle },
|
||||
};
|
||||
}
|
||||
130
src/store/dashboard/dashboard.reducer.js
Normal file
130
src/store/dashboard/dashboard.reducer.js
Normal file
@@ -0,0 +1,130 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { isUndefined } from 'lodash';
|
||||
import t from 'store/types';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
|
||||
const initialState = {
|
||||
pageTitle: '',
|
||||
pageSubtitle: '',
|
||||
pageHint: '',
|
||||
preferencesPageTitle: '',
|
||||
sidebarExpended: true,
|
||||
dialogs: {},
|
||||
alerts: {},
|
||||
drawers: {},
|
||||
topbarEditViewId: null,
|
||||
requestsLoading: 0,
|
||||
backLink: false,
|
||||
appIsLoading: true,
|
||||
appIntlIsLoading: true,
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:dashboard';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
[t.CHANGE_DASHBOARD_PAGE_TITLE]: (state, action) => {
|
||||
state.pageTitle = action.pageTitle;
|
||||
},
|
||||
|
||||
[t.ALTER_DASHBOARD_PAGE_SUBTITLE]: (state, action) => {
|
||||
state.pageSubtitle = action.pageSubtitle;
|
||||
},
|
||||
|
||||
[t.CHANGE_DASHBOARD_PAGE_HINT]: (state, action) => {
|
||||
state.pageHint = action.payload.pageHint;
|
||||
},
|
||||
|
||||
[t.CHANGE_PREFERENCES_PAGE_TITLE]: (state, action) => {
|
||||
state.preferencesPageTitle = action.pageTitle;
|
||||
},
|
||||
|
||||
[t.OPEN_DIALOG]: (state, action) => {
|
||||
state.dialogs[action.name] = {
|
||||
isOpen: true,
|
||||
payload: action.payload || {},
|
||||
};
|
||||
},
|
||||
|
||||
[t.CLOSE_DIALOG]: (state, action) => {
|
||||
state.dialogs[action.name] = {
|
||||
...state.dialogs[action.name],
|
||||
isOpen: false,
|
||||
};
|
||||
},
|
||||
|
||||
[t.OPEN_ALERT]: (state, action) => {
|
||||
state.alerts[action.name] = {
|
||||
isOpen: true,
|
||||
payload: action.payload || {},
|
||||
};
|
||||
},
|
||||
|
||||
[t.CLOSE_ALERT]: (state, action) => {
|
||||
state.alerts[action.name] = {
|
||||
...state.alerts[action.name],
|
||||
isOpen: false,
|
||||
};
|
||||
},
|
||||
[t.OPEN_DRAWER]: (state, action) => {
|
||||
state.drawers[action.name] = {
|
||||
isOpen: true,
|
||||
payload: action.payload || {},
|
||||
};
|
||||
},
|
||||
[t.CLOSE_DRAWER]: (state, action) => {
|
||||
state.drawers[action.name] = {
|
||||
...state.drawers[action.name],
|
||||
isOpen: false,
|
||||
};
|
||||
},
|
||||
[t.CLOSE_ALL_DIALOGS]: (state, action) => {},
|
||||
|
||||
[t.SET_TOPBAR_EDIT_VIEW]: (state, action) => {
|
||||
state.topbarEditViewId = action.id;
|
||||
},
|
||||
|
||||
[t.SIDEBAR_EXPEND_TOGGLE]: (state, action) => {
|
||||
const { toggle } = action.payload;
|
||||
state.sidebarExpended = isUndefined(toggle)
|
||||
? !state.sidebarExpended
|
||||
: !!toggle;
|
||||
},
|
||||
|
||||
[t.SET_DASHBOARD_BACK_LINK]: (state, action) => {
|
||||
const { backLink } = action.payload;
|
||||
state.backLink = backLink;
|
||||
},
|
||||
|
||||
[t.APP_IS_LOADING]: (state, action) => {
|
||||
const { isLoading } = action.payload;
|
||||
state.appIsLoading = isLoading;
|
||||
},
|
||||
|
||||
[t.APP_INTL_IS_LOADING]: (state, action) => {
|
||||
const { isLoading } = action.payload;
|
||||
state.appIntlIsLoading = isLoading;
|
||||
},
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
},
|
||||
});
|
||||
|
||||
export default persistReducer(CONFIG, reducerInstance);
|
||||
|
||||
export const getDialogPayload = (state, dialogName) => {
|
||||
return typeof state.dashboard.dialogs[dialogName] !== 'undefined'
|
||||
? state.dashboard.dialogs[dialogName].payload
|
||||
: {};
|
||||
};
|
||||
|
||||
export const getDialogActiveStatus = (state, dialogName) => {
|
||||
return true;
|
||||
};
|
||||
40
src/store/dashboard/dashboard.selectors.js
Normal file
40
src/store/dashboard/dashboard.selectors.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
|
||||
const dialogByNameSelector = (state, props) =>
|
||||
state.dashboard.dialogs?.[props.dialogName];
|
||||
|
||||
export const isDialogOpenFactory = () =>
|
||||
createSelector(dialogByNameSelector, (dialog) => {
|
||||
return dialog && dialog.isOpen;
|
||||
});
|
||||
|
||||
export const getDialogPayloadFactory = () =>
|
||||
createSelector(dialogByNameSelector, (dialog) => {
|
||||
return { ...dialog?.payload };
|
||||
});
|
||||
|
||||
const alertByNameSelector = (state, props) =>
|
||||
state.dashboard.alerts?.[props.name];
|
||||
|
||||
export const isAlertOpenFactory = () =>
|
||||
createSelector(alertByNameSelector, (alert) => {
|
||||
return alert && alert.isOpen;
|
||||
});
|
||||
|
||||
export const getAlertPayloadFactory = () =>
|
||||
createSelector(alertByNameSelector, (alert) => {
|
||||
return { ...alert?.payload };
|
||||
});
|
||||
|
||||
const drawerByNameSelector = (state, props) =>
|
||||
state.dashboard.drawers?.[props.name];
|
||||
|
||||
export const isDrawerOpenFactory = () =>
|
||||
createSelector(drawerByNameSelector, (drawer) => {
|
||||
return drawer && drawer.isOpen;
|
||||
});
|
||||
|
||||
export const getDrawerPayloadFactory = () =>
|
||||
createSelector(drawerByNameSelector, (drawer) => {
|
||||
return { ...drawer?.payload };
|
||||
});
|
||||
19
src/store/dashboard/dashboard.types.js
Normal file
19
src/store/dashboard/dashboard.types.js
Normal file
@@ -0,0 +1,19 @@
|
||||
export default {
|
||||
OPEN_DIALOG: 'OPEN_DIALOG',
|
||||
CLOSE_DIALOG: 'CLOSE_DIALOG',
|
||||
OPEN_ALERT: 'OPEN_ALERT',
|
||||
CLOSE_ALERT: 'CLOSE_ALERT',
|
||||
CLOSE_ALL_DIALOGS: 'CLOSE_ALL_DIALOGS',
|
||||
CLOSE_ALL_ALERTS: 'CLOSE_ALL_ALERTS',
|
||||
OPEN_DRAWER: 'OPEN_DRAWER',
|
||||
CLOSE_DRAWER: 'CLOSE_DRAWER',
|
||||
CHANGE_DASHBOARD_PAGE_TITLE: 'CHANGE_DASHBOARD_PAGE_TITLE',
|
||||
CHANGE_DASHBOARD_PAGE_HINT: 'CHANGE_DASHBOARD_PAGE_HINT',
|
||||
CHANGE_PREFERENCES_PAGE_TITLE: 'CHANGE_PREFERENCES_PAGE_TITLE',
|
||||
ALTER_DASHBOARD_PAGE_SUBTITLE: 'ALTER_DASHBOARD_PAGE_SUBTITLE',
|
||||
SET_TOPBAR_EDIT_VIEW: 'SET_TOPBAR_EDIT_VIEW',
|
||||
SIDEBAR_EXPEND_TOGGLE: 'SIDEBAR_EXPEND_TOGGLE',
|
||||
SET_DASHBOARD_BACK_LINK: 'SET_DASHBOARD_BACK_LINK',
|
||||
APP_IS_LOADING: 'APP_IS_LOADING',
|
||||
APP_INTL_IS_LOADING: 'APP_INTL_IS_LOADING'
|
||||
};
|
||||
17
src/store/enhancers/monitorReducer.js
Normal file
17
src/store/enhancers/monitorReducer.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const round = number => Math.round(number * 100) / 100
|
||||
const monitorReducerEnhancer = createStore => (
|
||||
reducer,
|
||||
initialState,
|
||||
enhancer
|
||||
) => {
|
||||
const monitoredReducer = (state, action) => {
|
||||
const start = performance.now()
|
||||
const newState = reducer(state, action)
|
||||
const end = performance.now()
|
||||
const diff = round(end - start)
|
||||
console.log('reducer process time:', diff)
|
||||
return newState
|
||||
}
|
||||
return createStore(monitoredReducer, initialState, enhancer)
|
||||
}
|
||||
export default monitorReducerEnhancer
|
||||
19
src/store/expenses/expenses.actions.js
Normal file
19
src/store/expenses/expenses.actions.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import t from 'store/types';
|
||||
|
||||
/**
|
||||
* Sets global table state of the table.
|
||||
* @param {object} queries
|
||||
*/
|
||||
export const setExpensesTableState = (queries) => {
|
||||
return {
|
||||
type: t.EXPENSES_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
export const resetExpensesTableState = () => {
|
||||
return {
|
||||
type: t.EXPENSES_TABLE_STATE_RESET,
|
||||
};
|
||||
};
|
||||
|
||||
36
src/store/expenses/expenses.reducer.js
Normal file
36
src/store/expenses/expenses.reducer.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import { createTableStateReducers } from 'store/tableState.reducer';
|
||||
import t from 'store/types';
|
||||
|
||||
// Default table query.
|
||||
export const defaultTableQuery = {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
filterRoles: [],
|
||||
viewSlug: null,
|
||||
};
|
||||
|
||||
// Initial state.
|
||||
const initialState = {
|
||||
tableState: defaultTableQuery,
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:expenses';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('EXPENSES', defaultTableQuery),
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
}
|
||||
});
|
||||
|
||||
export default persistReducer(CONFIG, reducerInstance);
|
||||
26
src/store/expenses/expenses.selectors.js
Normal file
26
src/store/expenses/expenses.selectors.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
import { defaultTableQuery } from './expenses.reducer';
|
||||
|
||||
// Items table state selectors.
|
||||
const expensesTableStateSelector = (state) => state.expenses.tableState;
|
||||
|
||||
// Retrive expenses table query.
|
||||
export const getExpensesTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
expensesTableStateSelector,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const expensesTableStateChangedFactory = () =>
|
||||
createDeepEqualSelector(expensesTableStateSelector, (tableState) => {
|
||||
return !isEqual(tableState, defaultTableQuery);
|
||||
});
|
||||
4
src/store/expenses/expenses.types.js
Normal file
4
src/store/expenses/expenses.types.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
EXPENSES_TABLE_STATE_SET: 'EXPENSES/TABLE_STATE_SET',
|
||||
EXPENSES_TABLE_STATE_RESET: 'EXPENSES/TABLE_STATE_RESET',
|
||||
};
|
||||
206
src/store/financialStatement/financialStatements.actions.js
Normal file
206
src/store/financialStatement/financialStatements.actions.js
Normal file
@@ -0,0 +1,206 @@
|
||||
import t from 'store/types';
|
||||
|
||||
/**
|
||||
* Toggles display of the balance sheet filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleBalanceSheetFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.BALANCE_SHEET}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the trial balance sheet filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleTrialBalanceSheetFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.TRIAL_BALANCE_SHEET}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the journal sheet filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleJournalSheeetFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.JOURNAL}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the profit/loss filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleProfitLossFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.PROFIT_LOSS}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the general ledger filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleGeneralLedgerFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.GENERAL_LEDGER}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the AR aging summary filter drawer.
|
||||
* @param {boolean} toggle -
|
||||
*/
|
||||
export function toggleARAgingSummaryFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.AR_AGING_SUMMARY}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the AP aging summary filter drawer.
|
||||
* @param {boolean} toggle -
|
||||
*/
|
||||
export function toggleAPAgingSummaryFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.AP_AGING_SUMMARY}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the purchases by items filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function togglePurchasesByItemsFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.PURCHASES_BY_ITEMS}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the sells by items filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleSalesByItemsFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.SALES_BY_ITEMS}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Toggles display of the inventory valuation filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleInventoryValuationFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.INVENTORY_VALUATION}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the customers balance summary filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleCustomersBalanceSummaryFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.CUSTOMERS_BALANCE_SUMMARY}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Toggles display of the vendors balance summary filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleVendorsBalanceSummaryFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.VENDORS_BALANCE_SUMMARY}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Toggles display of the customers transactions filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleCustomersTransactionsFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.CUSTOMERS_TRANSACTIONS}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the vendors transactions filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleVendorsTransactionsFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.VENDORS_TRANSACTIONS}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle display of the cash flow statement filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleCashFlowStatementFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.CASH_FLOW_STATEMENT}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the inventory item details filter drawer.
|
||||
* @param {boolean} toggle
|
||||
*/
|
||||
export function toggleInventoryItemDetailsFilterDrawer(toggle) {
|
||||
return {
|
||||
type: `${t.INVENTORY_ITEM_DETAILS}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
|
||||
payload: {
|
||||
toggle,
|
||||
},
|
||||
};
|
||||
}
|
||||
190
src/store/financialStatement/financialStatements.mappers.js
Normal file
190
src/store/financialStatement/financialStatements.mappers.js
Normal file
@@ -0,0 +1,190 @@
|
||||
import { omit, chain } from 'lodash';
|
||||
import moment from 'moment';
|
||||
|
||||
export const mapBalanceSheetToTableRows = (accounts) => {
|
||||
return accounts.map((account) => {
|
||||
return {
|
||||
...account,
|
||||
children: mapBalanceSheetToTableRows([
|
||||
...(account.children ? account.children : []),
|
||||
...(account.total && account.children && account.children.length > 0
|
||||
? [
|
||||
{
|
||||
name: `Total ${account.name}`,
|
||||
row_types: ['total-row', account.section_type],
|
||||
total: { ...account.total },
|
||||
...(account.total_periods && {
|
||||
total_periods: account.total_periods,
|
||||
}),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
]),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export const profitLossToTableRowsMapper = () => {};
|
||||
|
||||
export const journalToTableRowsMapper = (journal) => {
|
||||
const TYPES = {
|
||||
ENTRY: 'ENTRY',
|
||||
TOTAL_ENTRIES: 'TOTAL_ENTRIES',
|
||||
EMPTY_ROW: 'EMPTY_ROW',
|
||||
};
|
||||
|
||||
const entriesMapper = (transaction) => {
|
||||
return transaction.entries.map((entry, index) => ({
|
||||
...(index === 0
|
||||
? {
|
||||
date: transaction.date,
|
||||
reference_type: transaction.reference_type,
|
||||
reference_id: transaction.reference_id,
|
||||
reference_type_formatted: transaction.reference_type_formatted,
|
||||
}
|
||||
: {}),
|
||||
rowType: TYPES.ENTRY,
|
||||
...entry,
|
||||
}));
|
||||
};
|
||||
|
||||
return chain(journal)
|
||||
.map((transaction) => {
|
||||
const entries = entriesMapper(transaction);
|
||||
|
||||
return [
|
||||
...entries,
|
||||
{
|
||||
rowType: TYPES.TOTAL_ENTRIES,
|
||||
currency_code: transaction.currency_code,
|
||||
credit: transaction.credit,
|
||||
debit: transaction.debit,
|
||||
formatted_credit: transaction.formatted_credit,
|
||||
formatted_debit: transaction.formatted_debit,
|
||||
},
|
||||
{
|
||||
rowType: TYPES.EMPTY_ROW,
|
||||
},
|
||||
];
|
||||
})
|
||||
.flatten()
|
||||
.value();
|
||||
};
|
||||
|
||||
export const generalLedgerToTableRows = (accounts) => {
|
||||
return chain(accounts)
|
||||
.map((account) => {
|
||||
return {
|
||||
name: '',
|
||||
code: account.code,
|
||||
rowType: 'ACCOUNT_ROW',
|
||||
date: account.name,
|
||||
children: [
|
||||
{
|
||||
...account.opening_balance,
|
||||
name: 'Opening balance',
|
||||
rowType: 'OPENING_BALANCE',
|
||||
},
|
||||
...account.transactions.map((transaction) => ({
|
||||
...transaction,
|
||||
name: account.name,
|
||||
code: account.code,
|
||||
date: moment(transaction.date).format('DD MMM YYYY'),
|
||||
})),
|
||||
{
|
||||
...account.closing_balance,
|
||||
name: 'Closing balance',
|
||||
rowType: 'CLOSING_BALANCE',
|
||||
},
|
||||
],
|
||||
};
|
||||
})
|
||||
.value();
|
||||
};
|
||||
|
||||
export const ARAgingSummaryTableRowsMapper = (sheet, total) => {
|
||||
const rows = [];
|
||||
|
||||
const mapAging = (agingPeriods) => {
|
||||
return agingPeriods.reduce((acc, aging, index) => {
|
||||
acc[`aging-${index}`] = aging.total.formatted_amount;
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
sheet.customers.forEach((customer) => {
|
||||
const agingRow = mapAging(customer.aging);
|
||||
|
||||
rows.push({
|
||||
rowType: 'customer',
|
||||
name: customer.customer_name,
|
||||
...agingRow,
|
||||
current: customer.current.formatted_amount,
|
||||
total: customer.total.formatted_amount,
|
||||
});
|
||||
});
|
||||
if (rows.length <= 0) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
...rows,
|
||||
{
|
||||
name: '',
|
||||
rowType: 'total',
|
||||
current: sheet.total.current.formatted_amount,
|
||||
...mapAging(sheet.total.aging),
|
||||
total: sheet.total.total.formatted_amount,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export const APAgingSummaryTableRowsMapper = (sheet, total) => {
|
||||
const rows = [];
|
||||
|
||||
const mapAging = (agingPeriods) => {
|
||||
return agingPeriods.reduce((acc, aging, index) => {
|
||||
acc[`aging-${index}`] = aging.total.formatted_amount;
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
sheet.vendors.forEach((vendor) => {
|
||||
const agingRow = mapAging(vendor.aging);
|
||||
|
||||
rows.push({
|
||||
rowType: 'vendor',
|
||||
name: vendor.vendor_name,
|
||||
...agingRow,
|
||||
current: vendor.current.formatted_amount,
|
||||
total: vendor.total.formatted_amount,
|
||||
});
|
||||
});
|
||||
if (rows.length <= 0) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
...rows,
|
||||
{
|
||||
name: '',
|
||||
rowType: 'total',
|
||||
current: sheet.total.current.formatted_amount,
|
||||
...mapAging(sheet.total.aging),
|
||||
total: sheet.total.total.formatted_amount,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export const mapTrialBalanceSheetToRows = (sheet) => {
|
||||
const results = [];
|
||||
|
||||
if (sheet.accounts) {
|
||||
sheet.accounts.forEach((account) => {
|
||||
results.push(account);
|
||||
});
|
||||
}
|
||||
if (sheet.total) {
|
||||
results.push({
|
||||
rowType: 'total',
|
||||
...sheet.total,
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
105
src/store/financialStatement/financialStatements.reducer.js
Normal file
105
src/store/financialStatement/financialStatements.reducer.js
Normal file
@@ -0,0 +1,105 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import t from 'store/types';
|
||||
|
||||
// Initial state.
|
||||
const initialState = {
|
||||
balanceSheet: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
trialBalance: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
generalLedger: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
journal: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
profitLoss: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
ARAgingSummary: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
APAgingSummary: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
purchasesByItems: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
salesByItems: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
inventoryValuation: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
customersBalanceSummary: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
vendorsBalanceSummary: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
customersTransactions: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
vendorsTransactions: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
cashFlowStatement: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
inventoryItemDetails: {
|
||||
displayFilterDrawer: false,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Financial statement filter toggle.
|
||||
*/
|
||||
const financialStatementFilterToggle = (financialName, statePath) => {
|
||||
return {
|
||||
[`${financialName}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`]: (state, action) => {
|
||||
state[statePath].displayFilterDrawer =
|
||||
typeof action?.payload?.toggle !== 'undefined'
|
||||
? action.payload.toggle
|
||||
: !state[statePath].displayFilterDrawer;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
...financialStatementFilterToggle(t.BALANCE_SHEET, 'balanceSheet'),
|
||||
...financialStatementFilterToggle(t.TRIAL_BALANCE_SHEET, 'trialBalance'),
|
||||
...financialStatementFilterToggle(t.JOURNAL, 'journal'),
|
||||
...financialStatementFilterToggle(t.GENERAL_LEDGER, 'generalLedger'),
|
||||
...financialStatementFilterToggle(t.PROFIT_LOSS, 'profitLoss'),
|
||||
...financialStatementFilterToggle(t.AR_AGING_SUMMARY, 'ARAgingSummary'),
|
||||
...financialStatementFilterToggle(t.AP_AGING_SUMMARY, 'APAgingSummary'),
|
||||
...financialStatementFilterToggle(t.PURCHASES_BY_ITEMS, 'purchasesByItems'),
|
||||
...financialStatementFilterToggle(t.SALES_BY_ITEMS, 'salesByItems'),
|
||||
...financialStatementFilterToggle(
|
||||
t.INVENTORY_VALUATION,
|
||||
'inventoryValuation',
|
||||
),
|
||||
...financialStatementFilterToggle(
|
||||
t.CUSTOMERS_BALANCE_SUMMARY,
|
||||
'customersBalanceSummary',
|
||||
),
|
||||
...financialStatementFilterToggle(
|
||||
t.VENDORS_BALANCE_SUMMARY,
|
||||
'vendorsBalanceSummary',
|
||||
),
|
||||
...financialStatementFilterToggle(
|
||||
t.CUSTOMERS_TRANSACTIONS,
|
||||
'customersTransactions',
|
||||
),
|
||||
...financialStatementFilterToggle(
|
||||
t.VENDORS_TRANSACTIONS,
|
||||
'vendorsTransactions',
|
||||
),
|
||||
...financialStatementFilterToggle(t.CASH_FLOW_STATEMENT, 'cashFlowStatement'),
|
||||
...financialStatementFilterToggle(
|
||||
t.INVENTORY_ITEM_DETAILS,
|
||||
'inventoryItemDetails',
|
||||
),
|
||||
});
|
||||
241
src/store/financialStatement/financialStatements.selectors.js
Normal file
241
src/store/financialStatement/financialStatements.selectors.js
Normal file
@@ -0,0 +1,241 @@
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
// Financial Statements selectors.
|
||||
export const sheetByTypeSelector = (sheetType) => (state, props) => {
|
||||
return state.financialStatements[sheetType];
|
||||
};
|
||||
|
||||
export const filterDrawerByTypeSelector = (sheetType) => (state) => {
|
||||
return sheetByTypeSelector(sheetType)(state)?.displayFilterDrawer;
|
||||
};
|
||||
|
||||
export const balanceSheetFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('balanceSheet')(state);
|
||||
};
|
||||
|
||||
export const profitLossSheetFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('profitLoss')(state);
|
||||
};
|
||||
|
||||
export const generalLedgerFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('generalLedger')(state);
|
||||
};
|
||||
|
||||
// Trial balance filter drawer selector.
|
||||
export const trialBalanceFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('trialBalance')(state);
|
||||
};
|
||||
|
||||
export const journalFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('journal')(state);
|
||||
};
|
||||
|
||||
export const ARAgingSummaryFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('ARAgingSummary')(state);
|
||||
};
|
||||
|
||||
export const APAgingSummaryFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('APAgingSummary')(state);
|
||||
};
|
||||
|
||||
export const purchasesByItemsFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('purchasesByItems')(state);
|
||||
};
|
||||
|
||||
export const salesByItemsFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('salesByItems')(state);
|
||||
};
|
||||
export const inventoryValuationFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('inventoryValuation')(state);
|
||||
};
|
||||
|
||||
export const customerBalanceSummaryFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('customersBalanceSummary')(state);
|
||||
};
|
||||
|
||||
export const vendorsBalanceSummaryFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('vendorsBalanceSummary')(state);
|
||||
};
|
||||
|
||||
export const customersTransactionsFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('customersTransactions')(state);
|
||||
};
|
||||
|
||||
export const vendorsTransactionsFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('vendorsTransactions')(state);
|
||||
};
|
||||
|
||||
export const cashFlowStatementFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('cashFlowStatement')(state);
|
||||
};
|
||||
|
||||
export const inventoryItemDetailsDrawerFilter = (state) => {
|
||||
return filterDrawerByTypeSelector('inventoryItemDetails')(state);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve balance sheet filter drawer.
|
||||
*/
|
||||
export const getBalanceSheetFilterDrawer = createSelector(
|
||||
balanceSheetFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve whether trial balance sheet display filter drawer.
|
||||
*/
|
||||
export const getTrialBalanceSheetFilterDrawer = createSelector(
|
||||
trialBalanceFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve profit/loss filter drawer.
|
||||
*/
|
||||
export const getProfitLossFilterDrawer = createSelector(
|
||||
profitLossSheetFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve whether display general ledger (GL) filter drawer.
|
||||
*/
|
||||
export const getGeneralLedgerFilterDrawer = createSelector(
|
||||
generalLedgerFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve whether display journal sheet filter drawer.
|
||||
*/
|
||||
export const getJournalFilterDrawer = createSelector(
|
||||
journalFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve whether display AR aging summary drawer filter.
|
||||
*/
|
||||
export const getARAgingSummaryFilterDrawer = createSelector(
|
||||
ARAgingSummaryFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve whether display AR aging summary drawer filter.
|
||||
*/
|
||||
export const getAPAgingSummaryFilterDrawer = createSelector(
|
||||
APAgingSummaryFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve financial statement query by the given sheet index.
|
||||
*/
|
||||
export const getFinancialSheetQueryFactory = (sheetType) =>
|
||||
createSelector(sheetByTypeSelector(sheetType), (sheet) => {
|
||||
return sheet && sheet.query ? sheet.query : {};
|
||||
});
|
||||
|
||||
/**
|
||||
* Retrieve whether purchases by items display filter drawer.
|
||||
*/
|
||||
export const getPurchasesByItemsFilterDrawer = createSelector(
|
||||
purchasesByItemsFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve whether sales by items display filter drawer.
|
||||
*/
|
||||
export const getSalesByItemsFilterDrawer = createSelector(
|
||||
salesByItemsFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve whether sells by items display filter drawer.
|
||||
*/
|
||||
export const getInventoryValuationFilterDrawer = createSelector(
|
||||
inventoryValuationFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve customers balance summary filter drawer.
|
||||
*/
|
||||
export const getCustomersBalanceSummaryFilterDrawer = createSelector(
|
||||
customerBalanceSummaryFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
/**
|
||||
* Retrieve vendors balance summary filter drawer.
|
||||
*/
|
||||
export const getVendorsBalanceSummaryFilterDrawer = createSelector(
|
||||
vendorsBalanceSummaryFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve customers transactions filter drawer.
|
||||
*/
|
||||
export const getCustomersTransactionsFilterDrawer = createSelector(
|
||||
customersTransactionsFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve vendors transactions filter drawer.
|
||||
*/
|
||||
export const getVendorsTransactionsFilterDrawer = createSelector(
|
||||
vendorsTransactionsFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve cash flow statement filter drawer.
|
||||
*/
|
||||
export const getCashFlowStatementFilterDrawer = createSelector(
|
||||
cashFlowStatementFilterDrawerSelector,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve inventory item details filter drawer.
|
||||
*/
|
||||
export const getInventoryItemDetailsFilterDrawer = createSelector(
|
||||
inventoryItemDetailsDrawerFilter,
|
||||
(isOpen) => {
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
19
src/store/financialStatement/financialStatements.types.js
Normal file
19
src/store/financialStatement/financialStatements.types.js
Normal file
@@ -0,0 +1,19 @@
|
||||
export default {
|
||||
BALANCE_SHEET: 'BALANCE_SHEET',
|
||||
TRIAL_BALANCE_SHEET: 'TRIAL_BALANCE_SHEET',
|
||||
JOURNAL: 'JOURNAL',
|
||||
GENERAL_LEDGER: 'GENERAL_LEDGER',
|
||||
PROFIT_LOSS: 'PROFIT_LOSS',
|
||||
AR_AGING_SUMMARY: 'AR_AGING_SUMMARY',
|
||||
AP_AGING_SUMMARY: 'AP_AGING_SUMMARY',
|
||||
DISPLAY_FILTER_DRAWER_TOGGLE: 'DISPLAY_FILTER_DRAWER_TOGGLE',
|
||||
PURCHASES_BY_ITEMS: 'PURCHASES_BY_ITEMS',
|
||||
SALES_BY_ITEMS: 'SALES_BY_ITEMS',
|
||||
INVENTORY_VALUATION: 'INVENTORY_VALUATION',
|
||||
CUSTOMERS_BALANCE_SUMMARY: 'CUSTOMERS BALANCE SUMMARY',
|
||||
VENDORS_BALANCE_SUMMARY: 'VENDORS BALANCE SUMMARY',
|
||||
CUSTOMERS_TRANSACTIONS: 'CUSTOMERS TRANSACTIONS',
|
||||
VENDORS_TRANSACTIONS: 'VENDORS TRANSACTIONS',
|
||||
CASH_FLOW_STATEMENT: 'CASH FLOW STATEMENT',
|
||||
INVENTORY_ITEM_DETAILS: 'INVENTORY ITEM DETAILS',
|
||||
};
|
||||
10
src/store/globalErrors/globalErrors.actions.js
Normal file
10
src/store/globalErrors/globalErrors.actions.js
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
export const setGlobalErrors = (errors) => {
|
||||
return {
|
||||
type: 'GLOBAL_ERRORS_SET',
|
||||
payload: {
|
||||
errors,
|
||||
},
|
||||
};
|
||||
}
|
||||
17
src/store/globalErrors/globalErrors.reducer.js
Normal file
17
src/store/globalErrors/globalErrors.reducer.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import t from 'store/types';
|
||||
|
||||
const initialState = {
|
||||
data: {},
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
['GLOBAL_ERRORS_SET']: (state, action) => {
|
||||
const { errors } = action.payload;
|
||||
|
||||
state.data = {
|
||||
...state.data,
|
||||
...errors,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import t from 'store/types';
|
||||
|
||||
/**
|
||||
* Sets the inventory adjustments table state.
|
||||
*/
|
||||
export const setInventoryAdjustmentsTableState = (queries) => {
|
||||
return {
|
||||
type: t.INVENTORY_ADJUSTMENTS_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import { createTableStateReducers } from 'store/tableState.reducer';
|
||||
import t from 'store/types';
|
||||
|
||||
const initialState = {
|
||||
tableState: {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
sortBy: [],
|
||||
},
|
||||
selectedRows: [],
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:inventoryAdjustments';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: ['tableState'],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('INVENTORY_ADJUSTMENTS'),
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
},
|
||||
});
|
||||
|
||||
export default persistReducer(CONFIG, reducerInstance);
|
||||
@@ -0,0 +1,22 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import {
|
||||
paginationLocationQuery,
|
||||
} from 'store/selectors';
|
||||
|
||||
const inventoryAdjustmentTableState = (state) =>
|
||||
state.inventoryAdjustments.tableState;
|
||||
|
||||
/**
|
||||
* Retrieve the inventory adjustments table state.
|
||||
*/
|
||||
export const getInventroyAdjsTableStateFactory = () =>
|
||||
createSelector(
|
||||
paginationLocationQuery,
|
||||
inventoryAdjustmentTableState,
|
||||
(locationQuery, tableQuery) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableQuery,
|
||||
};
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
export default {
|
||||
INVENTORY_ADJUSTMENTS_TABLE_STATE_SET: 'INVENTORY_ADJUSTMENTS/TABLE_STATE_SET',
|
||||
};
|
||||
19
src/store/itemCategories/ItemsCategories.selectors.js
Normal file
19
src/store/itemCategories/ItemsCategories.selectors.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
|
||||
// Items categories table state.
|
||||
const itemsCategoriesTableStateSelector = (state) =>
|
||||
state.itemsCategories.tableState;
|
||||
|
||||
// Get items categories table state marged with location query.
|
||||
export const getItemsCategoriesTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
itemsCategoriesTableStateSelector,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
11
src/store/itemCategories/itemsCategory.actions.js
Normal file
11
src/store/itemCategories/itemsCategory.actions.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import t from 'store/types';
|
||||
|
||||
/**
|
||||
* Sets the items categories table state.
|
||||
*/
|
||||
export const setItemsCategoriesTableState = (queries) => {
|
||||
return {
|
||||
type: t.ITEMS_CATEGORIES_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
35
src/store/itemCategories/itemsCategory.reducer.js
Normal file
35
src/store/itemCategories/itemsCategory.reducer.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import {
|
||||
createTableStateReducers,
|
||||
} from 'store/tableState.reducer';
|
||||
import t from 'store/types';
|
||||
|
||||
// Initial state.
|
||||
const initialState = {
|
||||
tableState: {
|
||||
filterRoles: []
|
||||
},
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:itemCategories';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('ITEMS_CATEGORIES'),
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
},
|
||||
});
|
||||
|
||||
export default persistReducer(
|
||||
CONFIG,
|
||||
reducerInstance,
|
||||
);
|
||||
3
src/store/itemCategories/itemsCategory.type.js
Normal file
3
src/store/itemCategories/itemsCategory.type.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export default {
|
||||
ITEMS_CATEGORIES_TABLE_STATE_SET: 'ITEMS_CATEGORIES/TABLE_STATE_SET',
|
||||
};
|
||||
38
src/store/itemCategories/itemsCateory.reducer.js
Normal file
38
src/store/itemCategories/itemsCateory.reducer.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import t from 'store/types';
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
|
||||
const initialState = {
|
||||
tableState: {
|
||||
filterRoles: [],
|
||||
},
|
||||
categories: {},
|
||||
loading: false,
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
[t.ITEMS_CATEGORY_LIST_SET]: (state, action) => {
|
||||
const _categories = {};
|
||||
|
||||
action.categories.forEach(category => {
|
||||
_categories[category.id] = category;
|
||||
});
|
||||
state.categories = {
|
||||
...state.categories,
|
||||
..._categories
|
||||
};
|
||||
},
|
||||
|
||||
[t.CATEGORY_DELETE]: (state, action) => {
|
||||
const { id } = action.payload;
|
||||
const categories = { ...state.categories };
|
||||
|
||||
if (typeof categories[id] !== 'undefined') {
|
||||
delete categories[id];
|
||||
state.categories = categories;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const getCategoryId = (state, id) => {
|
||||
return state.itemCategories.categories[id] || {};
|
||||
};
|
||||
17
src/store/items/items.actions.js
Normal file
17
src/store/items/items.actions.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export const setItemsTableState = (queries) => {
|
||||
return {
|
||||
type: t.ITEMS_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
export const resetItemsTableState = () => {
|
||||
return {
|
||||
type: t.ITEMS_TABLE_STATE_RESET,
|
||||
};
|
||||
}
|
||||
|
||||
export const setSelectedRowsItems = () => {};
|
||||
39
src/store/items/items.reducer.js
Normal file
39
src/store/items/items.reducer.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import { createTableStateReducers } from 'store/tableState.reducer';
|
||||
import t from 'store/types';
|
||||
|
||||
export const defaultTableQuery = {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
filterRoles: [],
|
||||
inactiveMode: false,
|
||||
viewSlug: null,
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
tableState: defaultTableQuery,
|
||||
selectedRows: [],
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:items';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('ITEMS', defaultTableQuery),
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
},
|
||||
});
|
||||
|
||||
export default persistReducer(
|
||||
CONFIG,
|
||||
reducerInstance,
|
||||
);
|
||||
25
src/store/items/items.selectors.js
Normal file
25
src/store/items/items.selectors.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
import { defaultTableQuery } from './items.reducer';
|
||||
|
||||
const itemsTableStateSelector = (state) => state.items.tableState;
|
||||
|
||||
// Get items table state marged with location query.
|
||||
export const getItemsTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
itemsTableStateSelector,
|
||||
(locationQuery, tableState) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableState,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const isItemsTableStateChangedFactory = () =>
|
||||
createDeepEqualSelector(itemsTableStateSelector, (tableState) => {
|
||||
return !isEqual(tableState, defaultTableQuery);
|
||||
});
|
||||
5
src/store/items/items.types.js
Normal file
5
src/store/items/items.types.js
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
export default {
|
||||
ITEMS_TABLE_STATE_SET: 'ITEMS/TABLE_STATE_SET',
|
||||
ITEMS_TABLE_STATE_RESET: 'ITEMS/TABLE_STATE_RESET',
|
||||
};
|
||||
47
src/store/journalNumber.reducer.js
Normal file
47
src/store/journalNumber.reducer.js
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
export const journalNumberChangedReducer = (type) => ({
|
||||
[type]: (state, action) => {
|
||||
const { isChanged } = action.payload;
|
||||
state.journalNumberChanged = isChanged;
|
||||
},
|
||||
});
|
||||
|
||||
export const viewPaginationSetReducer = (type) => ({
|
||||
[type]: (state, action) => {
|
||||
const { pagination, customViewId } = action.payload;
|
||||
|
||||
const mapped = {
|
||||
pageSize: parseInt(pagination.page_size, 10),
|
||||
page: parseInt(pagination.page, 10),
|
||||
total: parseInt(pagination.total, 10),
|
||||
};
|
||||
const paginationMeta = {
|
||||
...mapped,
|
||||
pagesCount: Math.ceil(mapped.total / mapped.pageSize),
|
||||
pageIndex: Math.max(mapped.page - 1, 0),
|
||||
};
|
||||
state.views = {
|
||||
...state.views,
|
||||
[customViewId]: {
|
||||
...(state.views?.[customViewId] || {}),
|
||||
paginationMeta,
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const createTableQueryReducers = (RESOURCE_NAME) => ({
|
||||
[`${RESOURCE_NAME}/TABLE_QUERY_SET`]: (state, action) => {
|
||||
state.tableQuery = {
|
||||
...state.tableQuery,
|
||||
[state.key]: action.payload.value,
|
||||
};
|
||||
},
|
||||
|
||||
[`${RESOURCE_NAME}/TABLE_QUERIES_ADD`]: (state, action) => {
|
||||
state.tableQuery = {
|
||||
...state.tableQuery,
|
||||
...action.payload.queries,
|
||||
};
|
||||
},
|
||||
});
|
||||
23
src/store/localStorage.js
Normal file
23
src/store/localStorage.js
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
const LOCAL_STORAGE_NAMESPACE = 'application_state';
|
||||
|
||||
export const loadState = () => {
|
||||
try {
|
||||
const serializedState = localStorage.getItem(LOCAL_STORAGE_NAMESPACE);
|
||||
if (serializedState === null) {
|
||||
return undefined;
|
||||
}
|
||||
return JSON.parse(serializedState);
|
||||
} catch(error) {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
export const saveState = (state) => {
|
||||
try {
|
||||
const serializedState = JSON.stringify(state);
|
||||
localStorage.setItem(LOCAL_STORAGE_NAMESPACE, serializedState);
|
||||
} catch (error) {
|
||||
throw new Error('Something want wrong');
|
||||
}
|
||||
}
|
||||
8
src/store/manualJournals/manualJournals.actions.js
Normal file
8
src/store/manualJournals/manualJournals.actions.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export const setManualJournalsTableState = (queries) => {
|
||||
return {
|
||||
type: t.MANUAL_JOURNALS_TABLE_STATE_SET,
|
||||
payload: { queries },
|
||||
};
|
||||
};
|
||||
34
src/store/manualJournals/manualJournals.reducers.js
Normal file
34
src/store/manualJournals/manualJournals.reducers.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { persistReducer, purgeStoredState } from 'redux-persist';
|
||||
import storage from 'redux-persist/lib/storage';
|
||||
import { createTableStateReducers } from 'store/tableState.reducer';
|
||||
import t from 'store/types';
|
||||
|
||||
export const defaultTableQuery = {
|
||||
pageSize: 12,
|
||||
pageIndex: 0,
|
||||
filterRoles: [],
|
||||
viewSlug: null,
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
tableState: defaultTableQuery,
|
||||
};
|
||||
|
||||
const STORAGE_KEY = 'bigcapital:manualJournals';
|
||||
|
||||
const CONFIG = {
|
||||
key: STORAGE_KEY,
|
||||
whitelist: [],
|
||||
storage,
|
||||
};
|
||||
|
||||
const reducerInstance = createReducer(initialState, {
|
||||
...createTableStateReducers('MANUAL_JOURNALS', defaultTableQuery),
|
||||
|
||||
[t.RESET]: () => {
|
||||
purgeStoredState(CONFIG);
|
||||
},
|
||||
});
|
||||
|
||||
export default persistReducer(CONFIG, reducerInstance);
|
||||
25
src/store/manualJournals/manualJournals.selectors.js
Normal file
25
src/store/manualJournals/manualJournals.selectors.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import { paginationLocationQuery } from 'store/selectors';
|
||||
import { createDeepEqualSelector } from 'utils';
|
||||
import { defaultTableQuery } from './manualJournals.reducers';
|
||||
|
||||
const manualJournalsTableState = (state) => state.manualJournals.tableState;
|
||||
|
||||
// Retrieve manual jouranls table state.
|
||||
export const getManualJournalsTableStateFactory = () =>
|
||||
createDeepEqualSelector(
|
||||
paginationLocationQuery,
|
||||
manualJournalsTableState,
|
||||
(locationQuery, tableQuery) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableQuery,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const manualJournalTableStateChangedFactory = () =>
|
||||
createDeepEqualSelector(manualJournalsTableState, (tableState) => {
|
||||
return !isEqual(tableState, defaultTableQuery);
|
||||
});
|
||||
4
src/store/manualJournals/manualJournals.types.js
Normal file
4
src/store/manualJournals/manualJournals.types.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
MANUAL_JOURNALS_TABLE_STATE_SET: 'MANUAL_JOURNALS/TABLE_STATE_SET',
|
||||
MANUAL_JOURNALS_TABLE_STATE_RESET: 'MANUAL_JOURNALS/TABLE_STATE_RESET',
|
||||
};
|
||||
13
src/store/media/media.actions.js
Normal file
13
src/store/media/media.actions.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import ApiService from "services/ApiService"
|
||||
|
||||
export const submitMedia = ({ form, config }) => {
|
||||
return (dispatch) => {
|
||||
return ApiService.post('media/upload', form, config);
|
||||
};
|
||||
};
|
||||
|
||||
export const deleteMedia = ({ ids }) => {
|
||||
return (dispatch) => {
|
||||
return ApiService.delete('media', { params: { ids } });
|
||||
}
|
||||
};
|
||||
0
src/store/media/media.reducers.js
Normal file
0
src/store/media/media.reducers.js
Normal file
0
src/store/media/media.types.js
Normal file
0
src/store/media/media.types.js
Normal file
41
src/store/organizations/organizations.actions.js
Normal file
41
src/store/organizations/organizations.actions.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import ApiService from 'services/ApiService';
|
||||
import t from 'store/types';
|
||||
|
||||
export const setOrganizations = (organizations) => {
|
||||
return {
|
||||
type: t.ORGANIZATIONS_LIST_SET,
|
||||
payload: {
|
||||
organizations,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchOrganizations = () => (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.get('organization/all')
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
type: t.ORGANIZATIONS_LIST_SET,
|
||||
payload: {
|
||||
organizations: response.data.organizations,
|
||||
},
|
||||
});
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
export const setOrganizationSetupCompleted =
|
||||
(congrats) => (dispatch, getState) => {
|
||||
const tenantId = getState().authentication.tenantId;
|
||||
|
||||
dispatch({
|
||||
type: t.SET_ORGANIZATION_CONGRATS,
|
||||
payload: {
|
||||
tenantId,
|
||||
congrats,
|
||||
},
|
||||
});
|
||||
};
|
||||
39
src/store/organizations/organizations.reducers.js
Normal file
39
src/store/organizations/organizations.reducers.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { omit } from 'lodash';
|
||||
import t from 'store/types';
|
||||
|
||||
const initialState = {
|
||||
data: {},
|
||||
byOrganizationId: {},
|
||||
};
|
||||
|
||||
const reducer = createReducer(initialState, {
|
||||
|
||||
[t.ORGANIZATIONS_LIST_SET]: (state, action) => {
|
||||
const { organizations } = action.payload;
|
||||
const _data = {};
|
||||
const _dataByOrganizationId = {};
|
||||
|
||||
organizations.forEach((organization) => {
|
||||
_data[organization.id] = {
|
||||
...state.data[organization.id],
|
||||
...organization.metadata,
|
||||
...omit(organization, ['metadata']),
|
||||
};
|
||||
_dataByOrganizationId[organization.organization_id] = organization.id;
|
||||
});
|
||||
state.data = _data;
|
||||
state.byOrganizationId = _dataByOrganizationId;
|
||||
},
|
||||
|
||||
[t.SET_ORGANIZATION_CONGRATS]: (state, action) => {
|
||||
const { tenantId, congrats } = action.payload;
|
||||
|
||||
state.data[tenantId] = {
|
||||
...(state.data[tenantId] || {}),
|
||||
is_congrats: !!congrats,
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
export default reducer;
|
||||
39
src/store/organizations/organizations.selectors.js
Normal file
39
src/store/organizations/organizations.selectors.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
|
||||
const organizationSelector = (state, props) => {
|
||||
const tenantId = state.organizations.byOrganizationId[props.organizationId];
|
||||
return state.organizations.data[tenantId];
|
||||
};
|
||||
|
||||
export const getOrganizationByIdFactory = () =>
|
||||
createSelector(organizationSelector, (organization) => organization);
|
||||
|
||||
export const isOrganizationSeededFactory = () =>
|
||||
createSelector(organizationSelector, (organization) => {
|
||||
return !!organization?.seeded_at;
|
||||
});
|
||||
|
||||
export const isOrganizationBuiltFactory = () =>
|
||||
createSelector(organizationSelector, (organization) => {
|
||||
return !!organization?.initialized_at;
|
||||
});
|
||||
|
||||
export const isOrganizationReadyFactory = () =>
|
||||
createSelector(organizationSelector, (organization) => {
|
||||
return organization?.is_ready;
|
||||
});
|
||||
|
||||
export const isOrganizationSubscribedFactory = () =>
|
||||
createSelector(organizationSelector, (organization) => {
|
||||
return organization?.subscriptions?.length > 0;
|
||||
});
|
||||
|
||||
export const isOrganizationCongratsFactory = () =>
|
||||
createSelector(organizationSelector, (organization) => {
|
||||
return !!organization?.is_congrats;
|
||||
});
|
||||
|
||||
export const isOrganizationBuildRunningFactory = () =>
|
||||
createSelector(organizationSelector, (organization) => {
|
||||
return !!organization?.is_build_running;
|
||||
});
|
||||
7
src/store/organizations/organizations.types.js
Normal file
7
src/store/organizations/organizations.types.js
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
export default {
|
||||
ORGANIZATION_SET: 'ORGANIZATION_SET',
|
||||
ORGANIZATIONS_LIST_SET: 'ORGANIZATIONS_LIST_SET',
|
||||
SET_ORGANIZATION_CONGRATS: 'SET_ORGANIZATION_CONGRATS',
|
||||
ORGANIZATION_MUTATE_BASE_CURRENCY_ABILITIES: 'ORGANIZATION_MUTATE_BASE_CURRENCY_ABILITIES'
|
||||
};
|
||||
33
src/store/organizations/withSetupWizard.js
Normal file
33
src/store/organizations/withSetupWizard.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
export default (mapState) => {
|
||||
const mapStateToProps = (state, props) => {
|
||||
const {
|
||||
isOrganizationSetupCompleted,
|
||||
isOrganizationReady,
|
||||
isSubscriptionActive,
|
||||
isOrganizationBuildRunning
|
||||
} = props;
|
||||
|
||||
const condits = {
|
||||
isCongratsStep: isOrganizationSetupCompleted,
|
||||
isSubscriptionStep: !isSubscriptionActive,
|
||||
isInitializingStep: isOrganizationBuildRunning,
|
||||
isOrganizationStep: !isOrganizationReady && !isOrganizationBuildRunning,
|
||||
};
|
||||
const scenarios = [
|
||||
{ condition: condits.isSubscriptionStep, step: 'subscription' },
|
||||
{ condition: condits.isOrganizationStep, step: 'organization' },
|
||||
{ condition: condits.isInitializingStep, step: 'initializing' },
|
||||
{ condition: condits.isCongratsStep, step: 'congrats' },
|
||||
];
|
||||
const setupStep = scenarios.find((scenario) => scenario.condition);
|
||||
const mapped = {
|
||||
...condits,
|
||||
setupStepId: setupStep?.step,
|
||||
setupStepIndex: scenarios.indexOf(setupStep) + 1,
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
return connect(mapStateToProps);
|
||||
};
|
||||
0
src/store/paginator.reducer.js
Normal file
0
src/store/paginator.reducer.js
Normal file
5
src/store/plans/plans.actions.js
Normal file
5
src/store/plans/plans.actions.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import t from 'store/types';
|
||||
|
||||
export const initSubscriptionPlans = () => ({
|
||||
type: t.INIT_SUBSCRIPTION_PLANS
|
||||
});
|
||||
112
src/store/plans/plans.reducer.js
Normal file
112
src/store/plans/plans.reducer.js
Normal file
@@ -0,0 +1,112 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import intl from 'react-intl-universal';
|
||||
import t from 'store/types';
|
||||
|
||||
|
||||
const getSubscriptionPeriods = () => [
|
||||
{
|
||||
slug: 'month',
|
||||
label: intl.get('plan.monthly'),
|
||||
},
|
||||
{
|
||||
slug: 'year',
|
||||
label: intl.get('plan.yearly'),
|
||||
},
|
||||
];
|
||||
|
||||
const getSubscriptionPlans = () => [
|
||||
{
|
||||
name: intl.get('plan.essential.title'),
|
||||
slug: 'essentials',
|
||||
description: [
|
||||
intl.get('plan.feature.sale_purchase_invoice'),
|
||||
intl.get('plan.feature.receivable_payable_accounts'),
|
||||
intl.get('plan.feature.expenses_tracking'),
|
||||
intl.get('plan.feature.manual_journal'),
|
||||
intl.get('plan.feature.financial_reports'),
|
||||
intl.get('plan.feature.one_user_with_accountant'),
|
||||
],
|
||||
price: '100',
|
||||
periods: [
|
||||
{
|
||||
slug: 'month',
|
||||
label: intl.get('plan.monthly'),
|
||||
price: '100'
|
||||
},
|
||||
{
|
||||
slug: 'year',
|
||||
label: intl.get('plan.yearly'),
|
||||
price: '1,200',
|
||||
},
|
||||
],
|
||||
currencyCode: 'LYD',
|
||||
},
|
||||
{
|
||||
name: intl.get('plan.professional.title'),
|
||||
slug: 'plus',
|
||||
description: [
|
||||
intl.get('plan.feature.all_capital_essential'),
|
||||
intl.get('plan.feature.multi_currency'),
|
||||
intl.get('plan.feature.purchase_sell_orders'),
|
||||
intl.get('plan.feature.multi_inventory_managment'),
|
||||
intl.get('plan.feature.three_users'),
|
||||
intl.get('plan.feature.advanced_financial_reports'),
|
||||
],
|
||||
price: '200',
|
||||
currencyCode: 'LYD',
|
||||
periods: [
|
||||
{
|
||||
slug: 'month',
|
||||
label: intl.get('plan.monthly'),
|
||||
price: '200'
|
||||
},
|
||||
{
|
||||
slug: 'year',
|
||||
label: intl.get('plan.yearly'),
|
||||
price: '1,200',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: intl.get('plan.plus.title'),
|
||||
slug: 'enterprise',
|
||||
description: [
|
||||
intl.get('plan.feture.all_capital_professional_features'),
|
||||
intl.get('plan.feature.tracking_multi_locations'),
|
||||
intl.get('plan.feature.projects_accounting'),
|
||||
intl.get('plan.feature.accounting_dimensions'),
|
||||
],
|
||||
price: '300',
|
||||
currencyCode: 'LYD',
|
||||
periods: [
|
||||
{
|
||||
slug: 'month',
|
||||
label: intl.get('plan.monthly'),
|
||||
price: '300'
|
||||
},
|
||||
{
|
||||
slug: 'year',
|
||||
label: intl.get('plan.yearly'),
|
||||
price: '1,200',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const initialState = {
|
||||
plans: [],
|
||||
periods: [],
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
/**
|
||||
* Initialize the subscription plans.
|
||||
*/
|
||||
[t.INIT_SUBSCRIPTION_PLANS]: (state) => {
|
||||
const plans = getSubscriptionPlans();
|
||||
const periods = getSubscriptionPeriods();
|
||||
|
||||
state.plans = plans;
|
||||
state.periods = periods;
|
||||
},
|
||||
});
|
||||
19
src/store/plans/plans.selectors.js
Normal file
19
src/store/plans/plans.selectors.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
const plansSelector = (state) => state.plans.plans;
|
||||
const planSelector = (state, props) => state.plans.plans
|
||||
.find((plan) => plan.slug === props.planSlug);
|
||||
|
||||
// Retrieve manual jounral current page results.
|
||||
export const getPlansSelector = () => createSelector(
|
||||
plansSelector,
|
||||
(plans) => {
|
||||
return plans;
|
||||
},
|
||||
);
|
||||
|
||||
// Retrieve plan details.
|
||||
export const getPlanSelector = () => createSelector(
|
||||
planSelector,
|
||||
(plan) => plan,
|
||||
)
|
||||
4
src/store/plans/plans.types.js
Normal file
4
src/store/plans/plans.types.js
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
export default {
|
||||
INIT_SUBSCRIPTION_PLANS: 'INIT_SUBSCRIPTION_PLANS',
|
||||
};
|
||||
26
src/store/preferences/preferences.actions.js
Normal file
26
src/store/preferences/preferences.actions.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import ApiService from "services/ApiService";
|
||||
import t from 'store/types';
|
||||
|
||||
export const savePreferences = ({ options }) => {
|
||||
return (dispatch) => new Promise((resolve, reject) => {
|
||||
ApiService.post('options', { options }).then((response) => {
|
||||
dispatch({
|
||||
type: t.OPTIONS_SET,
|
||||
options: response.data.options,
|
||||
});
|
||||
resolve(response);
|
||||
}).catch(error => { reject(error); });
|
||||
});
|
||||
};
|
||||
|
||||
export const fetchPreferences = () => {
|
||||
return (dispatch) => new Promise((resolve, reject) => {
|
||||
ApiService.get('options').then((response) => {
|
||||
dispatch({
|
||||
type: t.OPTIONS.SET,
|
||||
options: response.data.options,
|
||||
});
|
||||
resolve(response);
|
||||
}).catch(error => { reject(error); });
|
||||
})
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user