diff --git a/app/actions/builder.actions.ts b/app/actions/builder.actions.ts index 3c89d51..84a4f7b 100644 --- a/app/actions/builder.actions.ts +++ b/app/actions/builder.actions.ts @@ -1,6 +1,7 @@ -import { AppBuilderData } from "../components/data/app-builder/AppBuilder.data"; +import { EntityData } from "../components/data/entity/Entity.data"; import { BuilderState } from "../reducers/builder.reducer"; -import { ADD_ATTRIBUTE, ADD_BUILDER_DATA, SELECTED_BUILDER } from "../types/builder.types"; +import { ADD_ATTRIBUTE, ADD_OR_SELECT_BUILDER_DATA, SELECTED_BUILDER } from "../types/builder.types"; +import { BuilderEntitySchema } from "../utils/UtilityFunction"; // export const setBuilderData_Case1 = (data: {[key: string]: string}) => (dispatch) => { // dispatch({ @@ -9,77 +10,17 @@ import { ADD_ATTRIBUTE, ADD_BUILDER_DATA, SELECTED_BUILDER } from "../types/buil // }); // }; -// export const setBuilderData = (builderData: AppBuilderData, entityData: DynamicEntity) => { -// return { -// payload: { builderData, entityData }, -// type : SET_BUILDER_DATA -// }; -// }; - -// export const setBuilderData = (builderData: AppBuilderData, entityData: DynamicEntity, currentState: BuilderState) => { -// const existingBuilderIndex = currentState.appBuilderData.findIndex( -// (data) => data.builderId === builderData.builderId -// ); - -// eslint-disable-next-line etc/no-commented-out-code -// let updatedAppBuilderData; - -// if (existingBuilderIndex > -1) { -// // Update existing builderData's entityData -// updatedAppBuilderData = currentState.appBuilderData.map((data, index) => -// index === existingBuilderIndex ? { ...data, entityData } : data -// ); -// } else { -// // Add new builderData to the state -// updatedAppBuilderData = [...currentState.appBuilderData, { ...builderData, entityData }]; -// } - -// return { -// payload: { appBuilderData: updatedAppBuilderData }, -// type : SET_BUILDER_DATA -// }; -// }; - -// export const addBuilderData = (builderData: AppBuilderData, entityData: EntityData, currentState: BuilderState) => { -// const existingBuilderIndex = currentState.appBuilderData.findIndex( -// (data) => data.builderId === builderData.builderId -// ); - -// eslint-disable-next-line etc/no-commented-out-code -// let updatedAppBuilderData; - -// if (existingBuilderIndex > -1) { -// // Update existing builderData's entityData using the setter method -// updatedAppBuilderData = currentState.appBuilderData.map((data, index) => { -// if (index === existingBuilderIndex) { -// // Directly update the entityData using the setter -// data.setEntityData(entityData); // Use setter to update entityData -// } -// return data; -// }); -// } else { -// // Add new builderData to the state and set entityData -// builderData.setEntityData(entityData); -// updatedAppBuilderData = [...currentState.appBuilderData, builderData]; -// } - -// return { -// payload: { appBuilderData: updatedAppBuilderData }, -// type : SET_BUILDER_DATA -// }; -// }; - -export const addBuilderData = (builderData: AppBuilderData) => { +export const selectBuilderData = (builderId: string) => { return { - payload: { appBuilderData: builderData }, - type : ADD_BUILDER_DATA + payload: { builderId }, + type : SELECTED_BUILDER }; }; -export const selectBuilderData = (builderId: string) => { +export const addOrSelectBuilder = (entityID: number, entityData: EntityData, builderType: string) => { return { - payload: { builderId }, - type : SELECTED_BUILDER + payload: { builderType, entityData, entityID }, + type : ADD_OR_SELECT_BUILDER_DATA }; }; diff --git a/app/components/AppBuilder.tsx b/app/components/AppBuilder.tsx index 8d88c41..171d914 100644 --- a/app/components/AppBuilder.tsx +++ b/app/components/AppBuilder.tsx @@ -10,7 +10,7 @@ import { AppBuilderData } from "./data/app-builder/AppBuilder.data"; import ToolbarGroup from "./toolbar/ToolbarGroup"; import ToolBoxGroup from "./toolbox/ToolBoxGroup"; import ViewerGroup from "./viewer/ViewerGroup"; -import { addBuilderData } from "../actions/builder.actions"; +import { addOrSelectBuilder } from "../actions/builder.actions"; import { CLOSE, CLOSE_FUNCTIONALITY_COMMING_SOON, PRIMARY, SMALL } from "../constants/AppBuilder.constant"; import AppBuilderFactory from "../factory/AppBuilder.factory"; import ModuleClasses from "../styles/ModuleClasses"; @@ -25,20 +25,22 @@ export default function AppBuilder() { const { state } = coreUseLocation(); const dispatch = useDispatch(); - const appBuilderDataFromStore = useSelector((state: any) => state.BuilderOptions?.appBuilderData); + const { appBuilderData: appBuilderDataFromStore } = useSelector((state: any) => state.BuilderOptions); const [entityData, setEntityData] = useState(null); const [builderType, setBuilderType] = useState(null); - const [selectedEntitySchema, setSelectedEntitySchema] = useState(null); - // const selectedEntitySchema = getBuilderEntitySchemaInterface(builderType); const [selectedBuilder, setSelectedBuilder] = useState(null); const [selectedViewerData, setSelectedViewerData] = useState(null); const [selectedToolboxData, setSelectedToolboxData] = useState(null); const [selectedToolbarData, setSelectedToolbarData] = useState(null); - // const [newBuilderDataInitialized, setNewBuilderDataInitialized] = useState(false); - const newBuilderDataInitialized = useRef(false); + const isSelectedBuilder = useRef(false); + /** + * Make the builder selected + * + * @param builderId + */ function handleTabSelect(builderId: string){ if(builderId/** @todo check if builder id exist */){ // dispatch(selectBuilderData(builderId)); @@ -47,68 +49,40 @@ export default function AppBuilder() { } } - /** - * - * @todo we need to recheck the function since appBuilderData from store is not getting updated after dispatch - */ - const checkIfBuilderExist = () => { - // check builderData.id - const builderData = appBuilderDataFromStore?.find( - (_builderData) => { - // const _entityData: EntityData = _builderData.getEntityData(); - - return _builderData.builderType === builderType && _builderData?.entityData?.id === entityData?.id; - }); - - if(builderData) { - return true; - } - - return false; - }; - useEffect(() => { - if( !newBuilderDataInitialized.current && builderType && entityData && entityData?.id > 0 && !checkIfBuilderExist()){ - const appBuilderData: AppBuilderData = AppBuilderFactory.getAppBuilderData>(builderType, entityData); - - // Object.setPrototypeOf(appBuilderData, AppBuilderData.prototype); - appBuilderData.setSelected(true); - dispatch(addBuilderData(appBuilderData)); - // setNewBuilderDataInitialized(true); - newBuilderDataInitialized.current = true; - } - }, [builderType, entityData, dispatch]); + /* In this useEffect we will set the builderType and entityData */ - useEffect(() => { - /** When location state value changes we will set the selected builder info */ if(!builderType || !entityData || entityData?.id <= 0 ){ - + // when builderType, entityData or entityData not greater than 0 + if (state && (state as AppBuilderState).data && (state as AppBuilderState).builderType){ + /* when state and state has data and builderType */ const typedState = state as AppBuilderState; setBuilderType(typedState.builderType); setEntityData(typedState.data); - // setSelectedEntitySchema(getBuilderEntitySchemaInterface(typedState.builderType)); } else { + /* when state is undefined or state has no data or builderType */ const currentBuilderData: AppBuilderData = appBuilderDataFromStore[0]; - // Object.setPrototypeOf(currentBuilderData, AppBuilderData.prototype); setBuilderType(currentBuilderData?.getBuilderType()); setEntityData(currentBuilderData?.getEntityData()); - // setSelectedEntitySchema(getBuilderEntitySchemaInterface(currentBuilderData?.getBuilderType())); } } else { - // if( !newBuilderDataInitialized.current && builderType && entityData && entityData?.id > 0 && !checkIfBuilderExist()){ - // const appBuilderData: AppBuilderData = AppBuilderFactory.getAppBuilderData>(builderType, entityData); - - // // Object.setPrototypeOf(appBuilderData, AppBuilderData.prototype); - // appBuilderData.setSelected(true); - // dispatch(addBuilderData(appBuilderData)); - // // setNewBuilderDataInitialized(true); - // newBuilderDataInitialized.current = true; - // } + // do nothing } }, [state, appBuilderDataFromStore, builderType, entityData]); + + useEffect(() => { + /* In this useEffect we will set the selected builder data */ + if(!isSelectedBuilder.current && builderType && entityData && entityData?.id > 0){ + /* if builder is not initialized and builderType and entityData is valid */ + dispatch(addOrSelectBuilder(entityData.id, entityData, builderType)); + isSelectedBuilder.current = true; + } else { + // do nothing + } + }, [isSelectedBuilder, builderType, entityData, dispatch]); useEffect(() => { if(selectedBuilder) { @@ -119,7 +93,7 @@ export default function AppBuilder() { setSelectedViewerData(_selectedBuilder.getViewers()); setSelectedToolboxData(_selectedBuilder.getToolBoxes()); setSelectedToolbarData(_selectedBuilder.getToolbars()); - } else{ + } else { setSelectedBuilder( appBuilderDataFromStore?.find( /** @todo type casting is not valid we need to fix and remove set prototype */ diff --git a/app/components/data/viewer/json/JsonViewer.data.ts b/app/components/data/viewer/json/JsonViewer.data.ts index ae8c5b5..b27ebc5 100644 --- a/app/components/data/viewer/json/JsonViewer.data.ts +++ b/app/components/data/viewer/json/JsonViewer.data.ts @@ -16,6 +16,7 @@ export class JsonViewerData extends ViewerData{ } prepareViewerContent(entityData: EntityData): void { - this.viewerContent = entityData?.getSchema(); + Object.setPrototypeOf(entityData, EntityData.prototype); + this.viewerContent = entityData.getSchema(); } } \ No newline at end of file diff --git a/app/reducers/builder.reducer.ts b/app/reducers/builder.reducer.ts index 7ba877d..34b19bc 100644 --- a/app/reducers/builder.reducer.ts +++ b/app/reducers/builder.reducer.ts @@ -1,5 +1,8 @@ import { AppBuilderData } from "../components/data/app-builder/AppBuilder.data"; -import { ADD_BUILDER_DATA, SELECTED_BUILDER, SET_BUILDER_DATA } from "../types/builder.types"; +import { EntityData } from "../components/data/entity/Entity.data"; +import AppBuilderFactory from "../factory/AppBuilder.factory"; +import { ADD_OR_SELECT_BUILDER_DATA, SET_BUILDER_DATA } from "../types/builder.types"; +import { BuilderEntitySchema } from "../utils/UtilityFunction"; export interface BuilderState { /** @todo Entity schema needs to be created and placed in place of any in the following line */ @@ -16,34 +19,62 @@ const builderOptions = (state = initialState, action: {type: string, payload: an appBuilderData: action.payload.appBuilderData, }; - case ADD_BUILDER_DATA: - /** make all others builder not selected */ + case ADD_OR_SELECT_BUILDER_DATA: // eslint-disable-next-line no-case-declarations - const builderData = state.appBuilderData; + let found = false; + // eslint-disable-next-line no-case-declarations + const updatedBuilderData = state.appBuilderData; + + updatedBuilderData.forEach((builder) => { + Object.setPrototypeOf(builder, AppBuilderData.prototype); + const entityData = builder.getEntityData(); + + Object.setPrototypeOf(entityData, EntityData.prototype); - builderData.forEach((builder) => { - builder.setSelected(false); + const payloadEnityData = action.payload.entityData; + + if(entityData.getId() === payloadEnityData?.id) { + builder.setSelected(true); + found = true; + } else { + builder.setSelected(false); + } }); - if(!state.appBuilderData.find((_builderData) => { - return _builderData.getEntityData().getId() === action.payload.appBuilderData?.entityData?.id; - })){ - builderData.push(action.payload.appBuilderData); + if(!found){ + const { builderType, entityData } = action.payload; + const newBuilder: AppBuilderData = AppBuilderFactory.getAppBuilderData>(builderType, entityData); + + Object.setPrototypeOf(newBuilder, AppBuilderData.prototype); + newBuilder.setSelected(true); + + updatedBuilderData.push(newBuilder); } - return { - ...state, - appBuilderData: builderData - }; - case SELECTED_BUILDER: return { ...state, - appBuilderData: state.appBuilderData.map((builderData) => { - builderData.setSelected(builderData.builderId === action.payload.builderId); - return builderData; - }), + appBuilderData: JSON.parse(JSON.stringify(updatedBuilderData)), }; + // case SELECTED_BUILDER: + // return { + // ...state, + // appBuilderData: state.appBuilderData.map((builderData) => { + // Object.setPrototypeOf(builderData, AppBuilderData.prototype); + // // builderData.setSelected(builderData.builderId === action.payload.builderId); + // if (builderData.builderId === action.payload.builderId) { + // // Only set selected to true if it's not already true + // if (!builderData.isSelected()) { + // builderData.setSelected(true); + // } + // } else { + // // Set all other builders to unselected + // builderData.setSelected(false); + // } + // return builderData; + // }), + // }; + default: return state; } diff --git a/app/types/builder.types.ts b/app/types/builder.types.ts index 8a3b8bd..cda2ecf 100644 --- a/app/types/builder.types.ts +++ b/app/types/builder.types.ts @@ -15,4 +15,5 @@ export const BUILDER_DATA_CASE_1 = "BUILDER_DATA_CASE_1"; export const SET_BUILDER_DATA = "SET_BUILDER_DATA"; export const ADD_BUILDER_DATA = "ADD_BUILDER_DATA"; -export const SELECTED_BUILDER = "SELECTED_BUILDER"; \ No newline at end of file +export const SELECTED_BUILDER = "SELECTED_BUILDER"; +export const ADD_OR_SELECT_BUILDER_DATA = "ADD_OR_SELECT_BUILDER_DATA"; \ No newline at end of file