web2019/static/js/shop/shop_store.js

307 lines
9.5 KiB
JavaScript

'use strict';
import {create} from "zustand";
import {data as shared_data, itemsUnfoldedList} from "./utils";
import {true_type_of} from "./options/utils";
import {v4 as uuidv4} from "uuid";
import {FillResources} from "./count_resources";
import {TriggerCrateWarnings, TriggerWarnings} from "./warnings";
import {Validation, validateEmail, validateNote} from "./validate";
import {CratesToJSON} from "./json_porter";
const cards_to_pn_map = (cards) => {
let result = {};
Object.entries(cards).forEach(([key, card], _i) => { result[card.name_number] = key})
return result;
};
const useBacklog = ((set, get) => ({
cards: shared_data.items,
groups: shared_data.columns.backlog,
cards_list: itemsUnfoldedList,
currency: shared_data.currency,
pn_to_cards: cards_to_pn_map(shared_data.items),
getCardDescription: index => get().cards[get().cards_list[index]],
getCardDescriptionByPn: pn => get().cards[get().pn_to_cards[pn]],
cardIndexById: card_id => get().cards_list.findIndex((element) => (card_id === element))
}));
const useCrateModes = ((set, get) => ({
crate_modes: shared_data.crateModes,
modes_order: shared_data.crateModeOrder,
crateParams: mode => get().crate_modes[mode],
}));
const useLayout = ((set, get) => ({
isTouch: window.isTouchEnabled(),
isMobile: window.deviceIsMobile(),
sideMenuIsOpen: false,
newCardJustAdded: false,
importIsOpen: false,
switchSideMenu: () => set(state => ({
sideMenuIsOpen: !state.sideMenuIsOpen
})),
openImport: () => set(state => ({
importIsOpen: true
})),
closeImport: () => set(state => ({
importIsOpen: false
})),
}))
const useSubmitForm = ((set, get) => ({
// TODO think about it
isProcessing: false,
shouldShowRFQFeedback: true,
RFQBodyType: 'email',
isProcessingComplete: true,
email: {
value: "",
error: null
},
note: {
value: "",
error: Validation.OK
},
description: "",
shouldShowDescription: false,
updateEmail: (new_email) => set(state => ({
email: {
value: new_email,
error: validateEmail(new_email)
}
})),
updateNote: (new_notes) => set(state => ({
note: {
value: new_notes,
error: validateNote(new_notes)
}
})),
updateDescription: () => set(state => ({
description: CratesToJSON(state.crates)
})),
showDescription: () => set(state => ({
description: CratesToJSON(state.crates),
shouldShowDescription: true
})),
closeDescription: () => set(state => ({
shouldShowDescription: false
})),
submitForm: () => set(state => ({})) // TODO
}));
const useHighlighted = ((set, get) => ({
highlighted: {
crate: "",
card: 0
},
highlightCard: (crate_id, index) => set(state => ({
highlighted: {
crate: crate_id,
card: index
}
})),
highlightReset: () => set(state => ({
highlighted: {
crate: "",
card: 0
}
})),
}));
const useCart = ((set, get) => ({
crates: shared_data.columns.crates,
active_crate: "crate0",
_newCrate: (crate_id) => set((state) => ({crates: state.crates.concat({
id: crate_id || "crate" + state.crates.length,
crate_mode: "rack",
items: [],
warnings: [],
occupiedHP: 0
})})),
delCrate: (id) => set(state => ({
crates: state.crates.filter((crate => crate.id !== id))
})),
_setCrateMode: (id, mode) => set(state => ({
crates: state.crates.map((crate, _i) => {
if (crate.id === id) {
return {
...crate,
crate_mode: mode
}
} else return crate;
})
})),
setActiveCrate: (id) => set(state => ({active_crate: id})),
_addCardFromBacklog: (crate_to, index_from, index_to) => set(state => {
const take_from = (true_type_of(index_from) === "array" ? index_from : [index_from]).map((item, _i) => (state.cards_list[item]));
const dest = crate_to || state.active_crate;
return {
crates: state.crates.map((crate, _i) => {
if (dest === crate.id) {
index_to = index_to != null ? index_to : crate.items.length;
return {
...crate,
items: crate.items.toSpliced(index_to, 0, ...take_from.map((card_name, _) => {
return {...state.cards[card_name], id: uuidv4()}
}))
}
} else return crate;
})
}
}),
_moveCard: (crate_from, index_from, crate_to, index_to) => set(state => {
console.log(crate_from, index_from, crate_to, index_to)
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_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: items_copy.toSpliced(index_to+1, 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 {
...crate,
items: crate.items.toSpliced(index_to, 1)
}
}
else return crate;
})
}
}),
_deleteCard: (crate_id, index) => set(state => ({
crates: state.crates.map((crate, _i) => {
if (crate_id === crate.id) {
return {
...crate,
items: crate.items.toSpliced(index, 1)
}
}
else return crate;
})
})),
_clearCrate: (id) => set(state => ({
crates: state.crates.map((crate, _i) => {
if (id === crate.id) {
return {
...crate,
items: []
}
}
else return crate;
})
})),
clearAll: () => set(state => ({
crates: []
})),
_updateOptions: (crate_id, index, new_options) => set(state => ({
crates: state.crates.map((crate, _i) => {
if (crate_id === crate.id) {
let itemsCopy = Array.from(crate.items);
itemsCopy[index].options_data = {...itemsCopy[index].options_data, ...new_options};
return {
...crate,
items: itemsCopy
}
}
else return crate;
})
})),
fillWarnings: (crate_id) => set(state => ({
crates: state.crates.map((crate, _i) => {
if (crate_id === crate.id) {
let itemsCopy = Array.from(crate.items);
itemsCopy = FillResources(itemsCopy);
itemsCopy = TriggerWarnings(itemsCopy);
const [crate_warnings, occupied] = TriggerCrateWarnings(crate);
return {
...crate,
items: itemsCopy,
warnings: crate_warnings,
occupiedHP: occupied
}
}
else return crate;
})
})),
totalOrderPrice: () => {
let sum = 0;
get().crates.forEach( (crate, _i) => {
sum += get().crate_modes[crate.crate_mode].price;
crate.items.forEach((item, _) => {
sum += item.price;
});
});
return sum;
},
// Composite actions that require warnings recalculation:
newCrate: () => {
const crate_id = "crate" + get().crates.length;
get()._newCrate(crate_id)
get().fillWarnings(crate_id);
},
setCrateMode: (id, mode) => {
console.log("setCrateMode", id, mode)
get()._setCrateMode(id, mode)
get().fillWarnings(id);
},
addCardFromBacklog: (crate_to, index_from, index_to) => {
const dest = crate_to || get().active_crate;
get()._addCardFromBacklog(dest, index_from, index_to)
get().fillWarnings(dest);
},
moveCard: (crate_from, index_from, crate_to, index_to) => {
get()._moveCard(crate_from, index_from, crate_to, index_to);
get().fillWarnings(crate_to);
if (crate_from !== crate_to) get().fillWarnings(crate_from);
},
deleteCard: (crate_id, index) => {
get()._deleteCard(crate_id, index);
get().fillWarnings(crate_id);
},
clearCrate: (id) => {
get()._clearCrate(id);
get().fillWarnings(id);
},
updateOptions: (crate_id, index, new_options) => {
get()._updateOptions(crate_id, index, new_options);
get().fillWarnings(crate_id);
}
// TODO load and save jsons?
}))
export const useShopStore = create((...params) => ({
...useBacklog(...params),
...useCrateModes(...params),
...useCart(...params),
...useSubmitForm(...params),
...useLayout(...params),
...useHighlighted(...params),
}))