import React, { useCallback } from "react"; import BaseControl, { ControlProps } from "./BaseControl"; import { StyledInputGroup, StyledPropertyPaneButton, StyledDragIcon, StyledDeleteIcon, StyledEditIcon, } from "./StyledControls"; import styled from "constants/DefaultTheme"; import { generateReactKey } from "utils/generators"; import { DroppableComponent } from "components/ads/DraggableListComponent"; import { getNextEntityName } from "utils/AppsmithUtils"; import _, { debounce } from "lodash"; import { Category, Size } from "components/ads/Button"; const StyledPropertyPaneButtonWrapper = styled.div` display: flex; width: 100%; justify-content: center; margin-top: 10px; `; const ItemWrapper = styled.div` display: flex; justify-content: flex-start; align-items: center; `; const MenuItemsWrapper = styled.div` width: 100%; display: flex; flex-direction: column; `; const StyledOptionControlInputGroup = styled(StyledInputGroup)` margin-right: 2px; margin-bottom: 2px; width: 100%; padding-left: 30px; padding-right: 60px; text-overflow: ellipsis; &&& { input { border: none; color: ${(props) => props.theme.colors.propertyPane.radioGroupText}; background: ${(props) => props.theme.colors.propertyPane.radioGroupBg}; &:focus { border: none; color: ${(props) => props.theme.colors.textOnDarkBG}; background: ${(props) => props.theme.colors.paneInputBG}; } } } `; const AddMenuItemButton = styled(StyledPropertyPaneButton)` justify-content: center; flex-grow: 1; `; type RenderComponentProps = { index: number; item: { label: string; isVisible?: boolean; }; deleteOption: (index: number) => void; updateOption: (index: number, value: string) => void; toggleVisibility?: (index: number) => void; onEdit?: (props: any) => void; }; function MenuItemComponent(props: RenderComponentProps) { const { deleteOption, index, item, updateOption } = props; const debouncedUpdate = debounce(updateOption, 1000); const handleChange = useCallback(() => props.onEdit && props.onEdit(index), [ index, ]); return ( { debouncedUpdate(index, value); }} placeholder="Menu item label" /> { deleteOption(index); }} width={20} /> ); } class MenuItemsControl extends BaseControl { updateItems = (items: Array>) => { const menuItems = items.reduce((obj: any, each: any, index: number) => { obj[each.id] = { ...each, index, }; return obj; }, {}); this.updateProperty(this.props.propertyName, menuItems); }; onEdit = (index: number) => { const menuItems: Array<{ id: string; label: string; }> = Object.values(this.props.propertyValue); const targetMenuItem = menuItems[index]; this.props.openNextPanel({ index, ...targetMenuItem, propPaneId: this.props.widgetProperties.widgetId, }); }; render() { const menuItems: Array<{ id: string; label: string; }> = _.isString(this.props.propertyValue) ? [] : Object.values(this.props.propertyValue); return ( ); } toggleVisibility = (index: number) => { const menuItems: Array<{ id: string; label: string; isDisabled: boolean; isVisible: boolean; widgetId: string; }> = this.props.propertyValue.slice(); const isVisible = menuItems[index].isVisible === true ? false : true; const updatedMenuItems = menuItems.map((item, itemIndex) => { if (index === itemIndex) { return { ...item, isVisible: isVisible, }; } return item; }); this.updateProperty(this.props.propertyName, updatedMenuItems); }; deleteOption = (index: number) => { const menuItemsArray: any = Object.values(this.props.propertyValue); const itemId = menuItemsArray[index].id; if (menuItemsArray && menuItemsArray.length === 1) return; const updatedArray = menuItemsArray.filter((eachItem: any, i: number) => { return i !== index; }); const updatedObj = updatedArray.reduce( (obj: any, each: any, index: number) => { obj[each.id] = { ...each, index, }; return obj; }, {}, ); this.deleteProperties([`${this.props.propertyName}.${itemId}.isVisible`]); this.updateProperty(this.props.propertyName, updatedObj); }; updateOption = (index: number, updatedLabel: string) => { const menuItemsArray: any = Object.values(this.props.propertyValue); const itemId = menuItemsArray[index].id; this.updateProperty( `${this.props.propertyName}.${itemId}.label`, updatedLabel, ); }; addOption = () => { let menuItems = this.props.propertyValue; const menuItemsArray = Object.values(menuItems); const newMenuItemId = generateReactKey({ prefix: "menuItem" }); const newMenuItemLabel = getNextEntityName( "Menu Item ", menuItemsArray.map((menuItem: any) => menuItem.label), ); menuItems = { ...menuItems, [newMenuItemId]: { id: newMenuItemId, label: newMenuItemLabel, widgetId: generateReactKey(), isDisabled: false, isVisible: true, }, }; this.updateProperty(this.props.propertyName, menuItems); }; static getControlType() { return "MENU_ITEMS"; } } export default MenuItemsControl;