diff --git a/src/qqq/components/query/AdvancedQueryPreview.tsx b/src/qqq/components/query/AdvancedQueryPreview.tsx new file mode 100644 index 0000000..1ea81de --- /dev/null +++ b/src/qqq/components/query/AdvancedQueryPreview.tsx @@ -0,0 +1,153 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2024. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + + +import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData"; +import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter"; +import Box from "@mui/material/Box"; +import colors from "qqq/assets/theme/base/colors"; +import {validateCriteria} from "qqq/components/query/FilterCriteriaRow"; +import XIcon from "qqq/components/query/XIcon"; +import FilterUtils from "qqq/utils/qqq/FilterUtils"; +import React, {useState} from "react"; + +interface AdvancedQueryPreviewProps +{ + tableMetaData: QTableMetaData; + queryFilter: QQueryFilter; + isEditable: boolean; + isQueryTooComplex: boolean; + removeCriteriaByIndexCallback: (index: number) => void; +} + +/******************************************************************************* + ** Box shown on query screen (and more??) to preview what a query looks like, + ** as an "advanced" style/precursor-to-writing-your-own-query thing. + *******************************************************************************/ +export default function AdvancedQueryPreview({tableMetaData, queryFilter, isEditable, isQueryTooComplex, removeCriteriaByIndexCallback}: AdvancedQueryPreviewProps): JSX.Element +{ + const [mouseOverElement, setMouseOverElement] = useState(null as string); + + + /******************************************************************************* + ** + *******************************************************************************/ + function handleMouseOverElement(name: string) + { + setMouseOverElement(name); + } + + + /******************************************************************************* + ** + *******************************************************************************/ + function handleMouseOutElement() + { + setMouseOverElement(null); + } + + + + /******************************************************************************* + ** format the current query as a string for showing on-screen as a preview. + *******************************************************************************/ + const queryToAdvancedString = (thisQueryFilter: QQueryFilter) => + { + if (queryFilter == null || !queryFilter.criteria) + { + return (); + } + + let counter = 0; + + return ( + + {thisQueryFilter.criteria?.map((criteria, i) => + { + const {criteriaIsValid} = validateCriteria(criteria, null); + if (criteriaIsValid) + { + counter++; + return ( + handleMouseOverElement(`queryPreview-${i}`)} onMouseOut={() => handleMouseOutElement()}> + {counter > 1 ? {thisQueryFilter.booleanOperator}  : } + {FilterUtils.criteriaToHumanString(tableMetaData, criteria, true)} + {isEditable && !isQueryTooComplex && ( + mouseOverElement == `queryPreview-${i}` && + removeCriteriaByIndexCallback(i)} /> + )} + {counter > 1 && i == thisQueryFilter.criteria?.length - 1 && thisQueryFilter.subFilters?.length > 0 ? {thisQueryFilter.booleanOperator}  : } + + ); + } + else + { + return (); + } + })} + + {thisQueryFilter.subFilters?.length > 0 && (thisQueryFilter.subFilters.map((filter: QQueryFilter, j) => + { + return ( + + {j > 0 ? {thisQueryFilter.booleanOperator}  : } + ( + {queryToAdvancedString(filter)} + ) + + ); + }))} + + ); + }; + + const moreSX = isEditable ? + { + borderTop: `1px solid ${colors.grayLines.main}`, + boxShadow: "inset 0px 0px 4px 2px #EFEFED", + borderRadius: "0 0 0.75rem 0.75rem", + } : + { + borderRadius: "0.75rem", + border: `1px solid ${colors.grayLines.main}`, + } + + return ( + + { + + + {queryToAdvancedString(queryFilter)} + + + } + + ) +} diff --git a/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx b/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx index 563d002..8a2ae6e 100644 --- a/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx +++ b/src/qqq/components/query/BasicAndAdvancedQueryControls.tsx @@ -44,11 +44,13 @@ import {GridApiPro} from "@mui/x-data-grid-pro/models/gridApiPro"; import QContext from "QContext"; import colors from "qqq/assets/theme/base/colors"; import {QCancelButton, QSaveButton} from "qqq/components/buttons/DefaultButtons"; +import AdvancedQueryPreview from "qqq/components/query/AdvancedQueryPreview"; import {QFilterCriteriaWithId} from "qqq/components/query/CustomFilterPanel"; import FieldListMenu from "qqq/components/query/FieldListMenu"; import {validateCriteria} from "qqq/components/query/FilterCriteriaRow"; import QuickFilter, {quickFilterButtonStyles} from "qqq/components/query/QuickFilter"; import XIcon from "qqq/components/query/XIcon"; +import {QueryScreenUsage} from "qqq/pages/records/query/RecordQuery"; import FilterUtils from "qqq/utils/qqq/FilterUtils"; import TableUtils from "qqq/utils/qqq/TableUtils"; import React, {forwardRef, useContext, useImperativeHandle, useReducer, useState} from "react"; @@ -75,6 +77,8 @@ interface BasicAndAdvancedQueryControlsProps ///////////////////////////////////////////////////////////////////////////////////////////// queryFilterJSON: string; + queryScreenUsage: QueryScreenUsage; + mode: string; setMode: (mode: string) => void; } @@ -397,60 +401,6 @@ const BasicAndAdvancedQueryControls = forwardRef((props: BasicAndAdvancedQueryCo }; - /******************************************************************************* - ** format the current query as a string for showing on-screen as a preview. - *******************************************************************************/ - const queryToAdvancedString = (thisQueryFilter: QQueryFilter) => - { - if (queryFilter == null || !queryFilter.criteria) - { - return (); - } - - let counter = 0; - - return ( - - {thisQueryFilter.criteria?.map((criteria, i) => - { - const {criteriaIsValid} = validateCriteria(criteria, null); - if (criteriaIsValid) - { - counter++; - return ( - handleMouseOverElement(`queryPreview-${i}`)} onMouseOut={() => handleMouseOutElement()}> - {counter > 1 ? {thisQueryFilter.booleanOperator}  : } - {FilterUtils.criteriaToHumanString(tableMetaData, criteria, true)} - {!isQueryTooComplex && ( - mouseOverElement == `queryPreview-${i}` && - removeCriteriaByIndex(i)} /> - )} - {counter > 1 && i == thisQueryFilter.criteria?.length - 1 && thisQueryFilter.subFilters?.length > 0 ? {thisQueryFilter.booleanOperator}  : } - - ); - } - else - { - return (); - } - })} - - {thisQueryFilter.subFilters?.length > 0 && (thisQueryFilter.subFilters.map((filter: QQueryFilter, j) => - { - return ( - - {j > 0 ? {thisQueryFilter.booleanOperator}  : } - ( - {queryToAdvancedString(filter)} - ) - - ); - }))} - - ); - }; - - /******************************************************************************* ** event handler for toggling between modes - basic & advanced. *******************************************************************************/ @@ -807,26 +757,7 @@ const BasicAndAdvancedQueryControls = forwardRef((props: BasicAndAdvancedQueryCo {sortMenuComponent} - - { - - - {queryToAdvancedString(queryFilter)} - - - } - + }