web2019/static/js/shop/shop_store.js
Egor Savkin 9edf410e4d Start refactor to state manager zustand
Signed-off-by: Egor Savkin <es@m-labs.hk>
2024-01-09 10:14:53 +08:00

192 lines
5.8 KiB
JavaScript

'use strict';
import {create} from "zustand";
import {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";
const useBacklog = ((set, get) => ({
cards: data.items,
groups: data.columns.backlog,
cards_list: itemsUnfoldedList,
currency: data.currency
}));
const useCrateModes = ((set, get) => ({
crate_modes: data.crateModes,
modes_order: data.crateModeOrder
}));
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,
}));
const useCart = ((set, get) => ({
crates: data.columns.crates,
active_crate: "crate0",
highlighted: {
crate: "",
card: 0
},
newCrate: () => set((state) => ({crates: state.crates.concat({
id: "crate"+state.crates.length,
crate_mode: "rack",
items: [],
warnings: []
})})),
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) {
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 => {
const the_card = state.crates.find((crate, _) => crate_from === crate.id )[index_from];
const del_card = crate_from === crate_to ? 1 : 0;
return {
crates: state.crates.map((crate, _i) => {
if (crate_to === crate.id) {
return {
...crate,
items: crate.items.toSpliced(index_to, del_card, the_card)
}
} else if (crate_from === crate.id) {
return {
...crate,
items: crate.items.toSpliced(index_to, 1)
}
}
else return crate;
})
}
}),
deleteCard: (crate, index) => set(state => ({
crates: state.crates.map((crate, _i) => {
if (crate === crate.id) {
return {
...crate,
items: crate.items.splice(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;
})
})),
updateOptions: (crate, index, new_options) => set(state => ({
crates: state.crates.map((crate, _i) => {
if (crate === 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;
})
})),
highlightCard: (crate, index) => set(state => ({
highlighted: {
crate: crate,
card: index
}
})),
highlightReset: () => set(state => ({
highlighted: {
crate: "",
card: 0
}
})),
fillWarnings: (crate) => set(state => ({
// actually seems to be just render-time action, no need to put data in it,
// though needs to be optimized to be done only on real crate updates
crates: state.crates.map((crate, _i) => {
if (crate === crate.id) {
let itemsCopy = Array.from(crate.items);
itemsCopy = FillResources(itemsCopy);
itemsCopy = TriggerWarnings(itemsCopy);
const crate_warnings = TriggerCrateWarnings(crate);
return {
...crate,
items: itemsCopy,
warnings: crate_warnings
}
}
else return crate;
})
}))
// TODO load and save jsons?
}))
export const useShopStore = create((...params) => ({
...useBacklog(...params),
...useCrateModes(...params),
...useCart(...params),
...useSubmitForm(...params),
...useLayout(...params)
}))