From 69c83d33b1bb6c2349787983edf37aa55db1f0ae Mon Sep 17 00:00:00 2001 From: Kurt Hutten Date: Sun, 12 Sep 2021 19:54:31 +1000 Subject: [PATCH] State controlled tray mvp --- .../src/components/IdeSideBar/IdeSideBar.tsx | 28 ++- .../components/IdeSideBar/sidebarConfig.tsx | 26 ++- app/web/src/helpers/hooks/useIdeState.ts | 198 ++++++++++-------- 3 files changed, 138 insertions(+), 114 deletions(-) diff --git a/app/web/src/components/IdeSideBar/IdeSideBar.tsx b/app/web/src/components/IdeSideBar/IdeSideBar.tsx index b92ab3c..666b37c 100644 --- a/app/web/src/components/IdeSideBar/IdeSideBar.tsx +++ b/app/web/src/components/IdeSideBar/IdeSideBar.tsx @@ -1,6 +1,7 @@ import { useState } from 'react' import Svg from 'src/components/Svg/Svg' import { sidebarTopConfig, sidebarBottomConfig, sidebarCombinedConfig } from './sidebarConfig' +import { useIdeContext } from 'src/helpers/hooks/useIdeContext' function TabToggle({ item, className = "", active, onChange, onClick }) { return ( @@ -20,29 +21,24 @@ function TabToggle({ item, className = "", active, onChange, onClick }) { } const IdeSideBar = () => { - const [selectedTab, setSelectedTab] = useState("") - const [lastOpen, setLastOpen] = useState("") + const { state, thunkDispatch } = useIdeContext() function onTabClick(name) { return function() { - if (selectedTab === name) { - setLastOpen(selectedTab) - setSelectedTab("") - } else if (selectedTab === "" && lastOpen === name) { - setSelectedTab(name) - } + thunkDispatch({type: 'settingsButtonClicked', payload: [name]}) } } + const selectedTab = React.useMemo(() => sidebarCombinedConfig.find(item => item.name === state.sideTray[0]), [state.sideTray]) return ( -
+
{ sidebarTopConfig.map((topItem, i) => ( setSelectedTab(topItem.name) } + active={ state.sideTray[0] === topItem.name } + onChange={ () => onTabClick(topItem.name) } onClick={ onTabClick(topItem.name) } key={ 'tab-' + i } /> @@ -52,18 +48,18 @@ const IdeSideBar = () => { { sidebarBottomConfig.map((bottomItem, i) => ( setSelectedTab(bottomItem.name) } + active={ state.sideTray[0] === bottomItem.name } + onChange={ () => onTabClick(bottomItem.name) } onClick={ onTabClick(bottomItem.name) } key={ 'tab-' + (sidebarTopConfig.length+i) } /> ))}
- { sidebarCombinedConfig.find(item => item.name === selectedTab)?.panel && ( + { selectedTab?.panel && (
-

{ selectedTab }

- { sidebarCombinedConfig.find(item => item.name === selectedTab).panel } +

{ selectedTab.name }

+ { selectedTab.panel }
) }
diff --git a/app/web/src/components/IdeSideBar/sidebarConfig.tsx b/app/web/src/components/IdeSideBar/sidebarConfig.tsx index a4bfed4..9015091 100644 --- a/app/web/src/components/IdeSideBar/sidebarConfig.tsx +++ b/app/web/src/components/IdeSideBar/sidebarConfig.tsx @@ -1,5 +1,6 @@ import React, { ReactNode } from 'react' import { SvgNames } from 'src/components/Svg/Svg' +import { useIdeContext } from 'src/helpers/hooks/useIdeContext' interface SidebarConfigType { name: string, @@ -67,7 +68,7 @@ export const sidebarBottomConfig : SidebarConfigType[] = [ name: 'Settings', icon: 'gear', disabled: false, - panel: , + panel: , }, ] @@ -76,15 +77,26 @@ export const sidebarCombinedConfig = [ ...sidebarBottomConfig, ] -function SettingsMenu() { +function SettingsMenu({parentName}: {parentName: string}) { + const { state, thunkDispatch } = useIdeContext() return (
{ settingsConfig.map(item => ( -
- { item.title } - { item.content } -
+
  • + + { state.sideTray.slice(-1)[0] === item.name && item.content } +
  • + //
    + // thunkDispatch((dispatch) => dispatch({type: 'settingsButtonClicked', payload:[parentName, item.name]}))} + // >{ item.title }hi there + // { state.sideTray.slice(-1)[0] === item.name && item.content } + // {state.sideTray.slice(-1)[0]} + //
    ))}
    ) -} \ No newline at end of file +} diff --git a/app/web/src/helpers/hooks/useIdeState.ts b/app/web/src/helpers/hooks/useIdeState.ts index 8945841..3e23c3c 100644 --- a/app/web/src/helpers/hooks/useIdeState.ts +++ b/app/web/src/helpers/hooks/useIdeState.ts @@ -115,6 +115,7 @@ export interface State { viewerSize: { width: number; height: number } isLoading: boolean threeInstance: RootState + sideTray: string[] // could probably be an array of a union type } const code = '' @@ -146,103 +147,118 @@ export const initialState: State = { viewerSize: { width: 0, height: 0 }, isLoading: false, threeInstance: null, + sideTray: [], } -export const useIdeState = (): [State, (actionOrThunk: any) => any] => { - const reducer = (state: State, { type, payload }): State => { - switch (type) { - case 'initIde': +const reducer = (state: State, { type, payload }): State => { + console.log('reducing') + switch (type) { + case 'initIde': + return { + ...state, + code: + payload.code || + // localStorage.getItem(makeCodeStoreKey(payload.cadPackage)) || + initCodeMap[payload.cadPackage] || + '', + ideType: payload.cadPackage, + } + case 'updateCode': + return { ...state, code: payload } + case 'healthyRender': + const customizerParams: CadhubParams[] = payload?.customizerParams?.length + ? payload.customizerParams + : state.customizerParams + const currentParameters = {} + customizerParams.forEach((param) => { + currentParameters[param.name] = + typeof state?.currentParameters?.[param.name] !== 'undefined' + ? state?.currentParameters?.[param.name] + : param.initial + }) + return { + ...state, + objectData: { + ...state.objectData, + type: payload.objectData?.type, + data: payload.objectData?.data, + }, + customizerParams, + currentParameters, + consoleMessages: payload.message + ? [...state.consoleMessages, payload.message] + : payload.message, + isLoading: false, + } + case 'errorRender': + return { + ...state, + consoleMessages: payload.message + ? [...state.consoleMessages, payload.message] + : payload.message, + isLoading: false, + } + case 'setCurrentCustomizerParams': + if (!Object.keys(payload || {}).length) return state + return { + ...state, + currentParameters: payload, + } + case 'setLayout': + return { + ...state, + layout: payload.message, + } + case 'updateCamera': + return { + ...state, + camera: payload.camera, + } + case 'updateViewerSize': + return { + ...state, + viewerSize: payload.viewerSize, + } + case 'setLoading': + return { + ...state, + isLoading: true, + } + case 'resetLoading': + return { + ...state, + isLoading: false, + } + case 'resetLayout': + return { + ...state, + layout: initialLayout, + } + case 'setThreeInstance': + return { + ...state, + threeInstance: payload, + } + case 'settingsButtonClicked': + const isReClick = + state.sideTray.length && + state.sideTray.length === payload.length && + state.sideTray.every((original, index) => original === payload[index]) + if (isReClick) { return { ...state, - code: - payload.code || - // localStorage.getItem(makeCodeStoreKey(payload.cadPackage)) || - initCodeMap[payload.cadPackage] || - '', - ideType: payload.cadPackage, + sideTray: state.sideTray.slice(0, -1), } - case 'updateCode': - return { ...state, code: payload } - case 'healthyRender': - const customizerParams: CadhubParams[] = payload?.customizerParams - ?.length - ? payload.customizerParams - : state.customizerParams - const currentParameters = {} - customizerParams.forEach((param) => { - currentParameters[param.name] = - typeof state?.currentParameters?.[param.name] !== 'undefined' - ? state?.currentParameters?.[param.name] - : param.initial - }) - return { - ...state, - objectData: { - ...state.objectData, - type: payload.objectData?.type, - data: payload.objectData?.data, - }, - customizerParams, - currentParameters, - consoleMessages: payload.message - ? [...state.consoleMessages, payload.message] - : payload.message, - isLoading: false, - } - case 'errorRender': - return { - ...state, - consoleMessages: payload.message - ? [...state.consoleMessages, payload.message] - : payload.message, - isLoading: false, - } - case 'setCurrentCustomizerParams': - if (!Object.keys(payload || {}).length) return state - return { - ...state, - currentParameters: payload, - } - case 'setLayout': - return { - ...state, - layout: payload.message, - } - case 'updateCamera': - return { - ...state, - camera: payload.camera, - } - case 'updateViewerSize': - return { - ...state, - viewerSize: payload.viewerSize, - } - case 'setLoading': - return { - ...state, - isLoading: true, - } - case 'resetLoading': - return { - ...state, - isLoading: false, - } - case 'resetLayout': - return { - ...state, - layout: initialLayout, - } - case 'setThreeInstance': - return { - ...state, - threeInstance: payload, - } - default: - return state - } + } + return { + ...state, + sideTray: payload, + } + default: + return state } - +} +export const useIdeState = (): [State, (actionOrThunk: any) => any] => { const [state, dispatch] = useReducer(reducer, initialState) mutableState = state const getState = (): State => mutableState