Skip to content

Commit

Permalink
Merge pull request #10 from openimis/develop
Browse files Browse the repository at this point in the history
v1.3
  • Loading branch information
edarchis authored Oct 28, 2021
2 parents 1666ca5 + 87c7455 commit 62d8ee3
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 112 deletions.
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "all",
"printWidth": 120,
"quoteProps": "preserve",
"arrowParens": "always"
}
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openimis/fe-product",
"version": "1.2.1",
"version": "1.3.0",
"description": "openIMIS Frontend Product reference module",
"license": "AGPL-3.0-only",
"repository": "openimis/openimis-fe-product_js",
Expand All @@ -12,7 +12,8 @@
},
"scripts": {
"build": "rollup -c",
"start": "rollup -c -w"
"start": "rollup -c -w",
"format": "prettier src -w"
},
"peerDependency": {
"react-intl": "^5.8.1"
Expand All @@ -26,11 +27,12 @@
"@babel/preset-react": "^7.9.4",
"@babel/runtime": "^7.9.6",
"@rollup/plugin-babel": "^5.0.0",
"@rollup/plugin-commonjs": "^11.1.0",
"@rollup/plugin-commonjs": "^20.0.0",
"@rollup/plugin-json": "^4.0.3",
"@rollup/plugin-node-resolve": "^7.1.3",
"@rollup/plugin-url": "^5.0.0",
"@rollup/plugin-node-resolve": "^13.0.4",
"@rollup/plugin-url": "^6.1.0",
"moment": "^2.25.3",
"prettier": "^2.3.2",
"prop-types": "^15.7.2",
"react-autosuggest": "^10.0.2",
"react-router-dom": "^5.2.0",
Expand Down
9 changes: 5 additions & 4 deletions src/actions.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { graphql, formatPageQuery } from "@openimis/fe-core";

export function fetchProducts(mm, str) {
let payload = formatPageQuery("productsStr",
let payload = formatPageQuery(
"productsStr",
!!str && str.length && [`str:"${str}"`],
mm.getRef("product.ProductPicker.projection")
mm.getRef("product.ProductPicker.projection"),
);
return graphql(payload, 'PRODUCT_PRODUCT_PICKER');
}
return graphql(payload, "PRODUCT_PRODUCT_PICKER");
}
11 changes: 5 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ import reducer from "./reducer";
import ProductPicker from "./pickers/ProductPicker";

const DEFAULT_CONFIG = {
"translations": [{ key: 'en', messages: messages_en }],
"reducers": [{ key: 'product', reducer }],
"translations": [{ key: "en", messages: messages_en }],
"reducers": [{ key: "product", reducer }],
"refs": [
{ key: "product.ProductPicker", ref: ProductPicker },
{ key: "product.ProductPicker.projection", ref: ["id", "code", "name", "location{id}"] },
{ key: "product.ProductPicker.sort", ref: 'product__code' },
{ key: "product.ProductPicker.sort", ref: "product__code" },
],
}

};

export const ProductModule = (cfg) => {
return { ...DEFAULT_CONFIG, ...cfg };
}
};
128 changes: 69 additions & 59 deletions src/pickers/ProductPicker.js
Original file line number Diff line number Diff line change
@@ -1,81 +1,91 @@
import React, { Component } from "react";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import { injectIntl } from 'react-intl';
import { injectIntl } from "react-intl";
import { formatMessage, AutoSuggestion, withModulesManager } from "@openimis/fe-core";
import { fetchProducts } from "../actions";
import _debounce from "lodash/debounce";

class ProductPicker extends Component {
constructor(props) {
super(props);
this.cache = props.modulesManager.getConf("fe-product", "cacheProducts", true);
this.selectThreshold = props.modulesManager.getConf("fe-product", "ProductPicker.selectThreshold", 10);
}

constructor(props) {
super(props);
this.cache = props.modulesManager.getConf("fe-product", "cacheProducts", true);
this.selectThreshold = props.modulesManager.getConf("fe-product", "ProductPicker.selectThreshold", 10);
componentDidMount() {
if (this.cache && !this.props.products) {
// prevent loading multiple times the cache when component is
// several times on tha page
setTimeout(() => {
!this.props.fetching && this.props.fetchProducts(this.props.modulesManager);
}, Math.floor(Math.random() * 300));
}
}

componentDidMount() {
if (this.cache && !this.props.products) {
// prevent loading multiple times the cache when component is
// several times on tha page
setTimeout(
() => {
!this.props.fetching && this.props.fetchProducts(this.props.modulesManager);
},
Math.floor(Math.random() * 300)
);
}
}

formatSuggestion = s => !!s ? `${s.code} ${s.name}` : '';
formatSuggestion = (s) => (!!s ? `${s.code} ${s.name}` : "");

getSuggestions = str => !!str &&
str.length >= this.props.modulesManager.getConf("fe-product", "productsMinCharLookup", 2) &&
this.props.fetchProducts(this.props.modulesManager, str);
getSuggestions = (str) =>
!!str &&
str.length >= this.props.modulesManager.getConf("fe-product", "productsMinCharLookup", 2) &&
this.props.fetchProducts(this.props.modulesManager, str);

debouncedGetSuggestion = _debounce(
this.getSuggestions,
this.props.modulesManager.getConf("fe-product", "debounceTime", 800)
)
debouncedGetSuggestion = _debounce(
this.getSuggestions,
this.props.modulesManager.getConf("fe-product", "debounceTime", 800),
);

onSuggestionSelected = v => this.props.onChange(v, this.formatSuggestion(v));
onSuggestionSelected = (v) => this.props.onChange(v, this.formatSuggestion(v));

render() {
const { intl, products, withLabel = true, label, withPlaceholder = false, placeholder, value, reset,
readOnly = false, required = false,
withNull = false, nullLabel = null,
filter = null
} = this.props;
let items = products
if (!!filter) {
items = this.props.filter(items)
}
return <AutoSuggestion
items={items}
label={!!withLabel && (label || formatMessage(intl, "product", "Product"))}
placeholder={!!withPlaceholder ? placeholder || formatMessage(intl, "product", "ProductPicker.placehoder") : null}
getSuggestions={this.cache ? null : this.debouncedGetSuggestion}
getSuggestionValue={this.formatSuggestion}
onSuggestionSelected={this.onSuggestionSelected}
value={value}
reset={reset}
readOnly={readOnly}
required={required}
selectThreshold={this.selectThreshold}
withNull={withNull}
nullLabel={nullLabel || formatMessage(intl, "product", "product.ProductPicker.null")}
/>
render() {
const {
intl,
products,
withLabel = true,
label,
withPlaceholder = false,
placeholder,
value,
reset,
readOnly = false,
required = false,
withNull = false,
nullLabel = null,
filter = null,
} = this.props;
let items = products;
if (!!filter) {
items = this.props.filter(items);
}
return (
<AutoSuggestion
items={items}
label={!!withLabel && (label || formatMessage(intl, "product", "Product"))}
placeholder={
!!withPlaceholder ? placeholder || formatMessage(intl, "product", "ProductPicker.placehoder") : null
}
getSuggestions={this.cache ? null : this.debouncedGetSuggestion}
getSuggestionValue={this.formatSuggestion}
onSuggestionSelected={this.onSuggestionSelected}
value={value}
reset={reset}
readOnly={readOnly}
required={required}
selectThreshold={this.selectThreshold}
withNull={withNull}
nullLabel={nullLabel || formatMessage(intl, "product", "product.ProductPicker.null")}
/>
);
}
}

const mapStateToProps = state => ({
products: state.product.products,
fetching: state.product.fetchingProducts,
const mapStateToProps = (state) => ({
products: state.product.products,
fetching: state.product.fetchingProducts,
});

const mapDispatchToProps = dispatch => {
return bindActionCreators({ fetchProducts }, dispatch);
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({ fetchProducts }, dispatch);
};

export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(
withModulesManager(ProductPicker)));
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(withModulesManager(ProductPicker)));
66 changes: 33 additions & 33 deletions src/reducer.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
import { parseData, formatServerError, formatGraphQLError } from '@openimis/fe-core';
import { parseData, formatServerError, formatGraphQLError } from "@openimis/fe-core";

function reducer(
state = {
fetchingProducts: false,
state = {
fetchingProducts: false,
fetchedProducts: false,
errorProducts: null,
products: null,
},
action,
) {
switch (action.type) {
case "PRODUCT_PRODUCT_PICKER_REQ":
return {
...state,
fetchingProducts: true,
fetchedProducts: false,
products: null,
errorProducts: null,
products: null,
},
action,
) {
switch (action.type) {
case 'PRODUCT_PRODUCT_PICKER_REQ':
return {
...state,
fetchingProducts: true,
fetchedProducts: false,
products: null,
errorProducts: null,
};
case 'PRODUCT_PRODUCT_PICKER_RESP':
return {
...state,
fetchingProducts: false,
fetchedProducts: true,
products: parseData(action.payload.data.productsStr),
errorProducts: formatGraphQLError(action.payload)
};
case 'PRODUCT_PRODUCT_PICKER_ERR':
return {
...state,
fetchingProducts: false,
errorProducts: formatServerError(action.payload)
};
default:
return state;
}
};
case "PRODUCT_PRODUCT_PICKER_RESP":
return {
...state,
fetchingProducts: false,
fetchedProducts: true,
products: parseData(action.payload.data.productsStr),
errorProducts: formatGraphQLError(action.payload),
};
case "PRODUCT_PRODUCT_PICKER_ERR":
return {
...state,
fetchingProducts: false,
errorProducts: formatServerError(action.payload),
};
default:
return state;
}
}

export default reducer;
10 changes: 5 additions & 5 deletions src/translations/en.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"product.Product": "Product",
"product.ProductPicker.placehoder": "Search Product…",
"product.ProductPicker.null": "Any",
"product.Product.none": "None"
}
"product.Product": "Product",
"product.ProductPicker.placehoder": "Search Product…",
"product.ProductPicker.null": "Any",
"product.Product.none": "None"
}

0 comments on commit 62d8ee3

Please sign in to comment.