Skip to content

Commit

Permalink
feat(global): ✨ add style class in JSON
Browse files Browse the repository at this point in the history
now we can add style class for any component and we can see those in JSON

Ref: #54
  • Loading branch information
PritamBag committed Oct 9, 2024
1 parent ae47e11 commit e4d9381
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 92 deletions.
73 changes: 72 additions & 1 deletion app/actions/test.action.js
Original file line number Diff line number Diff line change
@@ -1,73 +1,144 @@
import {
ADD_COMPONENT, ADD_COMPONENT_PROP, REMOVE_COMPONENT, RESET_TEST, SELECT_LAYOUT, SET_ACTIVE_BOX, SET_PROPS_COMPONENT_PATH, SET_SELECTED_COMPONENT_PATH, TEST_FAILURE, TEST_SUCCESS,
ADD_COMPONENT,
ADD_COMPONENT_PROP,
REMOVE_COMPONENT,
RESET_TEST,
SELECT_LAYOUT,
SET_ACTIVE_BOX,
SET_PROPS_COMPONENT_PATH,
SET_SELECTED_COMPONENT_PATH,
TEST_FAILURE,
TEST_SUCCESS,
TOGGLE_PROP_SELECTOR,
UPDATE_COMPONENT_PROPS,
UPDATE_COMPONENT_STYLE_CLASSES
} from "../types/test.types";

/**
* Dispatches a successful test action.
*/
export const testSuccess = () => {
return (dispatch) => {
dispatch({ type: TEST_SUCCESS });
};
};

/**
* Dispatches a failed test action.
*/
export const testFailure = () => {
return (dispatch) => {
dispatch({ type: TEST_FAILURE });
};
};

/**
* Resets the test state.
*/
export const resetTest = () => {
return (dispatch) => {
dispatch({ type: RESET_TEST });
};
};

/**
* Removes a component by ID.
* @param {string} componentId - The ID of the component to remove.
* @returns {Object} The action object.
*/
export const removeComponent = (componentId) => ({
payload: componentId,
type : REMOVE_COMPONENT
});

/**
* Selects a layout.
* @param {string} layout - The selected layout.
* @returns {Object} The action object.
*/
export const selectLayout = (layout) => ({
payload: layout,
type : SELECT_LAYOUT
});

/**
* Sets the active box index.
* @param {number} boxIndex - The index of the active box.
* @returns {Object} The action object.
*/
export const setActiveBox = (boxIndex) => ({
payload: boxIndex,
type : SET_ACTIVE_BOX
});

/**
* Sets the selected component path.
* @param {Array} path - The path to the selected component.
* @returns {Object} The action object.
*/
export const setSelectedComponentPath = (path) => ({
payload: path,
type : SET_SELECTED_COMPONENT_PATH
});

/**
* Adds a component to a specific box at a given path.
* @param {Object} componentData - The component data including component, boxIndex, and path.
* @returns {Object} The action object.
*/
export const addComponent = ({ component, boxIndex, path }) => ({
payload: { boxIndex, component, path },
type : ADD_COMPONENT
});

/**
* Sets the properties component path.
* @param {Object} payload - The payload containing the properties component path.
* @returns {Object} The action object.
*/
export const setPropsComponentPath = (payload) => ({
payload,
type: SET_PROPS_COMPONENT_PATH
});

/**
* Toggles the property selector visibility.
* @param {boolean} isOpen - The open/closed state of the property selector.
* @returns {Object} The action object.
*/
export const togglePropSelector = (isOpen) => ({
payload: isOpen,
type : TOGGLE_PROP_SELECTOR
});

/**
* Adds a property to a component.
* @param {Array} componentPath - The path to the component.
* @param {Object} prop - The property to add.
* @returns {Object} The action object.
*/
export const addComponentProp = (componentPath, prop) => ({
payload: { componentPath, prop },
type : ADD_COMPONENT_PROP
});

/**
* Updates the properties of a component.
* @param {Array} componentPath - The path to the component.
* @param {Object} props - The new properties for the component.
* @returns {Object} The action object.
*/
export const updateComponentProps = (componentPath, props) => ({
payload: { componentPath, props },
type : UPDATE_COMPONENT_PROPS
});

/**
* Updates the style classes of a component.
* @param {Array} componentPath - The path to the component.
* @param {Array} styleClasses - The new style classes for the component.
* @returns {Object} The action object.
*/
export const updateComponentStyleClasses = (componentPath, styleClasses) => ({
payload: { componentPath, styleClasses },
type : UPDATE_COMPONENT_STYLE_CLASSES
Expand Down
58 changes: 26 additions & 32 deletions app/components/page-builder/right-drawer-components/DialogDesign.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React from "react";

import {
CoreBox, CoreClasses, CoreIcon, CoreIconButton, CoreStack,
CoreBox,
CoreClasses,
CoreIcon,
CoreIconButton,
CoreStack,
CoreTooltip,
CoreTypographyBody2,
CoreTypographyOverline,
Expand All @@ -11,13 +15,11 @@ import {
export default function DialogDesign({ initialItems = [], onTransferDone }) {
const [selectedItemsAdding, setSelectedItemsAdding] = React.useState([]);
const [selectedItemsRemoving, setSelectedItemsRemoving] = React.useState([]);
const [transferredItems, setTransferredItems] = React.useState(initialItems);
const [transferredItems, setTransferredItems] = React.useState(Array.isArray(initialItems) ? initialItems : []);
const [activeList, setActiveList] = React.useState(null); // 'adding' or 'removing'
const lastClickRef = React.useRef({ action: null, item: null, time: 0 });
const DOUBLE_CLICK_THRESHOLD = 1000; // 1000 milliseconds threshold for consecutive clicks

// eslint-disable-next-line no-console
console.log(transferredItems);
const getHeaderClasses = (depth) => {
const baseClasses = [CoreClasses.POSITION.POSITION_STICKY, CoreClasses.PADDING.P1, CoreClasses.BG.BG_GREY_300, CoreClasses.COLOR.TEXT_BLACK_50];

Expand All @@ -37,37 +39,27 @@ export default function DialogDesign({ initialItems = [], onTransferDone }) {
const now = Date.now();
const { item: lastItem, time: lastTime, action: lastAction } = lastClickRef.current;

// Switch active list if a different action is selected
if (action !== activeList) {
if (action === "add") {
setSelectedItemsRemoving([]);
} else {
setSelectedItemsAdding([]);
}
action === "add" ? setSelectedItemsRemoving([]) : setSelectedItemsAdding([]);
setActiveList(action);
}

if (item === lastItem && action === lastAction && now - lastTime < DOUBLE_CLICK_THRESHOLD) {
if (action === "add") {
if (!transferredItems.includes(item)) {
setTransferredItems(prev => [...prev, item]);
setSelectedItemsAdding(prev => prev.filter(i => i !== item));
}
} else if (action === "remove") {
setTransferredItems(prev => prev.filter(i => i !== item));
setSelectedItemsRemoving(prev => prev.filter(i => i !== item));
}
} else {
if (action === "add") {
setSelectedItemsAdding(prev =>
prev.includes(item) ? prev.filter(i => i !== item) : [...prev, item]
);
} else if (action === "remove") {
setSelectedItemsRemoving(prev =>
prev.includes(item) ? prev.filter(i => i !== item) : [...prev, item]
);
}
}
// Determine if this is a double-click
const isDoubleClick = item === lastItem && action === lastAction && (now - lastTime < DOUBLE_CLICK_THRESHOLD);

// Handle actions based on double-click or single-click
isDoubleClick
? (action === "add" && !transferredItems.includes(item)
? (setTransferredItems(prev => [...prev, item]), setSelectedItemsAdding(prev => prev.filter(i => i !== item)))
: action === "remove" && (setTransferredItems(prev => prev.filter(i => i !== item)), setSelectedItemsRemoving(prev => prev.filter(i => i !== item)))
)
: (action === "add"
? setSelectedItemsAdding(prev => prev.includes(item) ? prev.filter(i => i !== item) : [...prev, item])
: setSelectedItemsRemoving(prev => prev.includes(item) ? prev.filter(i => i !== item) : [...prev, item])
);

// Update last click reference
lastClickRef.current = { action, item, time: now };
};

Expand All @@ -84,7 +76,7 @@ export default function DialogDesign({ initialItems = [], onTransferDone }) {
};

React.useEffect(() => {
onTransferDone(transferredItems);
onTransferDone(transferredItems); // Notify parent component of transferred items
}, [transferredItems, onTransferDone]);

const renderCoreKeys = (obj, parentKey = "", depth = 0) => {
Expand Down Expand Up @@ -117,7 +109,9 @@ export default function DialogDesign({ initialItems = [], onTransferDone }) {
onClick={() => handleItemClick(fullKey, "add")}
styleClasses={[CoreClasses.CURSOR.CURSOR_POINTER, activeList === "removing" ? CoreClasses.OPACITY._50 : null]}
>
<CoreTypographyOverline styleClasses={[selectedItemsAdding.includes(fullKey) ? CoreClasses.COLOR.TEXT_PRIMARY : CoreClasses.COLOR.TEXT_BLACK]}>{key}</CoreTypographyOverline>
<CoreTypographyOverline styleClasses={[selectedItemsAdding.includes(fullKey) ? CoreClasses.COLOR.TEXT_PRIMARY : CoreClasses.COLOR.TEXT_BLACK]}>
{key}
</CoreTypographyOverline>
</CoreBox>
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,62 +7,70 @@ import DialogDesign from "./DialogDesign";
import { updateComponentStyleClasses } from "../../../actions/test.action";

export default function StyleSelector() {
const [allPropsOpen, setAllPropsOpen] = React.useState(false);
const [tempTransferredItems, setTempTransferredItems] = React.useState([]);

const [dialogOpen, setDialogOpen] = React.useState(false);
const { setDialog } = React.useContext(CoreDialogContext);
const dispatch = useDispatch();
const propsComponentPath = useSelector((state) => state.testBuilderReducer?.propsComponentPath || null);
const componentsInBoxes = useSelector((state) => state.testBuilderReducer?.componentsInBoxes);

// Get the current style classes for the selected component
const currentStyleClasses = React.useMemo(() => {
if (propsComponentPath) {
let currentComponent = componentsInBoxes[propsComponentPath.placeholderIndex];

for (const index of propsComponentPath.componentPath) {
currentComponent = currentComponent.children[index];
}
return Array.isArray(currentComponent.styleClasses) ? currentComponent.styleClasses : [];
}
return [];
}, [propsComponentPath, componentsInBoxes]);

// Get the selectedComponentPath from Redux state
const selectedComponentPath = useSelector((state) => state.testBuilder?.selectedComponentPath || null);
const [tempTransferredItems, setTempTransferredItems] = React.useState(currentStyleClasses);

// Function to handle the dialog close and dispatch the updated styles
const handleDialogDone = () => {
if (selectedComponentPath) {
// eslint-disable-next-line no-console
console.log("Dispatching styles:", tempTransferredItems, selectedComponentPath);
dispatch(updateComponentStyleClasses(selectedComponentPath, tempTransferredItems));
React.useEffect(() => {
setTempTransferredItems(currentStyleClasses);
}, [currentStyleClasses]);

const handleDialogDone = React.useCallback(() => {
if (propsComponentPath) {
dispatch(updateComponentStyleClasses(propsComponentPath, tempTransferredItems));
// eslint-disable-next-line etc/no-commented-out-code
// console.log("Dispatching styles:", tempTransferredItems, propsComponentPath);
} else {
// eslint-disable-next-line no-console
console.warn("No component path is selected.");
// console.warn("No component path is selected.");
//do nothing
}
};
setDialogOpen(false);
}, [dispatch, propsComponentPath, tempTransferredItems]);

React.useEffect(() => {
if (allPropsOpen) {
if (dialogOpen) {
setDialog({
cancelButtonLabel: "Cancel",
dialogProps : { maxWidth: "xl" },
doneButton : handleDialogDone, // On done, apply styles
doneButtonLabel : "Apply",
noCancelButton : false,
noDoneButton : false,
showDialog : true,
subtitle : (
dialogProps : { maxWidth: "xl" },
doneButton : handleDialogDone,
doneButtonLabel: "Apply",
noCancelButton : false,
noDoneButton : false,
showDialog : true,
subtitle : (
<DialogDesign
initialItems={tempTransferredItems}
initialItems={currentStyleClasses}
onTransferDone={setTempTransferredItems}
/>
),
type: "info",
});

const timer = setTimeout(() => {
setAllPropsOpen(false);
}, 500);

return () => clearTimeout(timer);
}
}, [allPropsOpen, setDialog, tempTransferredItems]);
}, [dialogOpen, setDialog, handleDialogDone, currentStyleClasses]);

const handleClickAllPropsOpen = () => {
setAllPropsOpen(true);
const handleDialogOpen = () => {
setDialogOpen(true);
};

return (
<CoreButton variant="text" onClick={handleClickAllPropsOpen}>
<CoreButton variant="text" onClick={handleDialogOpen}>
Add styles
</CoreButton>
);
}
}
Loading

0 comments on commit e4d9381

Please sign in to comment.