diff --git a/static/js/shop/Cart.jsx b/static/js/shop/Cart.jsx
index 2b180aa2..965b9ce6 100644
--- a/static/js/shop/Cart.jsx
+++ b/static/js/shop/Cart.jsx
@@ -17,6 +17,8 @@ export function Cart({crate_index}) {
crate: state.crates[crate_index]
}));
+ console.log(resource_counters, crate)
+
const nbrOccupied = hp_to_slots(resource_counters.hp(crate.items, -1));
const nbrSlots = hp_to_slots(crate_type_to_hp(crate.crate_mode));
console.log(nbrOccupied, nbrSlots);
diff --git a/static/js/shop/OrderPanel.jsx b/static/js/shop/OrderPanel.jsx
index bb770505..ada7a914 100644
--- a/static/js/shop/OrderPanel.jsx
+++ b/static/js/shop/OrderPanel.jsx
@@ -1,7 +1,7 @@
import React from 'react'
-import {OrderSummary} from "./OrderSummary";
-import {OrderForm} from "./OrderForm";
-import {CrateList} from "./CrateList";
+import {OrderSummary} from "./OrderSummary.jsx";
+import {OrderForm} from "./OrderForm.jsx";
+import {CrateList} from "./CrateList.jsx";
import {useShopStore} from "./shop_store";
/**
@@ -40,7 +40,7 @@ export function OrderPanel({title, description}) {
diff --git a/static/js/shop/ProductCartItem.jsx b/static/js/shop/ProductCartItem.jsx
index 0e5a9283..429e9cab 100644
--- a/static/js/shop/ProductCartItem.jsx
+++ b/static/js/shop/ProductCartItem.jsx
@@ -24,10 +24,10 @@ export function ProductCartItem({card_index, crate_index, ext_data, first, last,
let options, options_data;
//const warnings = data && data.show_warnings;
- if (data && data.options) {
- options = data.options;
- if (!data.options_data) crate.options_data = {};
- options_data = crate.options_data;
+ if (card && card.options) {
+ options = card.options;
+ if (!card.options_data) card.options_data = {};
+ options_data = card.options_data;
options_data.ext_data = ext_data;
}
diff --git a/static/js/shop/Shop.jsx b/static/js/shop/Shop.jsx
index ef8d1e1a..d3c12f43 100644
--- a/static/js/shop/Shop.jsx
+++ b/static/js/shop/Shop.jsx
@@ -1,577 +1,49 @@
-import React, {PureComponent} from 'react';
-import PropTypes from "prop-types";
-import {FilterOptions} from "./options/utils";
-import {v4 as uuidv4} from "uuid";
+import React from 'react';
import {DragDropContext} from "@hello-pangea/dnd";
-import {copyFromBacklog, itemsUnfoldedList, nbrOccupiedSlotsInCrate, remove, reorder} from "./utils";
import {Layout} from "./Layout.jsx";
import {Backlog} from "./Backlog.jsx";
import {OrderPanel} from "./OrderPanel.jsx";
-import {OrderSummary} from "./OrderSummary.jsx";
-import {OrderForm} from "./OrderForm.jsx";
-import {TriggerCrateWarnings, TriggerWarnings} from "./warnings";
-import {FillResources} from "./count_resources";
-import {CrateList} from "./CrateList.jsx";
+import {useShopStore} from "./shop_store";
/**
* Component that render the entire shop
*/
export function Shop() {
-
- static get propTypes() {
- return {
- data: PropTypes.object.isRequired,
- };
+ const {addCardFromBacklog, moveCard, deleteCard} = useShopStore(state => ({
+ addCardFromBacklog: state.addCardFromBacklog,
+ moveCard: state.moveCard,
+ deleteCard: state.deleteCard
+ }));
+ const handleOnDragEnd = (drop_result, provided) => {
+ console.log(drop_result, provided)
+ //{
+ // "draggableId": "42dc17e9-9e75-45ee-ad27-2233b6f07a5e",
+ // "type": "DEFAULT",
+ // "source": {
+ // "index": 17,
+ // "droppableId": "backlog"
+ // },
+ // "reason": "DROP",
+ // "mode": "FLUID",
+ // "destination": {
+ // "droppableId": "crate0",
+ // "index": 0
+ // },
+ // "combine": null
+ // }
+ if (drop_result.source.droppableId === "backlog")
+ addCardFromBacklog(drop_result.destination.droppableId, drop_result.source.index, drop_result.destination.index);
+ else if(drop_result.destination.droppableId === "backlog")
+ deleteCard(drop_result.destination.droppableId, drop_result.destination.index);
+ else
+ moveCard(drop_result.source.droppableId, drop_result.source.index, drop_result.destination.droppableId, drop_result.destination.index)
}
- constructor(props) {
- super(props);
- this.state = this.props.data;
- this.handleCrateModeChange = this.handleCrateModeChange.bind(this);
- this.handleOnDragEnd = this.handleOnDragEnd.bind(this);
- this.handleDeleteItem = this.handleDeleteItem.bind(this);
- this.handleDeleteAllItems = this.handleDeleteAllItems.bind(this);
- this.handleMouseEnterItem = this.handleMouseEnterItem.bind(this);
- this.handleMouseLeaveItem = this.handleMouseLeaveItem.bind(this);
- this.handleClickAddItem = this.handleClickAddItem.bind(this);
- this.checkAlertsInNewState = this.checkAlertsInNewState.bind(this);
- this.handleClickSelectItem = this.handleClickSelectItem.bind(this);
- this.handleClickSubmit = this.handleClickSubmit.bind(this);
- this.handleToggleOverlayRemove = this.handleToggleOverlayRemove.bind(this);
- this.handleShowOverlayRemove = this.handleShowOverlayRemove.bind(this);
- this.handleClickToggleMobileSideMenu = this.handleClickToggleMobileSideMenu.bind(this);
- this.handleClickCloseRFQFeedback = this.handleClickCloseRFQFeedback.bind(this);
- this.handleClickShowOrder = this.handleClickShowOrder.bind(this);
- this.handleClickOpenImport = this.handleClickOpenImport.bind(this);
- this.handleLoadCustomConf = this.handleLoadCustomConf.bind(this);
- this.onAddCrate = this.onAddCrate.bind(this);
- this.onDeleteCrate = this.onDeleteCrate.bind(this);
- this.onCrateModeChange = this.onCrateModeChange.bind(this);
- this.onCrateSelected = this.onCrateSelected.bind(this);
- this.onCrateChanged = this.onCrateChanged.bind(this);
-
- this.timer = null;
- this.timer_remove = null;
- }
-
- componentDidMount() {
- const source = {
- droppableId: 'backlog',
- indexes: [
- itemsUnfoldedList.findIndex(element => element === "eem_pwr_mod"),
- itemsUnfoldedList.findIndex(element => element === "kasli")
- ],
- };
- const destination = {
- droppableId: 'crate0',
- index: 0,
- };
-
- this.handleOnDragEnd({
- source,
- destination
- });
- }
-
- componentDidUpdate(prevProps, prevState) {
- /**
- * We check alerts (reminder + warning) only when items inside crate or
- * crate mode change.
- *
- * In the function checkAlerts, we DO NOT want to change items as we will
- * trigger again this function (componentDidUpdate) and thus,
- * making an infinite loop.
- */
- console.log("componentDidUpdate")
- return;
- if (
- (prevState.columns.crates !== this.state.columns.crates.items) ||
- (prevState.currentMode !== this.state.currentMode)
- ) {
- this.checkAlerts(this.state.columns.cart.items);
- }
-
-
- if (this.state.newCardJustAdded) {
- this.timer = setTimeout(() => {
- this.setState({
- newCardJustAdded: false,
- });
- }, 2000);
- }
- }
-
- componentWillUnmount() {
- clearTimeout(this.timer);
- }
-
- onCrateChanged(crate_id) {
- // kinda silly that hover over cards triggers checkAlerts
-
- this.checkAlertsInNewState(crate_id, this.state);
-
- }
-
- handleCrateModeChange(mode) {
- this.setState({
- currentMode: mode,
- });
- }
-
- handleDeleteItem(index) {
- let cloned = Array.from(this.state.columns.cart.items);
- let cloned_data = Array.from(this.state.columns.cart.itemsData);
- cloned.splice(index, 1);
- cloned_data.splice(index, 1);
-
- this.setState({
- ...this.state,
- columns: {
- ...this.state.columns,
- cart: {
- ...this.state.columns.cart,
- items: cloned,
- itemsData: cloned_data,
- },
- },
- });
- }
-
- handleDeleteAllItems() {
- this.setState({
- ...this.state,
- columns: {
- ...this.state.columns,
- cart: {
- ...this.state.columns.cart,
- items: [],
- itemsData: []
- },
- },
- });
- }
-
- handleMouseEnterItem(id) {
- this.setState({
- ...this.state,
- currentItemHovered: id,
- });
- }
-
- handleMouseLeaveItem() {
- this.setState({
- ...this.state,
- currentItemHovered: null,
- });
- }
-
- handleClickAddItem(index, tap) {
- const source = {
- droppableId: 'backlog',
- index: index,
- };
- const destination = {
- droppableId: 'cart',
- index: this.state.columns.cart.items.length,
- };
-
- this.handleOnDragEnd({
- source,
- destination
- }, tap);
- }
-
- handleClickSelectItem(index) {
- const itemsCloned = Array.from(this.state.columns.cart.items);
-
- this.setState({
- ...this.state,
- columns: {
- ...this.state.columns,
- cart: {
- ...this.state.columns.cart,
- items: itemsCloned.map((item, id) => {
- return {...item, selected: id === index ? true : false};
- }),
- }
- },
- });
- }
-
- handleToggleOverlayRemove(index, show) {
- const itemsCloned = Array.from(this.state.columns.cart.items);
-
- this.setState({
- ...this.state,
- columns: {
- ...this.state.columns,
- cart: {
- ...this.state.columns.cart,
- items: itemsCloned.map((item, id) => {
- return {
- ...item,
- showOverlayRemove: id === index ? show : false
- };
- }),
- }
- },
- });
- }
-
- handleShowOverlayRemove(index) {
- if (this.timer_remove)
- clearTimeout(this.timer_remove);
-
- this.handleToggleOverlayRemove(index, true);
-
- this.timer_remove = setTimeout(() => {
- this.handleToggleOverlayRemove(index, false);
- }, 2000);
- }
-
- handleClickShowOrder() {
- const crate = {
- items: [],
- type: this.state.currentMode,
- };
- const clonedCart = Array.from(this.state.columns.cart.items);
- const clonedCartData = Array.from(this.state.columns.cart.itemsData);
- for (const i in clonedCart) {
- const item = clonedCart[i];
- const item_data = clonedCartData[i];
- crate.items.push({
- 'pn': item.name_number,
- 'options': (item_data.options_data && item_data.options) ? FilterOptions(item_data.options, item_data.options_data) : null,
- });
- }
-
- this.setState({
- isProcessing: false,
- shouldShowRFQFeedback: true,
- RFQBodyType: 'show',
- RFQBodyOrder: JSON.stringify(crate, null, 2),
- });
- }
-
- handleClickOpenImport() {
- this.setState({
- isProcessing: false,
- shouldShowRFQFeedback: true,
- RFQBodyType: 'import',
- });
- }
-
- handleLoadCustomConf(customconf) {
- if (!customconf) {return; }
-
- const items = this.props.data.items;
-
- let new_items = [];
- let new_items_data = [];
-
-
- this.setState({
- ...this.state,
- columns: {
- ...this.state.columns,
- cart: {
- ...this.state.columns.cart,
- items: [],
- },
- },
- }, function () {
-
- customconf.items.map(function (item) {
- Object.keys(items).map(key => {
- if (item.pn && item.pn === items[key].name_number) {
- new_items.push(Object.assign({
- ...items[key],
- }, {
- id: uuidv4(),
- options_data: item.options ? item.options : null,
- }));
- new_items_data.push({options_data: item.options ? item.options : null});
- }
- });
-
- return item;
- });
-
- this.setState({
- ...this.state,
- columns: {
- ...this.state.columns,
- cart: {
- ...this.state.columns.cart,
- items: new_items,
- itemsData: new_items_data,
- },
- },
- currentMode: customconf.type,
- });
- });
- }
-
- handleClickSubmit(note, email) {
- const crate = {
- items: [],
- type: this.state.currentMode,
- };
- const clonedCart = Array.from(this.state.columns.cart.items);
- const clonedCartData = Array.from(this.state.columns.cart.itemsData);
- for (const i in clonedCart) {
- const item = clonedCart[i];
- const item_data = clonedCartData[i];
- crate.items.push({
- 'pn': item.name_number,
- 'options': (item_data.options_data && item_data.options) ? FilterOptions(item_data.options, item_data.options_data) : null,
- });
- }
-
- const {data} = this.props;
-
- this.setState({isProcessing: true});
-
- fetch(data.API_RFQ, {
- method: "POST",
- headers: {'Content-Type': 'application/json'},
- body: JSON.stringify({
- email,
- note,
- configuration: JSON.stringify(crate)
- })
- }).then(response => {
- if (response.status !== 200) {
- throw Error("Response status is not OK: " + response.status + ".\n" + response);
- }
- this.setState({
- isProcessing: false,
- shouldShowRFQFeedback: true,
- RFQBodyType: 'email',
- isProcessingComplete: true,
- });
- }).catch(err => {
- console.error("Request failed, reason:", err)
- this.setState({isProcessing: false}, () => {
- alert("We cannot receive your request. Try using the export by coping the configuration and send it to us at sales@m-labs.hk");
- });
- })
- }
-
- handleOnDragEnd(result) {
- /**
- * 4 cases:
- * - from backlog to one of the crate - add to the correct crate in correct order
- * - from one crate to another - delete from one crate and put to another in correct order
- * - within one crate - reorder
- * - from crate to backlog - delete
- * */
-
- const {
- source,
- destination,
- } = result;
- /* better move to another function
- let dragged_items = [];
- if (source.indexes) {
- source.indexes.forEach((card_index, _) => {
- dragged_items.push(itemsUnfoldedList[card_index]);
- })
- } else if (source.index >= 0) {
- dragged_items.push(itemsUnfoldedList[source.index]);
- }*/
-
- console.log('==> result', result);
-
- // dropped outside the list
- if (!destination) {
- return;
- }
-
- switch (source.droppableId) {
- // TODO add delete functionality
- case destination.droppableId:
- /*this.setState({
- ...this.state,
- columns: {
- ...this.state.columns,
- crates: {
- ...this.state.columns.crates,
- [destination.droppableId]: {
- ...this.state.columns.crates[destination.droppableId],
- items: reorder(
- this.state.columns.crates[source.droppableId].items,
- source.index,
- destination.index
- )}}
- }
- });*/
- this.checkAlertsInNewState(destination.droppableId, {
- ...this.state,
- columns: {
- ...this.state.columns,
- crates: {
- ...this.state.columns.crates,
- [destination.droppableId]: {
- ...this.state.columns.crates[destination.droppableId],
- items: reorder(
- this.state.columns.crates[source.droppableId].items,
- source.index,
- destination.index
- )}}
- }
- });
- break;
- case 'backlog':
- /*this.setState({
- ...this.state,
- columns: {
- ...this.state.columns,
- crates: {
- ...this.state.columns.crates,
- [destination.droppableId]: {
- ...this.state.columns.crates[destination.droppableId],
- items: copyFromBacklog(
- this.state.items,
- this.state.columns.crates[destination.droppableId],
- source,
- destination
- )}}
- }
- });*/
- this.checkAlertsInNewState(destination.droppableId, {
- ...this.state,
- columns: {
- ...this.state.columns,
- crates: {
- ...this.state.columns.crates,
- [destination.droppableId]: {
- ...this.state.columns.crates[destination.droppableId],
- items: copyFromBacklog(
- this.state.items,
- this.state.columns.crates[destination.droppableId],
- source,
- destination
- )}}
- }
- });
- break;
- default:
- this.setState({
- columns: move(
- this.state.columns[source.droppableId],
- this.state.columns[destination.droppableId],
- source,
- destination
- )
- });
- break;
- }
- }
-
- handleClickToggleMobileSideMenu() {
- this.setState({
- ...this.state,
- mobileSideMenuShouldOpen: !this.state.mobileSideMenuShouldOpen,
- });
- }
-
- handleClickCloseRFQFeedback() {
- this.setState({
- shouldShowRFQFeedback: false,
- });
- }
-
- checkAlertsInNewState(crate_id, new_state) {
- console.log('--- START CHECKING CRATE WARNING ---');
-
- let itemsCloned = Array.from(new_state.columns.crates[crate_id].items);
-
- const crate_warnings = TriggerCrateWarnings(new_state.columns.crates[crate_id]);
-
- itemsCloned.forEach((elem, _idx) => {
- if (!elem.options_data && !!elem.options) {
- elem.options_data = {}
- }
- });
-
- itemsCloned = FillResources(itemsCloned);
- itemsCloned = TriggerWarnings(itemsCloned);
-
- // update state with rules
- this.setState({
- ...this.state,
- columns: {
- ...new_state.columns,
- crates: {
- ...new_state.columns.crates,
- [crate_id]: {
- ...new_state.columns.crates[crate_id],
- items: itemsCloned,
- warnings: crate_warnings
- },
- }
- }
- });
- }
-
- onAddCrate(id) {
- this.setState({
- ...this.state,
- columns: {
- ...this.state.columns,
- crates: {
- ...this.state.columns.crates,
- [id]: {
- crate_type: "rack",
- items: []
- }}
- }
- });
- }
- onDeleteCrate(id) {
- let new_state = {
- ...this.state,
- columns: {
- ...this.state.columns,
- crates: {
- ...this.state.columns.crates,
- [id]: undefined
- }
- }};
- delete new_state.columns.crates[id];
- this.setState(new_state);
- }
-
- onCrateSelected(id) {
- console.log(id)
- this.setState({
- active_crate: id
- })
- }
-
- onCrateModeChange(crate_id, new_mode) {
- let new_state = {
- ...this.state,
- columns: {
- ...this.state.columns,
- crates: {
- ...this.state.columns.crates,
- [crate_id]: {
- ...this.state.columns.crates[crate_id],
- crate_type: new_mode
- }
- }
- }};
- this.setState(new_state);
- }
-
-
return (
-
+
diff --git a/static/js/shop/shop_store.js b/static/js/shop/shop_store.js
index 124ff57e..96061d5e 100644
--- a/static/js/shop/shop_store.js
+++ b/static/js/shop/shop_store.js
@@ -93,14 +93,21 @@ const useCart = ((set, get) => ({
}
}),
moveCard: (crate_from, index_from, crate_to, index_to) => set(state => {
- const the_card = state.crates.find((crate, _) => crate_from === crate.id )[index_from];
- const del_card = crate_from === crate_to ? 1 : 0;
+ const the_card = state.crates.find((crate, _) => crate_from === crate.id ).items[index_from];
return {
crates: state.crates.map((crate, _i) => {
- if (crate_to === crate.id) {
+ if (crate_to === crate_from && crate_to === crate.id) {
+ //const the_card = {...crate[index_from]};
+ let items_copy = Array.from(crate.items);
+ delete items_copy[index_from];
return {
...crate,
- items: crate.items.toSpliced(index_to, del_card, the_card)
+ items: items_copy.toSpliced(index_to, 0, the_card).filter((item, _) => !!item)
+ }
+ } else if (crate_to === crate.id) {
+ return {
+ ...crate,
+ items: crate.items.toSpliced(index_to, 0, the_card)
}
} else if (crate_from === crate.id) {
return {
diff --git a/static/js/shop/warnings.js b/static/js/shop/warnings.js
index beaca90d..fc325ce1 100644
--- a/static/js/shop/warnings.js
+++ b/static/js/shop/warnings.js
@@ -100,7 +100,7 @@ const Types = {
export function TriggerCardWarnings(data, index, precounted) {
const element = data[index];
- return element.warnings
+ return (element.warnings && element.warnings
.map((warning, _) => {
if (!!Types[warning])
return Types[warning].trigger(data, index, precounted) ? {trigger: undefined, name: warning, ...Types[warning]} : null;
@@ -109,7 +109,7 @@ export function TriggerCardWarnings(data, index, precounted) {
})
.filter((warning, _) => {
return !!warning
- });
+ }));
}
export function TriggerWarnings(data) {