aretherecookies-mobile/js/enhancers/productsEnhancers.js

91 lines
2.3 KiB
JavaScript
Raw Normal View History

2020-04-17 22:50:23 -05:00
// @flow
import withProps from 'recompose/withProps';
import compose from 'recompose/compose';
import mapPropsStream from 'recompose/mapPropsStream';
import Products$ from '../streams/ProductsStream';
import typeof ProductRecord from '../records/ProductRecord';
import { Map, Set } from 'immutable';
import { pipe, path, toLower, equals } from 'ramda';
type FindPredicate<A> = (left: A) => (right: A) => Boolean;
const getName: (f: ProductRecord) => String = pipe(
path(['name']),
toLower
);
const matchesName: FindPredicate<ProductRecord> = left => right => {
return equals(getName(left), getName(right));
};
const addIfNotExisting = (predicate: FindPredicate<ProductRecord>) => (
set: Set<ProductRecord>,
item: ProductRecord
) => {
return !set.find(predicate(item)) ? set.add(item) : set;
};
const intoSet = reducer => items => {
return items ? items.reduce(reducer, new Set()) : new Set();
};
export const withProducts = mapPropsStream(props$ =>
props$.combineLatest(Products$, (props, products) => {
return {
...props,
productsMap: products,
};
})
);
export const withProductsAsSeq = mapPropsStream(props$ =>
props$.combineLatest(Products$, (props, products) => {
return {
...props,
productsSeq: products && products.valueSeq(),
};
})
);
export const withProductIdFromRoute = withProps((props: { match: { params: { id: string } } }) => {
const id: string = path(['match', 'params', 'id'], props) || '';
return { productId: id };
});
export const withProduct = compose(
withProducts,
withProductIdFromRoute,
withProps((props: { productsMap: ?Map<number, ProductRecord>, productId: number }) => {
const { productsMap, productId } = props;
return { product: productsMap && productsMap.get(productId) };
})
);
export const withProductPlaceId = withProps((props: { product: ProductRecord }) => {
const { product } = props;
return {
placeId: product && product.placeId,
};
});
export const withProductsGroupedByPlace = compose(
withProducts,
withProps((props: { productsMap: ?Map<number, ProductRecord> }) => {
if (!props.productsMap) {
return {};
}
return {
productsByPlace: props.productsMap.groupBy(product => product.placeId),
};
})
);
export const withUniqueProducts = compose(
withProductsAsSeq,
withProps(({ productsSeq }) => {
return {
productsSeq: intoSet(addIfNotExisting(matchesName))(productsSeq),
};
})
);