Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ahmed Bouhuolia
2020-10-24 12:41:24 +02:00
14 changed files with 135 additions and 76 deletions

View File

@@ -0,0 +1,49 @@
import React, { useCallback } from 'react';
import { FormattedMessage as T } from 'react-intl';
import { ListSelect } from 'components';
import { MenuItem } from '@blueprintjs/core';
export default function CategoriesSelectList({
categoriesList,
selecetedCategoryId,
defaultSelectText = <T id={'select_category'} />,
onCategorySelected,
...restProps
}) {
// Filter Items Category
const filterItemCategory = (query, item, _index, exactMatch) => {
const normalizedTitle = item.name.toLowerCase();
const normalizedQuery = query.toLowerCase();
if (exactMatch) {
return normalizedTitle === normalizedQuery;
} else {
return `${item.code} ${normalizedTitle}`.indexOf(normalizedQuery) >= 0;
}
};
const handleItemCategorySelected = useCallback(
(ItemCategory) => onCategorySelected && onCategorySelected(ItemCategory),
[],
);
const categoryItem = useCallback(
(item, { handleClick }) => (
<MenuItem key={item.id} text={item.name} onClick={handleClick} />
),
[],
);
return (
<ListSelect
items={categoriesList}
selectedItemProp={'id'}
selectedItem={selecetedCategoryId}
labelProp={'name'}
defaultText={defaultSelectText}
onItemSelect={handleItemCategorySelected}
itemPredicate={filterItemCategory}
itemRenderer={categoryItem}
{...restProps}
/>
);
}

View File

@@ -25,6 +25,8 @@ import Dialog from './Dialog/Dialog';
import DialogContent from './Dialog/DialogContent';
import DialogSuspense from './Dialog/DialogSuspense';
import InputPrependButton from './Forms/InputPrependButton';
import CategoriesSelectList from './CategoriesSelectList';
const Hint = FieldHint;
export {
@@ -55,5 +57,6 @@ export {
Dialog,
DialogContent,
DialogSuspense,
InputPrependButton
};
InputPrependButton,
CategoriesSelectList
};

View File

@@ -17,6 +17,7 @@ function Customer({
formik,
//#withCustomersActions
requestFetchCustomers,
requestFetchCustomer,
}) {
const { id } = useParams();
const history = useHistory();
@@ -26,11 +27,12 @@ function Customer({
requestFetchCustomers({}),
);
// Handle fetch customer details.
const fetchCustomer= useQuery(['customer', id], () =>
requestFetchCustomers(),
{ enabled: !!id },
const fetchCustomer = useQuery(
['customer', id],
(key, customerId) => requestFetchCustomer(customerId),
{ enabled: id && id },
);
const handleFormSubmit = useCallback(
(payload) => {
payload.redirect && history.push('/customers');

View File

@@ -1,20 +1,21 @@
import { connect } from 'react-redux';
import {
fetchCustomers,
fetchCustomer,
submitCustomer,
editCustomer,
deleteCustomer,
deleteBulkCustomers
deleteBulkCustomers,
} from 'store/customers/customers.actions';
import t from 'store/types';
export const mapDispatchToProps = (dispatch) => ({
requestFetchCustomers: (query) => dispatch(fetchCustomers({ query })),
requestDeleteCustomer: (id) => dispatch(deleteCustomer({ id })),
requestDeleteBulkCustomers:(ids)=>dispatch(deleteBulkCustomers({ids})),
requestDeleteBulkCustomers: (ids) => dispatch(deleteBulkCustomers({ ids })),
requestSubmitCustomer: (form) => dispatch(submitCustomer({ form })),
requestEditCustomer: (id, form) => dispatch(editCustomer({ id, form })),
requestFetchCustomer: (id) => dispatch(fetchCustomer({ id })),
addCustomersTableQueries: (queries) =>
dispatch({
type: t.CUSTOMERS_TABLE_QUERIES_ADD,

View File

@@ -50,6 +50,7 @@ const ItemsCategoryList = ({
(category) => (
<Menu>
<MenuItem
icon={<Icon icon="pen-18" />}
text={formatMessage({ id: 'edit_category' })}
onClick={handelEditCategory(category)}
/>

View File

@@ -23,7 +23,11 @@ import ErrorMessage from 'components/ErrorMessage';
import Icon from 'components/Icon';
import MoneyInputGroup from 'components/MoneyInputGroup';
import Dragzone from 'components/Dragzone';
import { ListSelect, AccountsSelectList, If } from 'components';
import {
ListSelect,
AccountsSelectList,
CategoriesSelectList,
} from 'components';
import withItemsActions from 'containers/Items/withItemsActions';
import withItemCategories from 'containers/Items/withItemCategories';
@@ -170,7 +174,7 @@ const ItemForm = ({
},
onSubmit: (values, { setSubmitting, resetForm, setErrors }) => {
const saveItem = (mediaIds) => {
const formValues = { ...values, media_ids: mediaIds };
const formValues = { ...values };
if (itemDetail && itemDetail.id) {
requestEditItem(itemDetail.id, formValues)
.then((response) => {
@@ -222,29 +226,6 @@ const ItemForm = ({
},
});
const accountItem = useCallback(
(item, { handleClick }) => (
<MenuItem
key={item.id}
text={item.name}
label={item.code}
onClick={handleClick}
/>
),
[],
);
// Filter Account Items
const filterAccounts = (query, item, _index, exactMatch) => {
const normalizedTitle = item.name.toLowerCase();
const normalizedQuery = query.toLowerCase();
if (exactMatch) {
return normalizedTitle === normalizedQuery;
} else {
return `${item.code} ${normalizedTitle}`.indexOf(normalizedQuery) >= 0;
}
};
const onItemAccountSelect = useCallback(
(filedName) => {
return (account) => {
@@ -254,13 +235,6 @@ const ItemForm = ({
[setFieldValue],
);
const categoryItem = useCallback(
(item, { handleClick }) => (
<MenuItem key={item.id} text={item.name} onClick={handleClick} />
),
[],
);
const requiredSpan = useMemo(() => <span class="required">*</span>, []);
const infoIcon = useMemo(() => <Icon icon="info-circle" iconSize={12} />, []);
@@ -374,17 +348,11 @@ const ItemForm = ({
Classes.FILL,
)}
>
<ListSelect
items={categoriesList}
noResults={<MenuItem disabled={true} text="No results." />}
itemRenderer={categoryItem}
itemPredicate={filterAccounts}
<CategoriesSelectList
categoriesList={categoriesList}
selecetedCategoryId={values.category_id}
onCategorySelected={onItemAccountSelect('category_id')}
popoverProps={{ minimal: true }}
onItemSelect={onItemAccountSelect('category_id')}
selectedItem={values.customer_id}
selectedItemProp={'id'}
defaultText={<T id={'select_category'} />}
labelProp={'name'}
/>
</FormGroup>

View File

@@ -40,11 +40,8 @@ const ItemFormContainer = ({
const fetchItemDetail = useQuery(
['item', id],
(key, _id) => requestFetchItem(_id),
{
enabled: !!id,
},
{ enabled: id && id },
);
const handleFormSubmit = useCallback(
(payload) => {
payload.redirect && history.push('/items');

View File

@@ -9,9 +9,7 @@ import {
Intent,
} from '@blueprintjs/core';
import { FormattedMessage as T, useIntl } from 'react-intl';
import DataTable from 'components/DataTable';
import Icon from 'components/Icon';
import Money from 'components/Money';
import { Icon, DataTable, Money, If, Choose } from 'components';
import LoadingIndicator from 'components/LoadingIndicator';
import withItems from 'containers/Items/withItems';
@@ -56,14 +54,19 @@ const ItemsDataTable = ({
const actionMenuList = useCallback(
(item) => (
<Menu>
<MenuItem text={formatMessage({ id: 'view_details' })} />
<MenuItem
icon={<Icon icon="reader-18" />}
text={formatMessage({ id: 'view_details' })}
/>
<MenuDivider />
<MenuItem
icon={<Icon icon="pen-18" />}
text={formatMessage({ id: 'edit_item' })}
onClick={handleEditItem(item)}
/>
<MenuItem
text={formatMessage({ id: 'delete_item' })}
icon={<Icon icon="trash-16" iconSize={16} />}
onClick={handleDeleteItem(item)}
intent={Intent.DANGER}
/>
@@ -72,9 +75,12 @@ const ItemsDataTable = ({
[handleEditItem, handleDeleteItem, formatMessage],
);
const handleRowContextMenu = useCallback((cell) => {
return actionMenuList(cell.row.original);
}, [actionMenuList]);
const handleRowContextMenu = useCallback(
(cell) => {
return actionMenuList(cell.row.original);
},
[actionMenuList],
);
const columns = useMemo(
() => [
@@ -155,7 +161,6 @@ const ItemsDataTable = ({
},
[onSelectedRowsChange],
);
return (
<LoadingIndicator loading={loading} mount={false}>
<DataTable

View File

@@ -211,6 +211,8 @@ export default {
once_delete_this_item_you_will_able_to_restore_it: `Once you delete this item, you won\'t be able to restore the item later. Are you sure you want to delete ?<br /><br />If you're not sure, you can inactivate it instead.`,
the_item_has_been_successfully_deleted:
'The item has been successfully deleted.',
the_item_has_been_successfully_edited:
'The item #{number} has been successfully edited.',
the_item_category_has_been_successfully_created:
'The item category has been successfully created.',
the_item_category_has_been_successfully_edited:

View File

@@ -1,3 +1,4 @@
import { resolve } from 'p-progress';
import ApiService from 'services/ApiService';
import t from 'store/types';
@@ -52,14 +53,13 @@ export const fetchCustomers = ({ query }) => {
ApiService.get(`customers`, { params: { ...pageQuery, ...query } })
.then((response) => {
dispatch({
type: t.CUSTOMER_SET,
type: t.CUSTOMERS_ITEMS_SET,
customers: response.data.customers,
});
dispatch({
type: t.CUSTOMERS_PAGE_SET,
customers: response.data.customers,
customViewId: response.data.customers.customViewId,
customViewId: response.data.customers?.viewMeta?.customViewId || -1,
paginationMeta: response.data.pagination,
});
dispatch({
@@ -74,6 +74,26 @@ export const fetchCustomers = ({ query }) => {
});
};
export const fetchCustomer = ({ id }) => {
return (dispatch) =>
new Promise((resolve, reject) => {
ApiService.get(`customers/${id}`)
.then((response) => {
dispatch({
type: t.CUSTOMER_SET,
payload: {
id,
customer: response.data.contact,
},
});
resolve(response);
})
.catch((error) => {
reject(error);
});
});
};
export const deleteCustomer = ({ id }) => {
return (dispatch) =>
new Promise((resolve, reject) => {

View File

@@ -11,7 +11,7 @@ const initialState = {
};
const customersReducer = createReducer(initialState, {
[t.CUSTOMER_SET]: (state, action) => {
[t.CUSTOMERS_ITEMS_SET]: (state, action) => {
const _customers = {};
action.customers.forEach((customer) => {
@@ -51,6 +51,10 @@ const customersReducer = createReducer(initialState, {
});
state.items = items;
},
[t.CUSTOMER_SET]: (state, action) => {
const { id, customer } = action.payload;
state.items[id] = { ...customer };
},
});
export default createTableQueryReducers('customers', customersReducer);

View File

@@ -27,7 +27,7 @@ export const fetchItems = ({ query }) => {
dispatch({
type: t.ITEMS_PAGE_SET,
items: response.data.items,
customViewId: response.data.customViewId,
customViewId: response.data?.filter_meta?.view?.custom_view_id,
paginationMeta: response.data.pagination,
});
dispatch({
@@ -55,8 +55,12 @@ export const fetchItem = ({ id }) => {
.then((response) => {
dispatch({
type: t.ITEM_SET,
item: response.data.item,
payload: {
id,
item: response.data.item,
},
});
resolve(response);
})
.catch((error) => {
reject(error);

View File

@@ -27,6 +27,11 @@ const itemsReducer = createReducer(initialState, {
};
},
[t.ITEM_SET]: (state, action) => {
const { id, item } = action.payload;
state.items[id] = { ...item };
},
[t.ITEMS_PAGE_SET]: (state, action) => {
const { items, customViewId, paginationMeta } = action;
@@ -42,10 +47,10 @@ const itemsReducer = createReducer(initialState, {
state.itemsRelation[item.id] = [];
}
const filteredRelation = state.itemsRelation[item.id].filter(
(relation) => (
(relation) =>
relation.viewId === viewId &&
relation.pageNumber === paginationMeta.page
));
relation.pageNumber === paginationMeta.page,
);
filteredRelation.push({
viewId,

View File

@@ -1,7 +1,6 @@
export default {
ITEMS_SET: 'ITEMS_SET',
ITEM_SET: 'ITEM_SET',
ITEMS_PAGE_SET: 'ITEMS_PAGE_SET',
ITEM_DELETE: 'ITEM_DELETE',
ITEM_BULK_ACTION_ADD: 'ITEM_BULK_ACTION_ADD',
@@ -12,6 +11,5 @@ export default {
ITEMS_TABLE_LOADING: 'ITEMS_TABLE_LOADING',
ITEMS_SET_CURRENT_VIEW: 'ITEMS_SET_CURRENT_VIEW',
ITEMS_BULK_DELETE:'ITEMS_BULK_DELETE'
ITEMS_BULK_DELETE: 'ITEMS_BULK_DELETE',
};