diff --git a/app/client/src/components/formControls/SortingControl.tsx b/app/client/src/components/formControls/SortingControl.tsx index 5f92252b9056..2e1a239f02c7 100644 --- a/app/client/src/components/formControls/SortingControl.tsx +++ b/app/client/src/components/formControls/SortingControl.tsx @@ -1,9 +1,12 @@ -import React, { useEffect, useRef } from "react"; +import React, { useEffect, useMemo, useRef } from "react"; import { useSelector } from "react-redux"; import FormControl from "pages/Editor/FormControl"; -import { Classes } from "@appsmith/ads-old"; import styled from "styled-components"; -import { FieldArray, getFormValues } from "redux-form"; +import { + FieldArray, + getFormValues, + type WrappedFieldArrayProps, +} from "redux-form"; import type { ControlProps } from "./BaseControl"; import { getBindingOrConfigPathsForSortingControl } from "entities/Action/actionProperties"; import { SortingSubComponent } from "./utils"; @@ -26,9 +29,6 @@ const columnFieldConfig: any = { initialValue: "", inputType: "TEXT", placeholderText: "Column name", - customStyles: { - // width: "280px", - }, }; // Form config for the order field @@ -52,60 +52,42 @@ const orderFieldConfig: any = { ], }; -// main container for the fsorting component -const SortingContainer = styled.div` - display: flex; - flex-direction: column; - justify-content: space-between; +const SortingContainer = styled.div<{ isBreakpointSmall: boolean }>` + display: grid; + grid-template-columns: ${({ isBreakpointSmall }) => + isBreakpointSmall ? "1fr 50px" : "1fr 50px"}; + gap: 5px; + align-items: center; `; -// container for the two sorting dropdown -const SortingDropdownContainer = styled.div<{ size: string }>` - display: flex; - flex-direction: row; - width: min-content; - justify-content: space-between; - margin-bottom: 5px; +const SortingFields = styled.div<{ isBreakpointSmall: boolean }>` + display: grid; + grid-template-columns: ${({ isBreakpointSmall }) => + isBreakpointSmall ? "1fr" : "1fr 180px"}; + grid-template-rows: ${({ isBreakpointSmall }) => + isBreakpointSmall ? "1fr 1fr" : "1fr"}; gap: 5px; - align-items: center; - > div { - width: 250px; - } - ${(props) => - props.size === "small" && - ` - // Hide the dropdown labels to decrease the width - // The design system component has inline style hence the !important - .t--form-control-DROP_DOWN .${Classes.TEXT} { - display: none !important; - } - // Show the icons hidden initially - .t--form-control-DROP_DOWN .remixicon-icon { - display: initial; - } - `} `; + const ButtonWrapper = styled.div` display: flex; flex-direction: row; `; -// container for the column dropdown section -const ColumnDropdownContainer = styled.div``; -// Component for the icons -const CenteredButton = styled(Button)``; +export type SortingControlProps = ControlProps; -// TODO: Fix this the next time the file is edited -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function SortingComponent(props: any) { - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const formValues: any = useSelector((state) => +export type SortingComponentProps = WrappedFieldArrayProps & + Pick; + +function SortingComponent(props: SortingComponentProps) { + const { configProperty, fields, formName } = props; + + const formValues = useSelector((state) => getFormValues(props.formName)(state), ); const onDeletePressed = (index: number) => { - props.fields.remove(index); + fields.remove(index); }; const targetRef = useRef(null); @@ -113,105 +95,100 @@ function SortingComponent(props: any) { const isBreakpointSmall = size === "small"; useEffect(() => { - // this path represents the path to the sortBy object, wherever the location is in the actionConfiguration object - let sortingObjectPath; // if the path ends with .data which we expect it to. - if (props.configProperty.endsWith(".data")) { + if (configProperty.endsWith(".data")) { // we remove the .data and get the path of the sort object // NOTE: 5 is used because (.data) = 5 - sortingObjectPath = props.configProperty.substring( + const sortingObjectPath = configProperty.substring( 0, - props.configProperty.length - 5, + configProperty.length - 5, ); - } - // sortDataValue is the path to the value (.data included) itself in the sort object - const sortDataValue = get(formValues, props.configProperty); - // sort object value is the path to the sort object itself. - const sortObjectValue = get(formValues, sortingObjectPath); - - // The reason we are making this check is to prevent new fields from being pushed when the form control is visited - // for some reason the fields object is initially undefined in first render, before being initialized with the correct values after. - // so we check to see if the sortObjectValue exist first (if the value has been initalized). - if (!sortObjectValue) { - return; - } - // then we check if the redux fields have any items in it, - // and we also check if the value exists in the redux state as an array and if that value has no items in it. - // if they are both empty we want to push a new field. - // We also want to check if the value is undefined, this means that the sort data value is non existent, if it is, we want to push a new field. - if ( - (props.fields.length < 1 && - isArray(sortDataValue) && - sortDataValue.length < 1) || - (props.fields.length < 1 && !sortDataValue) - ) { - props.fields.push({ - column: "", - order: OrderDropDownValues.ASCENDING, - }); - } else { - onDeletePressed(props.index); + // sortDataValue is the path to the value (.data included) itself in the sort object + const sortDataValue = get(formValues, configProperty); + // sort object value is the path to the sort object itself. + const sortObjectValue = get(formValues, sortingObjectPath); + + // The reason we are making this check is to prevent new fields from being pushed when the form control is visited + // for some reason the fields object is initially undefined in first render, before being initialized with the correct values after. + // so we check to see if the sortObjectValue exist first (if the value has been initalized). + if (sortObjectValue) { + // then we check if the redux fields have any items in it, + // and we also check if the value exists in the redux state as an array and if that value has no items in it. + // if they are both empty we want to push a new field. + // We also want to check if the value is undefined, this means that the sort data value is non existent, if it is, we want to push a new field. + if ( + (fields.length < 1 && + isArray(sortDataValue) && + sortDataValue.length < 1) || + (fields.length < 1 && !sortDataValue) + ) { + fields.push({ + column: "", + order: OrderDropDownValues.ASCENDING, + }); + } + } } - }, [props.fields.length]); + }, [fields.length]); return ( - - {props.fields && - props.fields.length > 0 && - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - props.fields.map((field: any, index: number) => { + + {fields && + fields.length > 0 && + fields.map((field, index: number) => { const columnPath = getBindingOrConfigPathsForSortingControl( SortingSubComponent.Column, field, - undefined, ); - const OrderPath = getBindingOrConfigPathsForSortingControl( + + const orderPath = getBindingOrConfigPathsForSortingControl( SortingSubComponent.Order, field, - undefined, ); + return ( - - + + - - - {/* Component to render the delete icon */} - + +