chrone: sperate client and server to different repos.

This commit is contained in:
a.bouhuolia
2021-09-21 17:13:53 +02:00
parent e011b2a82b
commit 18df5530c7
10015 changed files with 17686 additions and 97524 deletions

View File

@@ -0,0 +1,135 @@
import React from 'react';
import { debounce } from 'lodash';
import { isUndefined } from 'lodash';
import { useUniversalSearch } from 'hooks/query';
import { UniversalSearch } from 'components';
import { RESOURCES_TYPES } from 'common/resourcesTypes';
import { compose } from 'utils';
import withUniversalSearchActions from './withUniversalSearchActions';
import withUniversalSearch from './withUniversalSearch';
import DashboardUniversalSearchItemActions from './DashboardUniversalSearchItemActions';
import { DashboardUniversalSearchItem } from './components';
import DashboardUniversalSearchHotkeys from './DashboardUniversalSearchHotkeys';
import { getUniversalSearchTypeOptions } from './utils';
/**
* Dashboard universal search.
*/
function DashboardUniversalSearch({
// #withUniversalSearchActions
setSelectedItemUniversalSearch,
// #withUniversalSearch
globalSearchShow,
closeGlobalSearch,
defaultUniversalResourceType,
}) {
// Search keyword.
const [searchKeyword, setSearchKeyword] = React.useState('');
// Default search type.
const [defaultSearchType, setDefaultSearchType] = React.useState(
defaultUniversalResourceType || RESOURCES_TYPES.CUSTOMR,
);
// Search type.
const [searchType, setSearchType] = React.useState(defaultSearchType);
// Sync default search type with default universal resource type.
React.useEffect(() => {
if (
!isUndefined(defaultUniversalResourceType) &&
defaultSearchType !== defaultUniversalResourceType
) {
setSearchType(defaultUniversalResourceType);
setDefaultSearchType(defaultUniversalResourceType);
}
}, [defaultSearchType, defaultUniversalResourceType]);
// Fetch accounts list according to the given custom view id.
const {
data,
remove,
isFetching: isSearchFetching,
isLoading: isSearchLoading,
refetch,
} = useUniversalSearch(searchType, searchKeyword, {
keepPreviousData: true,
enabled: false,
});
// Handle query change.
const handleQueryChange = (query) => {
setSearchKeyword(query);
};
// Handle search type change.
const handleSearchTypeChange = (type) => {
remove();
setSearchType(type.key);
};
// Handle overlay of universal search close.
const handleClose = () => {
closeGlobalSearch();
};
// Handle universal search item select.
const handleItemSelect = (item) => {
setSelectedItemUniversalSearch(searchType, item.id);
closeGlobalSearch();
setSearchKeyword('');
};
const debounceFetch = React.useRef(
debounce(() => {
refetch();
}, 200),
);
React.useEffect(() => {
if (searchKeyword && searchType) {
debounceFetch.current();
}
}, [searchKeyword, searchType]);
// Handles the overlay once be closed.
const handleOverlayClosed = () => {
setSearchKeyword('');
};
const searchTypeOptions = React.useMemo(
() => getUniversalSearchTypeOptions(),
[],
);
return (
<div class="dashboard__universal-search">
<UniversalSearch
isOpen={globalSearchShow}
isLoading={isSearchFetching}
items={data}
overlayProps={{
onClose: handleClose,
onClosed: handleOverlayClosed,
}}
searchResource={searchType}
onQueryChange={handleQueryChange}
onSearchTypeChange={handleSearchTypeChange}
onItemSelect={handleItemSelect}
itemRenderer={DashboardUniversalSearchItem}
query={searchKeyword}
searchTypeOptions={searchTypeOptions}
/>
<DashboardUniversalSearchItemActions />
<DashboardUniversalSearchHotkeys />
</div>
);
}
export default compose(
withUniversalSearchActions,
withUniversalSearch(({ globalSearchShow, defaultUniversalResourceType }) => ({
globalSearchShow,
defaultUniversalResourceType,
})),
)(DashboardUniversalSearch);

View File

@@ -0,0 +1,26 @@
import { universalSearchInvoiceBind } from '../Sales/Invoices/InvoiceUniversalSearch';
import { universalSearchReceiptBind } from '../Sales/Receipts/ReceiptUniversalSearch';
import { universalSearchBillBind } from '../Purchases/Bills/BillUniversalSearch';
import { universalSearchEstimateBind } from '../Sales/Estimates/EstimatesLanding/EstimateUniversalSearch';
import { universalSearchPaymentReceiveBind } from '../Sales/PaymentReceives/PaymentReceiveUniversalSearch';
import { universalSearchPaymentMadeBind } from '../Purchases/PaymentMades/PaymentMadeUniversalSearch';
import { universalSearchItemBind } from '../Items/ItemsUniversalSearch';
import { universalSearchCustomerBind } from '../Customers/CustomersUniversalSearch';
import { universalSearchJournalBind } from '../Accounting/ManualJournalUniversalSearch';
import { universalSearchAccountBind } from '../Accounts/AccountUniversalSearch';
import { universalSearchVendorBind } from '../Vendors/VendorsUniversalSearch';
// Universal search binds.
export const universalSearchBinds = [
universalSearchItemBind,
universalSearchAccountBind,
universalSearchInvoiceBind,
universalSearchReceiptBind,
universalSearchEstimateBind,
universalSearchBillBind,
universalSearchPaymentReceiveBind,
universalSearchPaymentMadeBind,
universalSearchCustomerBind,
universalSearchVendorBind,
universalSearchJournalBind,
];

View File

@@ -0,0 +1,21 @@
import * as R from 'ramda';
import { useHotkeys } from 'react-hotkeys-hook';
import withUniversalSearchActions from './withUniversalSearchActions';
/**
* Universal search hotkey.
*/
function DashboardUniversalSearchHotkey({
openGlobalSearch,
}) {
useHotkeys('shift+p', (event, handle) => {
openGlobalSearch();
});
return null;
}
export default R.compose(
withUniversalSearchActions
)(DashboardUniversalSearchHotkey);

View File

@@ -0,0 +1,43 @@
import React from 'react';
import * as R from 'ramda';
import withUniversalSearch from './withUniversalSearch';
import { getUniversalSearchItemsActions } from './utils';
import withUniversalSearchActions from './withUniversalSearchActions';
/**
* Universal search selected item action based on each resource type.
*/
function DashboardUniversalSearchItemActions({
searchSelectedResourceType,
searchSelectedResourceId,
// #with
resetSelectedItemUniversalSearch,
}) {
const components = getUniversalSearchItemsActions();
// Handle action execuation.
const handleActionExec = React.useCallback(() => {
resetSelectedItemUniversalSearch();
}, [resetSelectedItemUniversalSearch]);
return components.map((COMPONENT) => (
<COMPONENT
resourceId={searchSelectedResourceId}
resourceType={searchSelectedResourceType}
onAction={handleActionExec}
/>
));
}
export default R.compose(
withUniversalSearch(
({ searchSelectedResourceType, searchSelectedResourceId }) => ({
searchSelectedResourceType,
searchSelectedResourceId,
}),
),
withUniversalSearchActions,
)(DashboardUniversalSearchItemActions);

View File

@@ -0,0 +1,44 @@
import React from 'react';
import { MenuItem } from '@blueprintjs/core';
import { highlightText } from 'utils';
import { getUniversalSearchBind } from './utils';
/**
* Default univesal search item component.
*/
function UniversalSearchItemDetail(item, { handleClick, modifiers, query }) {
return (
<MenuItem
active={modifiers.active}
disabled={modifiers.disabled}
text={
<div>
<div>{highlightText(item.text, query)}</div>
{item.subText && (
<span class="bp3-text-muted">
{highlightText(item.subText, query)}
</span>
)}
</div>
}
label={item.label ? highlightText(item.label, query) : ''}
onClick={handleClick}
/>
);
}
/**
*
* @param {*} props
* @param {*} actions
* @returns
*/
export const DashboardUniversalSearchItem = (props, actions) => {
const itemRenderer = getUniversalSearchBind(props._type, 'itemRenderer');
return typeof itemRenderer !== 'undefined'
? itemRenderer(props, actions)
: UniversalSearchItemDetail(props, actions);
};

View File

@@ -0,0 +1,44 @@
import { get } from 'lodash';
import { universalSearchBinds } from './DashboardUniversalSearchBinds';
/**
*
* @returns
*/
export const getUniversalSearchBinds = () => {
return universalSearchBinds.map((binder) => binder());
};
/**
*
* @param {*} resourceType
* @param {*} key
* @returns
*/
export const getUniversalSearchBind = (resourceType, key) => {
const resourceConfig = getUniversalSearchBinds().find(
(meta) => meta.resourceType === resourceType,
);
return key ? get(resourceConfig, key) : resourceConfig;
};
/**
*
* @returns
*/
export const getUniversalSearchTypeOptions = () => {
return getUniversalSearchBinds().map((bind) => ({
key: bind.resourceType,
label: bind.optionItemLabel,
}))
}
/**
*
* @returns
*/
export const getUniversalSearchItemsActions = () => {
return getUniversalSearchBinds()
.filter((bind) => bind.selectItemAction)
.map((bind) => bind.selectItemAction);
}

View File

@@ -0,0 +1,18 @@
import { connect } from 'react-redux';
export default (mapState) => {
const mapStateToProps = (state, props) => {
const { globalSearch } = state;
const mapped = {
globalSearchShow: globalSearch.isOpen,
defaultUniversalResourceType: globalSearch.defaultResourceType,
searchSelectedResourceType: globalSearch.selectedItem.resourceType,
searchSelectedResourceId: globalSearch.selectedItem.resourceId,
};
return mapState ? mapState(mapped, state, props) : mapped;
};
return connect(mapStateToProps);
};

View File

@@ -0,0 +1,27 @@
import { connect } from 'react-redux';
import t from 'store/types';
import {
universalSearchResetResourceType,
universalSearchSetResourceType,
universalSearchSetSelectedItem,
universalSearchResetSelectedItem
} from '../../store/search/search.actions';
export const mapDispatchToProps = (dispatch) => ({
openGlobalSearch: () => dispatch({ type: t.OPEN_SEARCH }),
closeGlobalSearch: () => dispatch({ type: t.CLOSE_SEARCH }),
setResourceTypeUniversalSearch: (resourceType) =>
dispatch(universalSearchSetResourceType(resourceType)),
resetResourceTypeUniversalSearch: () =>
dispatch(universalSearchResetResourceType()),
setSelectedItemUniversalSearch: (resourceType, resourceId) =>
dispatch(universalSearchSetSelectedItem(resourceType, resourceId)),
resetSelectedItemUniversalSearch: () =>
dispatch(universalSearchResetSelectedItem()),
});
export default connect(null, mapDispatchToProps);