diff --git a/client/src/containers/Alerts/Item/ItemActivateAlert.js b/client/src/containers/Alerts/Item/ItemActivateAlert.js new file mode 100644 index 000000000..8af112266 --- /dev/null +++ b/client/src/containers/Alerts/Item/ItemActivateAlert.js @@ -0,0 +1,77 @@ +import React from 'react'; +import { + FormattedMessage as T, + useIntl, +} from 'react-intl'; +import { Intent, Alert } from '@blueprintjs/core'; +import { queryCache } from 'react-query'; +import { AppToaster } from 'components'; + +import withItemsActions from 'containers/Items/withItemsActions'; +import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; +import withAlertActions from 'containers/Alert/withAlertActions'; + +import { compose } from 'utils'; + +/** + * Item activate alert. + */ +function ItemActivateAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { itemId }, + + // #withItemsActions + requestActivateItem, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + + // Handle activate item alert cancel. + const handleCancelActivateItem = () => { + closeAlert(name); + }; + + // Handle confirm item activated. + const handleConfirmItemActivate = () => { + requestActivateItem(itemId) + .then(() => { + closeAlert(name); + AppToaster.show({ + message: formatMessage({ + id: 'the_item_has_been_activated_successfully', + }), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('items-table'); + }) + .catch((error) => { + closeAlert(name); + }); + }; + + return ( + } + confirmButtonText={} + intent={Intent.WARNING} + isOpen={isOpen} + onCancel={handleCancelActivateItem} + onConfirm={handleConfirmItemActivate} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withItemsActions, +)(ItemActivateAlert); diff --git a/client/src/containers/Alerts/Item/ItemBulkDeleteAlert.js b/client/src/containers/Alerts/Item/ItemBulkDeleteAlert.js new file mode 100644 index 000000000..0aa178eb5 --- /dev/null +++ b/client/src/containers/Alerts/Item/ItemBulkDeleteAlert.js @@ -0,0 +1,74 @@ +import React from 'react'; +import { FormattedMessage as T, useIntl } from 'react-intl'; +import { Intent, Alert } from '@blueprintjs/core'; +import { AppToaster } from 'components'; + +import withItemsActions from 'containers/Items/withItemsActions'; +import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; +import withAlertActions from 'containers/Alert/withAlertActions'; + +import { compose } from 'utils'; + +/** + * Item bulk delete alert. + */ +function ItemBulkDeleteAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { itemsIds }, + + // #withItemsActions + requestDeleteBulkItems, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + + // handle cancel item bulk delete alert. + const handleCancelBulkDelete = () => { + closeAlert(name); + }; + // Handle confirm items bulk delete. + const handleConfirmBulkDelete = () => { + requestDeleteBulkItems(itemsIds) + .then(() => { + closeAlert(name); + AppToaster.show({ + message: formatMessage({ + id: 'the_items_has_been_deleted_successfully', + }), + intent: Intent.SUCCESS, + }); + }) + .catch((errors) => { + closeAlert(name); + }); + }; + + return ( + } + confirmButtonText={ + + } + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelBulkDelete} + onConfirm={handleConfirmBulkDelete} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withItemsActions, +)(ItemBulkDeleteAlert); diff --git a/client/src/containers/Alerts/Item/ItemDeleteAlert.js b/client/src/containers/Alerts/Item/ItemDeleteAlert.js new file mode 100644 index 000000000..529caa4aa --- /dev/null +++ b/client/src/containers/Alerts/Item/ItemDeleteAlert.js @@ -0,0 +1,83 @@ +import React from 'react'; +import { + FormattedMessage as T, + FormattedHTMLMessage, + useIntl, +} from 'react-intl'; +import { Intent, Alert } from '@blueprintjs/core'; +import { queryCache } from 'react-query'; +import { AppToaster } from 'components'; + +import { handleDeleteErrors } from 'containers/Items/utils'; + +import withItemsActions from 'containers/Items/withItemsActions'; +import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; +import withAlertActions from 'containers/Alert/withAlertActions'; + +import { compose } from 'utils'; + +/** + * Item delete alerts. + */ +function ItemDeleteAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { itemId }, + + // #withItemsActions + requestDeleteItem, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + + // handle cancel delete item alert. + const handleCancelItemDelete = () => { + closeAlert(name); + }; + + const handleConfirmDeleteItem = () => { + requestDeleteItem(itemId) + .then(() => { + closeAlert(name); + AppToaster.show({ + message: formatMessage({ + id: 'the_item_has_been_deleted_successfully', + }), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('items-table'); + }) + .catch(({ errors }) => { + handleDeleteErrors(errors); + closeAlert(name); + }); + }; + + return ( + } + confirmButtonText={} + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelItemDelete} + onConfirm={handleConfirmDeleteItem} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withItemsActions, +)(ItemDeleteAlert); diff --git a/client/src/containers/Alerts/Item/ItemInactivateAlert.js b/client/src/containers/Alerts/Item/ItemInactivateAlert.js new file mode 100644 index 000000000..975f2ca00 --- /dev/null +++ b/client/src/containers/Alerts/Item/ItemInactivateAlert.js @@ -0,0 +1,77 @@ +import React from 'react'; +import { + FormattedMessage as T, + useIntl, +} from 'react-intl'; +import { Intent, Alert } from '@blueprintjs/core'; +import { queryCache } from 'react-query'; +import { AppToaster } from 'components'; + +import withItemsActions from 'containers/Items/withItemsActions'; +import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; +import withAlertActions from 'containers/Alert/withAlertActions'; + +import { compose } from 'utils'; + +/** + * Item inactivate alert. + */ +function ItemInactivateAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { itemId }, + + // #withItemsActions + requestInactiveItem, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + + // handle cancel inactivate alert. + const handleCancelInactivateItem = () => { + closeAlert(name); + }; + + // Handle confirm item Inactive. + const handleConfirmItemInactive = () => { + requestInactiveItem(itemId) + .then(() => { + closeAlert(name); + AppToaster.show({ + message: formatMessage({ + id: 'the_item_has_been_inactivated_successfully', + }), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('items-table'); + }) + .catch((error) => { + closeAlert(name); + }); + }; + + return ( + } + confirmButtonText={} + intent={Intent.WARNING} + isOpen={isOpen} + onCancel={handleCancelInactivateItem} + onConfirm={handleConfirmItemInactive} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withItemsActions, +)(ItemInactivateAlert); diff --git a/client/src/containers/Items/ItemsActionsBar.js b/client/src/containers/Items/ItemsActionsBar.js index 2e4897c37..33c159e87 100644 --- a/client/src/containers/Items/ItemsActionsBar.js +++ b/client/src/containers/Items/ItemsActionsBar.js @@ -22,6 +22,7 @@ import { If, DashboardActionViewsList } from 'components'; import withResourceDetail from 'containers/Resources/withResourceDetails'; import withItems from 'containers/Items/withItems'; import withItemsActions from './withItemsActions'; +import withAlertActions from 'containers/Alert/withAlertActions'; import { compose } from 'utils'; import { connect } from 'react-redux'; @@ -32,27 +33,23 @@ const ItemsActionsBar = ({ // #withItems itemsViews, + itemsSelectedRows, //#withItemActions addItemsTableQueries, changeItemsCurrentView, + // #withAlertActions + openAlert, onFilterChanged, - selectedRows = [], - onBulkDelete, }) => { const { formatMessage } = useIntl(); const history = useHistory(); - const [filterCount, setFilterCount] = useState(0); const onClickNewItem = useCallback(() => { history.push('/items/new'); }, [history]); - const hasSelectedRows = useMemo(() => selectedRows.length > 0, [ - selectedRows, - ]); - const filterDropdown = FilterDropdown({ fields: resourceFields, initialCondition: { @@ -68,10 +65,6 @@ const ItemsActionsBar = ({ }, }); - const handleBulkDelete = useCallback(() => { - onBulkDelete && onBulkDelete(selectedRows.map((r) => r.id)); - }, [onBulkDelete, selectedRows]); - const handleTabChange = (viewId) => { changeItemsCurrentView(viewId.id || -1); addItemsTableQueries({ @@ -79,6 +72,11 @@ const ItemsActionsBar = ({ }); }; + // Handle cancel/confirm items bulk. + const handleBulkDelete = () => { + openAlert('items-bulk-delete', { itemsIds: itemsSelectedRows }); + }; + return ( @@ -105,18 +103,12 @@ const ItemsActionsBar = ({ >