From 7d1952344dd9677ed12e3e5c0ccc57fc001c7b42 Mon Sep 17 00:00:00 2001
From: elforjani3
Date: Sat, 23 May 2020 13:53:49 +0200
Subject: [PATCH 1/2] WIP feature/editItem
---
client/src/containers/Items/ItemForm.js | 161 ++++++++++++++----
client/src/containers/Items/ItemFormPage.js | 38 ++++-
client/src/containers/Items/ItemsDataTable.js | 18 +-
client/src/containers/Items/ItemsList.js | 15 +-
client/src/containers/Items/withItemDetail.js | 9 +
.../src/containers/Items/withItemsActions.js | 2 +
client/src/routes/dashboard.js | 7 +
server/src/http/controllers/Items.js | 2 +-
8 files changed, 203 insertions(+), 49 deletions(-)
create mode 100644 client/src/containers/Items/withItemDetail.js
diff --git a/client/src/containers/Items/ItemForm.js b/client/src/containers/Items/ItemForm.js
index 41856af91..cde7897fc 100644
--- a/client/src/containers/Items/ItemForm.js
+++ b/client/src/containers/Items/ItemForm.js
@@ -1,4 +1,4 @@
-import React, { useState, useMemo, useCallback } from 'react';
+import React, { useState, useMemo, useCallback,useEffect } from 'react';
import * as Yup from 'yup';
import { useFormik } from 'formik';
import {
@@ -15,35 +15,61 @@ import { Row, Col } from 'react-grid-system';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { Select } from '@blueprintjs/select';
import { queryCache } from 'react-query';
-
+import {useParams} from 'react-router-dom';
import AppToaster from 'components/AppToaster';
-import AccountsConnect from 'connectors/Accounts.connector';
-import ItemsConnect from 'connectors/Items.connect';
import { compose } from 'utils';
import ErrorMessage from 'components/ErrorMessage';
import classNames from 'classnames';
import Icon from 'components/Icon';
-import ItemCategoryConnect from 'connectors/ItemsCategory.connect';
+import withItemsActions from 'containers/Items/withItemsActions';
+import withItemCategories from 'containers/Items/withItemCategories'
+import withAccounts from 'containers/Accounts/withAccounts';
+import withMediaActions from 'containers/Media/withMediaActions';
+
import MoneyInputGroup from 'components/MoneyInputGroup';
import { useHistory } from 'react-router-dom';
import Dragzone from 'components/Dragzone';
-import MediaConnect from 'connectors/Media.connect';
import useMedia from 'hooks/useMedia';
+import withItems from './withItems';
+import withItemDetail from 'containers/Items/withItemDetail'
+import { pick } from 'lodash';
+import withDashboardActions from 'containers/Dashboard/withDashboard';
const ItemForm = ({
+
+ // #withItemActions
requestSubmitItem,
+ requestEditItem,
+
accounts,
- categories,
+ accountsTypes,
+ itemDetail,
+
+
+ // #withDashboard
+ changePageTitle,
+
+ // #withItemCategories
+ categoriesList,
+
+
+
+// #withMediaActions
requestSubmitMedia,
requestDeleteMedia,
+
+
}) => {
+
const [selectedAccounts, setSelectedAccounts] = useState({});
+ const [selectedAccountType, setSelectedAccountType] = useState(null);
+
const history = useHistory();
const { formatMessage } = useIntl();
-
+ const {id} =useParams();
const {
files,
setFiles,
@@ -81,7 +107,7 @@ const ItemForm = ({
stock: Yup.string() || Yup.boolean(),
});
- const initialValues = useMemo(
+ const defaultInitialValues = useMemo(
() => ({
active: true,
name: '',
@@ -97,6 +123,21 @@ const ItemForm = ({
}),
[]
);
+ const initialValues = useMemo(() => ({
+ ...(itemDetail) ? {
+ ...pick(itemDetail, Object.keys(defaultInitialValues)),
+
+ } : {
+ ...defaultInitialValues,
+ }
+ }), [itemDetail, defaultInitialValues]);
+
+
+ useEffect(() => {
+ itemDetail && itemDetail.id ?
+ changePageTitle(formatMessage({id:'edit_item_details'})) :
+ changePageTitle(formatMessage({id:'new_item'}));
+ }, [changePageTitle,itemDetail]);
const {
getFieldProps,
@@ -112,24 +153,47 @@ const ItemForm = ({
initialValues: {
...initialValues,
},
- onSubmit: (values, { setSubmitting }) => {
+ onSubmit: (values, { setSubmitting,resetForm,setErrors }) => {
+
const saveItem = (mediaIds) => {
const formValues = { ...values, media_ids: mediaIds };
+ if(itemDetail && itemDetail.id ){
- return requestSubmitItem(formValues).then((response) => {
- AppToaster.show({
- message: formatMessage({
- id: 'service_has_been_successful_created',
- }, {
- name: values.name,
- service: formatMessage({ id: 'item' }),
- }),
- intent: Intent.SUCCESS,
+ requestEditItem(itemDetail.id,formValues)
+ .then((response)=>{
+ AppToaster.show({
+ message:formatMessage({
+ id:'the_item_has_been_successfully_edited',
+ },{
+ number:itemDetail.id
+ }),
+ intent:Intent.SUCCESS
+ });
+ setSubmitting(false);
+ resetForm();
+ }).catch((errors)=>{
+ setSubmitting(false)
});
- queryCache.removeQueries(['items-table']);
- history.push('/dashboard/items');
- });
- };
+
+ }else{
+
+ requestSubmitItem(formValues).then((response) => {
+ AppToaster.show({
+ message: formatMessage({
+ id: 'service_has_been_successful_created',
+ }, {
+ name: values.name,
+ service: formatMessage({ id: 'item' }),
+ }),
+ intent: Intent.SUCCESS,
+ });
+ queryCache.removeQueries(['items-table']);
+ history.push('/items');
+ });
+ };
+ }
+
+
Promise.all([saveMedia(), deleteMedia()]).then(
([savedMediaResponses]) => {
@@ -152,6 +216,7 @@ const ItemForm = ({
[]
);
+
// Filter Account Items
const filterAccounts = (query, account, _index, exactMatch) => {
const normalizedTitle = account.name.toLowerCase();
@@ -163,6 +228,19 @@ const ItemForm = ({
}
};
+
+// Set default
+ // useEffect(()=>{
+
+ // if(itemDetail && itemDetail.id){
+ // const defaultType = itemDetail.find(
+ // (t) => t.id === itemDetail.id
+ // );
+
+ // defaultType && setSelectedAccountType(defaultType);
+ // }
+
+ // },[])
const onItemAccountSelect = useCallback(
(filedName) => {
return (account) => {
@@ -183,6 +261,7 @@ const ItemForm = ({
[]
);
+
const getSelectedAccountLabel = useCallback(
(fieldName, defaultLabel) => {
return typeof selectedAccounts[fieldName] !== 'undefined'
@@ -199,10 +278,18 @@ const ItemForm = ({
setFieldValue(fieldKey, value);
};
- const initialAttachmentFiles = useMemo(() => {
- return [];
- }, []);
-
+
+ const initialAttachmentFiles =useMemo(()=>{
+ return itemDetail && itemDetail.media
+ ? itemDetail.media.map((attach)=>({
+
+ preview:attach.attachment_file,
+ upload:true,
+ metadata:{...attach}
+
+ })):[];
+
+ },[itemDetail])
const handleDropFiles = useCallback((_files) => {
setFiles(_files.filter((file) => file.uploaded === false));
}, []);
@@ -297,7 +384,7 @@ const ItemForm = ({
)}
>
+
+ }
+ confirmButtonText={`${formatMessage({id:'delete'})} (${selectedRowsCount})`}
+ icon="trash"
+ intent={Intent.DANGER}
+ isOpen={bulkDelete}
+ onCancel={handleCancelBulkDelete}
+ onConfirm={handleConfirmBulkDelete}
+ >
+
+
+
+
diff --git a/client/src/containers/Items/withItemsActions.js b/client/src/containers/Items/withItemsActions.js
index 9be79e2e3..fc8cafe94 100644
--- a/client/src/containers/Items/withItemsActions.js
+++ b/client/src/containers/Items/withItemsActions.js
@@ -4,12 +4,14 @@ import {
deleteItem,
submitItem,
editItem,
+ deleteBulkItems
} from 'store/items/items.actions';
import t from 'store/types';
export const mapDispatchToProps = (dispatch) => ({
requestFetchItems: (query) => dispatch(fetchItems({ query })),
requestDeleteItem: (id) => dispatch(deleteItem({ id })),
+ requestDeleteBulkItems:(ids)=>dispatch(deleteBulkItems({ids})),
requestSubmitItem: (form) => dispatch(submitItem({ form })),
requestEditItem:(id,form) => dispatch(editItem({id,form})),
addBulkActionItem: (id) => dispatch({
diff --git a/client/src/lang/en/index.js b/client/src/lang/en/index.js
index b32e523f8..0d0e5a735 100644
--- a/client/src/lang/en/index.js
+++ b/client/src/lang/en/index.js
@@ -322,7 +322,10 @@ export default {
organization_industry_:'Organization industry',
base_currency_:'Base currency',
date_format_:'Date format',
- view_name_:'View name'
+ category_name_:'Category name',
+ view_name_:'View name',
+ the_items_has_been_successfully_deleted: 'The items have been successfully deleted.',
+ once_delete_these_items_you_will_not_able_restore_them: 'Once you delete these items, you won\'t be able to retrieve them later. Are you sure you want to delete them?',
};
diff --git a/client/src/store/items/items.actions.js b/client/src/store/items/items.actions.js
index bbb1a3eef..461bd949b 100644
--- a/client/src/store/items/items.actions.js
+++ b/client/src/store/items/items.actions.js
@@ -76,3 +76,19 @@ export const deleteItem = ({ id }) => {
}).catch((error) => { reject(error); });
});
};
+
+
+
+export const deleteBulkItems = ({ ids }) => {
+ return dispatch => new Promise((resolve, reject) => {
+ ApiService.delete(`items`, { params: { ids }}).then((response) => {
+ dispatch({
+ type: t.ITEMS_BULK_DELETE,
+ payload: { ids }
+ });
+ resolve(response);
+ }).catch((error) => {
+ reject(error);
+ });
+ });
+};
diff --git a/client/src/store/items/items.types.js b/client/src/store/items/items.types.js
index 3d9c5b621..44561af21 100644
--- a/client/src/store/items/items.types.js
+++ b/client/src/store/items/items.types.js
@@ -12,4 +12,6 @@ export default {
ITEMS_TABLE_LOADING: 'ITEMS_TABLE_LOADING',
ITEMS_SET_CURRENT_VIEW: 'ITEMS_SET_CURRENT_VIEW',
+ ITEMS_BULK_DELETE:'ITEMS_BULK_DELETE'
+
};