|
| 1 | +import { httpActions } from '@codetanzania/emis-api-client'; |
| 2 | +import { |
| 3 | + deleteItemCategory, |
| 4 | + paginateItemCategories, |
| 5 | + refreshItemCategories, |
| 6 | +} from '@codetanzania/emis-api-states'; |
| 7 | +import { List } from 'antd'; |
| 8 | +import concat from 'lodash/concat'; |
| 9 | +import intersectionBy from 'lodash/intersectionBy'; |
| 10 | +import map from 'lodash/map'; |
| 11 | +import remove from 'lodash/remove'; |
| 12 | +import uniq from 'lodash/uniq'; |
| 13 | +import uniqBy from 'lodash/uniqBy'; |
| 14 | +import PropTypes from 'prop-types'; |
| 15 | +import React, { Component, Fragment } from 'react'; |
| 16 | +import ListHeader from '../../../../components/ListHeader'; |
| 17 | +import Toolbar from '../../../../components/Toolbar'; |
| 18 | +import { notifyError, notifySuccess } from '../../../../util'; |
| 19 | +import ListItem from '../ListItem'; |
| 20 | + |
| 21 | +/* constants */ |
| 22 | +const headerLayout = [ |
| 23 | + { span: 6, header: 'Name' }, |
| 24 | + { span: 14, header: 'Description' }, |
| 25 | +]; |
| 26 | +const { getItemCategoriesExportUrl } = httpActions; |
| 27 | + |
| 28 | +/** |
| 29 | + * @class |
| 30 | + * @name ItemCategoriesList |
| 31 | + * @description Render ItemCategoriesList component which have actionBar, ItemCategories |
| 32 | + * header and ItemCategories list components |
| 33 | + * |
| 34 | + * @version 0.1.0 |
| 35 | + * @since 0.1.0 |
| 36 | + */ |
| 37 | +class ItemCategoriesList extends Component { |
| 38 | + static propTypes = { |
| 39 | + loading: PropTypes.bool.isRequired, |
| 40 | + itemCategories: PropTypes.arrayOf( |
| 41 | + PropTypes.shape({ |
| 42 | + _id: PropTypes.string.isRequired, |
| 43 | + value: PropTypes.string.isRequired, |
| 44 | + abbreviation: PropTypes.string.isRequired, |
| 45 | + color: PropTypes.string.isRequired, |
| 46 | + description: PropTypes.string.isRequired, |
| 47 | + }) |
| 48 | + ).isRequired, |
| 49 | + page: PropTypes.number.isRequired, |
| 50 | + total: PropTypes.number.isRequired, |
| 51 | + onEdit: PropTypes.func.isRequired, |
| 52 | + onFilter: PropTypes.func.isRequired, |
| 53 | + onNotify: PropTypes.func.isRequired, |
| 54 | + onShare: PropTypes.func.isRequired, |
| 55 | + onBulkShare: PropTypes.func.isRequired, |
| 56 | + }; |
| 57 | + |
| 58 | + state = { |
| 59 | + selectedItemCategories: [], |
| 60 | + selectedPages: [], |
| 61 | + }; |
| 62 | + |
| 63 | + /** |
| 64 | + * @function |
| 65 | + * @name handleOnSelectItem |
| 66 | + * @description Handle select a single itemCategory action |
| 67 | + * |
| 68 | + * @param {Object} itemCategory selected itemCategory object |
| 69 | + * |
| 70 | + * @version 0.1.0 |
| 71 | + * @since 0.1.0 |
| 72 | + */ |
| 73 | + handleOnSelectItem = itemCategory => { |
| 74 | + const { selectedItemCategories } = this.state; |
| 75 | + this.setState({ |
| 76 | + selectedItemCategories: concat([], selectedItemCategories, itemCategory), |
| 77 | + }); |
| 78 | + }; |
| 79 | + |
| 80 | + /** |
| 81 | + * @function |
| 82 | + * @name handleSelectAll |
| 83 | + * @description Handle select all itemCategories actions from current page |
| 84 | + * |
| 85 | + * @version 0.1.0 |
| 86 | + * @since 0.1.0 |
| 87 | + */ |
| 88 | + handleSelectAll = () => { |
| 89 | + const { selectedItemCategories, selectedPages } = this.state; |
| 90 | + const { itemCategories, page } = this.props; |
| 91 | + const selectedList = uniqBy( |
| 92 | + [...selectedItemCategories, ...itemCategories], |
| 93 | + '_id' |
| 94 | + ); |
| 95 | + const pages = uniq([...selectedPages, page]); |
| 96 | + this.setState({ |
| 97 | + selectedItemCategories: selectedList, |
| 98 | + selectedPages: pages, |
| 99 | + }); |
| 100 | + }; |
| 101 | + |
| 102 | + /** |
| 103 | + * @function |
| 104 | + * @name handleDeselectAll |
| 105 | + * @description Handle deselect all itemCategories in a current page |
| 106 | + * |
| 107 | + * @returns {undefined} undefined |
| 108 | + * |
| 109 | + * @version 0.1.0 |
| 110 | + * @since 0.1.0 |
| 111 | + */ |
| 112 | + handleDeselectAll = () => { |
| 113 | + const { itemCategories, page } = this.props; |
| 114 | + const { selectedItemCategories, selectedPages } = this.state; |
| 115 | + const selectedList = uniqBy([...selectedItemCategories], '_id'); |
| 116 | + const pages = uniq([...selectedPages]); |
| 117 | + |
| 118 | + remove(pages, itemCategory => itemCategory === page); |
| 119 | + |
| 120 | + itemCategories.forEach(itemCategory => { |
| 121 | + remove( |
| 122 | + selectedList, |
| 123 | + item => item._id === itemCategory._id // eslint-disable-line |
| 124 | + ); |
| 125 | + }); |
| 126 | + |
| 127 | + this.setState({ |
| 128 | + selectedItemCategories: selectedList, |
| 129 | + selectedPages: pages, |
| 130 | + }); |
| 131 | + }; |
| 132 | + |
| 133 | + /** |
| 134 | + * @function |
| 135 | + * @name handleFilterByStatus |
| 136 | + * @description Handle filter itemCategories by status action |
| 137 | + * |
| 138 | + * @version 0.1.0 |
| 139 | + * @since 0.1.0 |
| 140 | + */ |
| 141 | + handleFilterByStatus = () => { |
| 142 | + // if (status === 'All') { |
| 143 | + // filter({}); |
| 144 | + // } else if (status === 'Active') { |
| 145 | + // filter({}); |
| 146 | + // } else if (status === 'Archived') { |
| 147 | + // filter({}); |
| 148 | + // } |
| 149 | + }; |
| 150 | + |
| 151 | + /** |
| 152 | + * @function |
| 153 | + * @name handleOnDeselectItem |
| 154 | + * @description Handle deselect a single itemCategory action |
| 155 | + * |
| 156 | + * @param {Object} itemCategory itemCategory to be removed from selected itemCategories |
| 157 | + * @returns {undefined} undefined |
| 158 | + * |
| 159 | + * @version 0.1.0 |
| 160 | + * @since 0.1.0 |
| 161 | + */ |
| 162 | + handleOnDeselectItem = itemCategory => { |
| 163 | + const { selectedItemCategories } = this.state; |
| 164 | + const selectedList = [...selectedItemCategories]; |
| 165 | + |
| 166 | + remove( |
| 167 | + selectedList, |
| 168 | + item => item._id === itemCategory._id // eslint-disable-line |
| 169 | + ); |
| 170 | + |
| 171 | + this.setState({ selectedItemCategories: selectedList }); |
| 172 | + }; |
| 173 | + |
| 174 | + render() { |
| 175 | + const { |
| 176 | + itemCategories, |
| 177 | + loading, |
| 178 | + page, |
| 179 | + total, |
| 180 | + onEdit, |
| 181 | + onFilter, |
| 182 | + onNotify, |
| 183 | + onShare, |
| 184 | + onBulkShare, |
| 185 | + } = this.props; |
| 186 | + const { selectedItemCategories, selectedPages } = this.state; |
| 187 | + const selectedItemsCount = intersectionBy( |
| 188 | + this.state.selectedItemCategories, |
| 189 | + itemCategories, |
| 190 | + '_id' |
| 191 | + ).length; |
| 192 | + |
| 193 | + return ( |
| 194 | + <Fragment> |
| 195 | + {/* toolbar */} |
| 196 | + <Toolbar |
| 197 | + itemName="itemCategory" |
| 198 | + page={page} |
| 199 | + total={total} |
| 200 | + selectedItemsCount={selectedItemsCount} |
| 201 | + exportUrl={getItemCategoriesExportUrl({ |
| 202 | + filter: { _id: map(selectedItemCategories, '_id') }, |
| 203 | + })} |
| 204 | + onFilter={onFilter} |
| 205 | + onNotify={() => onNotify(selectedItemCategories)} |
| 206 | + onPaginate={nextPage => { |
| 207 | + paginateItemCategories(nextPage); |
| 208 | + }} |
| 209 | + onRefresh={() => |
| 210 | + refreshItemCategories( |
| 211 | + () => { |
| 212 | + notifySuccess('ItemCategories refreshed successfully'); |
| 213 | + }, |
| 214 | + () => { |
| 215 | + notifyError( |
| 216 | + 'An Error occurred while refreshing ItemCategories please contact system administrator' |
| 217 | + ); |
| 218 | + } |
| 219 | + ) |
| 220 | + } |
| 221 | + onShare={() => onBulkShare(selectedItemCategories)} |
| 222 | + /> |
| 223 | + {/* end toolbar */} |
| 224 | + |
| 225 | + {/* itemCategory list header */} |
| 226 | + <ListHeader |
| 227 | + headerLayout={headerLayout} |
| 228 | + onSelectAll={this.handleSelectAll} |
| 229 | + onDeselectAll={this.handleDeselectAll} |
| 230 | + isBulkSelected={selectedPages.includes(page)} |
| 231 | + /> |
| 232 | + {/* end itemCategory list header */} |
| 233 | + |
| 234 | + {/* itemCategories list */} |
| 235 | + <List |
| 236 | + loading={loading} |
| 237 | + dataSource={itemCategories} |
| 238 | + renderItem={itemCategory => ( |
| 239 | + <ListItem |
| 240 | + key={itemCategory._id} // eslint-disable-line |
| 241 | + abbreviation={itemCategory.abbreviation} |
| 242 | + name={itemCategory.value} |
| 243 | + color={itemCategory.color} |
| 244 | + description={ |
| 245 | + itemCategory.description ? itemCategory.description : 'N/A' |
| 246 | + } |
| 247 | + isSelected={ |
| 248 | + // eslint-disable-next-line |
| 249 | + map( |
| 250 | + selectedItemCategories, |
| 251 | + item => item._id // eslint-disable-line |
| 252 | + ).includes( |
| 253 | + itemCategory._id // eslint-disable-line |
| 254 | + ) |
| 255 | + } |
| 256 | + onSelectItem={() => { |
| 257 | + this.handleOnSelectItem(itemCategory); |
| 258 | + }} |
| 259 | + onDeselectItem={() => { |
| 260 | + this.handleOnDeselectItem(itemCategory); |
| 261 | + }} |
| 262 | + onEdit={() => onEdit(itemCategory)} |
| 263 | + onArchive={() => |
| 264 | + deleteItemCategory( |
| 265 | + itemCategory._id, // eslint-disable-line |
| 266 | + () => { |
| 267 | + notifySuccess('Item was archived successfully'); |
| 268 | + }, |
| 269 | + () => { |
| 270 | + notifyError( |
| 271 | + 'An Error occurred while archiving Item please contact system administrator' |
| 272 | + ); |
| 273 | + } |
| 274 | + ) |
| 275 | + } |
| 276 | + onShare={() => { |
| 277 | + onShare(itemCategory); |
| 278 | + }} |
| 279 | + /> |
| 280 | + )} |
| 281 | + /> |
| 282 | + {/* end itemCategories list */} |
| 283 | + </Fragment> |
| 284 | + ); |
| 285 | + } |
| 286 | +} |
| 287 | + |
| 288 | +export default ItemCategoriesList; |
0 commit comments