From 0e342ca02e90468e3c193fbf40b7d481b40da93f Mon Sep 17 00:00:00 2001 From: elforjani3 Date: Wed, 21 Oct 2020 19:22:04 +0200 Subject: [PATCH 1/3] WIP Feature : categoriesSelectList & Fix: Items --- client/src/components/CategoriesSelectList.js | 49 +++++++++++++++++ client/src/components/index.js | 7 ++- client/src/containers/Items/ItemForm.js | 52 ++++--------------- client/src/containers/Items/ItemFormPage.js | 5 +- client/src/containers/Items/ItemsDataTable.js | 21 +++++--- client/src/lang/en/index.js | 2 + 6 files changed, 80 insertions(+), 56 deletions(-) create mode 100644 client/src/components/CategoriesSelectList.js diff --git a/client/src/components/CategoriesSelectList.js b/client/src/components/CategoriesSelectList.js new file mode 100644 index 000000000..1b7022bed --- /dev/null +++ b/client/src/components/CategoriesSelectList.js @@ -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 = , + 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 }) => ( + + ), + [], + ); + + return ( + + ); +} diff --git a/client/src/components/index.js b/client/src/components/index.js index 45bacda7c..ffdd3a48c 100644 --- a/client/src/components/index.js +++ b/client/src/components/index.js @@ -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 -}; \ No newline at end of file + InputPrependButton, + CategoriesSelectList +}; diff --git a/client/src/containers/Items/ItemForm.js b/client/src/containers/Items/ItemForm.js index ec9dd3576..74fd054ed 100644 --- a/client/src/containers/Items/ItemForm.js +++ b/client/src/containers/Items/ItemForm.js @@ -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 }) => ( - - ), - [], - ); - - // 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 }) => ( - - ), - [], - ); - const requiredSpan = useMemo(() => *, []); const infoIcon = useMemo(() => , []); @@ -374,17 +348,11 @@ const ItemForm = ({ Classes.FILL, )} > - } - itemRenderer={categoryItem} - itemPredicate={filterAccounts} + } - labelProp={'name'} /> diff --git a/client/src/containers/Items/ItemFormPage.js b/client/src/containers/Items/ItemFormPage.js index bd2bc7200..28af781ae 100644 --- a/client/src/containers/Items/ItemFormPage.js +++ b/client/src/containers/Items/ItemFormPage.js @@ -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'); diff --git a/client/src/containers/Items/ItemsDataTable.js b/client/src/containers/Items/ItemsDataTable.js index 7a3fdf33b..98e4c1c90 100644 --- a/client/src/containers/Items/ItemsDataTable.js +++ b/client/src/containers/Items/ItemsDataTable.js @@ -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) => ( - + } + text={formatMessage({ id: 'view_details' })} + /> } text={formatMessage({ id: 'edit_item' })} onClick={handleEditItem(item)} /> } 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 (
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: From 274bd2ea48d7dd69b3cf699092de3fed2f3f6fff Mon Sep 17 00:00:00 2001 From: elforjani3 Date: Thu, 22 Oct 2020 14:38:18 +0200 Subject: [PATCH 2/3] Fix : ItemCategory & items --- client/src/containers/Items/ItemCategoriesTable.js | 1 + client/src/store/customers/customers.actions.js | 2 +- client/src/store/items/items.actions.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/containers/Items/ItemCategoriesTable.js b/client/src/containers/Items/ItemCategoriesTable.js index 518400615..4347e9965 100644 --- a/client/src/containers/Items/ItemCategoriesTable.js +++ b/client/src/containers/Items/ItemCategoriesTable.js @@ -50,6 +50,7 @@ const ItemsCategoryList = ({ (category) => ( } text={formatMessage({ id: 'edit_category' })} onClick={handelEditCategory(category)} /> diff --git a/client/src/store/customers/customers.actions.js b/client/src/store/customers/customers.actions.js index 5b7ef800e..b0be90079 100644 --- a/client/src/store/customers/customers.actions.js +++ b/client/src/store/customers/customers.actions.js @@ -59,7 +59,7 @@ export const fetchCustomers = ({ query }) => { 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({ diff --git a/client/src/store/items/items.actions.js b/client/src/store/items/items.actions.js index b53b69963..ac0e31ddc 100644 --- a/client/src/store/items/items.actions.js +++ b/client/src/store/items/items.actions.js @@ -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({ From 099fa6324577f8396bd5d99592f6434e5d0c9215 Mon Sep 17 00:00:00 2001 From: elforjani3 Date: Thu, 22 Oct 2020 18:05:24 +0200 Subject: [PATCH 3/3] Fix: specific item api & customer api --- client/src/containers/Customers/Customer.js | 10 ++++---- .../Customers/withCustomersActions.js | 7 +++--- .../src/store/customers/customers.actions.js | 24 +++++++++++++++++-- .../src/store/customers/customers.reducer.js | 6 ++++- client/src/store/items/items.actions.js | 6 ++++- client/src/store/items/items.reducer.js | 11 ++++++--- client/src/store/items/items.types.js | 6 ++--- 7 files changed, 52 insertions(+), 18 deletions(-) diff --git a/client/src/containers/Customers/Customer.js b/client/src/containers/Customers/Customer.js index c179fc8f5..c0f263f57 100644 --- a/client/src/containers/Customers/Customer.js +++ b/client/src/containers/Customers/Customer.js @@ -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'); diff --git a/client/src/containers/Customers/withCustomersActions.js b/client/src/containers/Customers/withCustomersActions.js index 590004dd3..ae3808859 100644 --- a/client/src/containers/Customers/withCustomersActions.js +++ b/client/src/containers/Customers/withCustomersActions.js @@ -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, diff --git a/client/src/store/customers/customers.actions.js b/client/src/store/customers/customers.actions.js index b0be90079..470cbb97f 100644 --- a/client/src/store/customers/customers.actions.js +++ b/client/src/store/customers/customers.actions.js @@ -1,3 +1,4 @@ +import { resolve } from 'p-progress'; import ApiService from 'services/ApiService'; import t from 'store/types'; @@ -52,10 +53,9 @@ 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, @@ -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) => { diff --git a/client/src/store/customers/customers.reducer.js b/client/src/store/customers/customers.reducer.js index a0ea60a8e..870e0e674 100644 --- a/client/src/store/customers/customers.reducer.js +++ b/client/src/store/customers/customers.reducer.js @@ -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); diff --git a/client/src/store/items/items.actions.js b/client/src/store/items/items.actions.js index ac0e31ddc..bbffc11fd 100644 --- a/client/src/store/items/items.actions.js +++ b/client/src/store/items/items.actions.js @@ -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); diff --git a/client/src/store/items/items.reducer.js b/client/src/store/items/items.reducer.js index b52b7966c..028eb9aeb 100644 --- a/client/src/store/items/items.reducer.js +++ b/client/src/store/items/items.reducer.js @@ -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, diff --git a/client/src/store/items/items.types.js b/client/src/store/items/items.types.js index 44561af21..e35fb5cfe 100644 --- a/client/src/store/items/items.types.js +++ b/client/src/store/items/items.types.js @@ -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', };