Skip to content

Commit

Permalink
refactor(global): ♻️ add reducer action for adding builderdata
Browse files Browse the repository at this point in the history
now if any builderdata is in reducer then no duplicate builderdata is added

Ref #54
  • Loading branch information
PritamBag committed Dec 30, 2024
1 parent 11e9354 commit e12e00e
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 99 deletions.
9 changes: 8 additions & 1 deletion app/actions/reducer.action.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { AppBuilderData } from "../components/data/app-builder/AppBuilder.data";
import { Property } from "../components/data/toolbox/property/Property.interface";
import { ToolBoxData } from "../components/data/toolbox/ToolBox.data";
import {
ADD_ATTRIBUTE, BUILDER_HISTORY, ADD_ATTRIBUTE_FROM_MODEL_SCHEMA, SET_MODEL_SCHEMAS, SET_TOOLBOX_CONTENT, SET_TOOLBOX_DATA, SET_VIEWER_GROUP_DATA, UPDATE_BUTTON_NAME, UPDATE_ENTITY_DISPLAY_PROPS
ADD_ATTRIBUTE, BUILDER_HISTORY, ADD_ATTRIBUTE_FROM_MODEL_SCHEMA, SET_MODEL_SCHEMAS, SET_TOOLBOX_CONTENT, SET_TOOLBOX_DATA, SET_VIEWER_GROUP_DATA, UPDATE_BUTTON_NAME, UPDATE_ENTITY_DISPLAY_PROPS,
ADD_APP_BUILDER_DATA_TO_REDUCER
} from "../types/builder.types";

export const builderHistory = (data:any, CRUD:string)=>({
Expand Down Expand Up @@ -59,3 +61,8 @@ export const selectedAttribute = (id: string) => ({
payload: { id },
type : UPDATE_ENTITY_DISPLAY_PROPS,
});

export const addAppBuilderDataToReducer = (data: AppBuilderData, builderData: any) => ({
payload: { builderData, data },
type : ADD_APP_BUILDER_DATA_TO_REDUCER,
});
7 changes: 6 additions & 1 deletion app/components/AppBuilder.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable etc/no-commented-out-code */
import React from "react";
import React, { useEffect } from "react";

import { CoreLayoutItem, AppBuilderContainerLayout, coreUseLocation } from "@wrappid/core";
import { useDispatch } from "react-redux";
Expand All @@ -9,6 +9,7 @@ import HeaderComp from "./Header";
import ToolBoxGroup from "./toolbox/ToolBoxGroup";
import GetDataFromReducer from "./UtilityFunction";
import ViewerGroup from "./viewers/ViewerGroup";
import { addAppBuilderDataToReducer } from "../actions/reducer.action";
import AppBuilderFactory from "../factory/AppBuilder.factory";

interface DynamicSchema {
Expand Down Expand Up @@ -65,6 +66,10 @@ export default function AppBuilder<T extends AppBuilderData>() {
const dispatch = useDispatch();

const appBuilderData:T = AppBuilderFactory.getAppBuilderData(builderType);

useEffect(() => {
dispatch(addAppBuilderDataToReducer(appBuilderData, data));
}, []);

const viewerData = appBuilderData.getViewers();

Expand Down
14 changes: 13 additions & 1 deletion app/components/data/app-builder/AppBuilder.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import { ViewerData } from "../viewer/Viewer.data";
/** An abstract base class for managing builder data in application builders. */
export abstract class AppBuilderData {

private builderId:string;
readonly builderId:string;

private builderData: any;

readonly builderType: typeof AppBuilderFactory.BUILDER_TYPES[keyof typeof AppBuilderFactory.BUILDER_TYPES];
/** Private property to store toolbox-related data. */
private toolboxes: ToolBoxData[] = [];
Expand All @@ -36,6 +39,15 @@ export abstract class AppBuilderData {
this.prepareViewers();
}

getBuilderData() {
return this.builderData;
}

// Setter for builderData
setBuilderData(data: any) {
this.builderData = data;
}

/**
* Prepare toolboxes - should be called after child class properties are set
*/
Expand Down
151 changes: 56 additions & 95 deletions app/reducers/builder.reducer.ts
Original file line number Diff line number Diff line change
@@ -1,114 +1,75 @@
import { getWrappidUUID } from "@wrappid/core/utils/appUtils";

import { ReducerAttributeData } from "./ReducerAttribute.data";
import { AppBuilderData } from "../components/data/app-builder/AppBuilder.data";
import ValidProps from "../components/data/valid-props/Validprops";
import AppBuilderFactory from "../factory/AppBuilder.factory";
import { ADD_ATTRIBUTE, ADD_ATTRIBUTE_FROM_MODEL_SCHEMA, SET_MODEL_SCHEMAS, UPDATE_ENTITY_DISPLAY_PROPS } from "../types/builder.types";
import { ADD_APP_BUILDER_DATA_TO_REDUCER } from "../types/builder.types";

interface BuilderState {
appBuilderData: AppBuilderData[];
attributeData: ReducerAttributeData;
modelSchema?: object;
}

const initialState: BuilderState = {
appBuilderData: [AppBuilderFactory.getAppBuilderData(AppBuilderFactory.BUILDER_TYPES.FORM), AppBuilderFactory.getAppBuilderData(AppBuilderFactory.BUILDER_TYPES.MODEL), AppBuilderFactory.getAppBuilderData(AppBuilderFactory.BUILDER_TYPES.PAGE)],
attributeData : new ReducerAttributeData(),
modelSchema : {}
const initialState: BuilderState = { appBuilderData: [] };

const recreateBuilderInstance = (builderData: any): AppBuilderData => {
// Create new instance using the stored data
const builder = AppBuilderFactory.getAppBuilderData(builderData.builderType);

// Restore all the data from the stored object
if (builderData.builderData) {
builder.setBuilderData(builderData.builderData);
}

return builder;
};

const builderOptions = (state = initialState, action: any) => {
const builderOptions = (state = initialState, action: any): BuilderState => {
switch (action.type) {

case SET_MODEL_SCHEMAS: {
return {
...state,
modelSchema: action.payload
};
}

// case SET_TOOLBOX_CONTENT: {
// const { toolboxContent } = action.payload;

// return {
// ...state,
// appBuilderData: state.appBuilderData.map(builder => {
// if (builder.builderType.includes(AppBuilderFactory.BUILDER_TYPES.MODEL)) {
// const toolboxes = builder.getToolBoxes();

// toolboxes.forEach(toolbox => {
// if (toolbox.variant === "property") {
// toolbox.setToolBoxContent(toolboxContent);
// }
// });
// }
// return builder;
// })
// };
// }

case ADD_ATTRIBUTE: {
const { validPropsForAllAttribute } = action.payload;
const newAttribute = {
attributeSelected: false,
id : getWrappidUUID(),
selectedProps : {},
validProps : [...validPropsForAllAttribute]
};

return {
...state,
attributeData: {
...state.attributeData,
ButtonAttribute: [...state.attributeData.ButtonAttribute, newAttribute]
}
};
}

case ADD_ATTRIBUTE_FROM_MODEL_SCHEMA: {
const { attributesOfModelSchema } = action.payload;

// Convert the model schema attributes into the desired format
const newAttributes = attributesOfModelSchema.map((attr: any) => {
const selectedProps = Object.entries(attr).reduce((acc: { [key: string]: any }, [key, value]) => {
acc[key] = value;
return acc;
}, {});

// Generate validProps using ValidProps.getValidProps() for each attribute's selectedProps
const validPropsInstance = new ValidProps();
const validProps = validPropsInstance.getValidProps();

return {
attributeSelected: false,
id : getWrappidUUID(),
selectedProps : selectedProps,
validProps : validProps,
};
case ADD_APP_BUILDER_DATA_TO_REDUCER: {
const { data, builderData } = action.payload;

// Recreate instances for existing builders to ensure methods are available
const currentBuilders = state.appBuilderData.map(builder =>
recreateBuilderInstance(builder)
);

// Check if builderId already exists
const isBuilderIdExists = currentBuilders.some(
(builder) => builder.builderId === data.builderId
);

if (isBuilderIdExists) {
// eslint-disable-next-line no-console
console.warn(
`Duplicate builderId detected: ${data.builderId}`
);
return state;
}

// Check if the same data exists in any builder's data
const isDataExistsGlobally = currentBuilders.some((builder) => {
const existingBuilderData = builder.getBuilderData();

if (!existingBuilderData) return false;

return existingBuilderData.some(
(existingData) =>
existingData.id === builderData.id &&
existingData.name === builderData.name
);
});

return {
...state,
attributeData: {
...state.attributeData,
ButtonAttribute: [...newAttributes]
}
};
}
if (isDataExistsGlobally) {
// eslint-disable-next-line no-console
console.warn(
`Duplicate data detected for id: ${builderData.id} and name: ${builderData.name}`
);
return state;
}

case UPDATE_ENTITY_DISPLAY_PROPS: {
const { id } = action.payload;
// Set the new data
data.setBuilderData([builderData]);

return {
...state,
attributeData: {
...state.attributeData,
ButtonAttribute: state.attributeData.ButtonAttribute.map(attr => ({
...attr,
attributeSelected: attr.id === id
}))
}
appBuilderData: [...state.appBuilderData, data]
};
}

Expand Down
4 changes: 3 additions & 1 deletion app/types/builder.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ export const SET_MODEL_SCHEMAS = "SET_MODEL_SCHEMAS";
export const ADD_ATTRIBUTE_FROM_MODEL_SCHEMA = "ADD_ATTRIBUTE_FROM_MODEL_SCHEMA";
export const BUILDER_HISTORY = "BUILDER_HISTORY";
export const CURRENT_POINTER_INC = "CURRENT_POINTER_INC";
export const CURRENT_POINTER_DEC = "CURRENT_POINTER_DEC";
export const CURRENT_POINTER_DEC = "CURRENT_POINTER_DEC";

export const ADD_APP_BUILDER_DATA_TO_REDUCER = "ADD_APP_BUILDER_DATA_TO_REDUCER";

0 comments on commit e12e00e

Please sign in to comment.