mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-17 21:00:45 +00:00
CE-1115 - Break this component out into its own ... component.
This commit is contained in:
153
src/qqq/components/query/AdvancedQueryPreview.tsx
Normal file
153
src/qqq/components/query/AdvancedQueryPreview.tsx
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
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 (<span></span>);
|
||||
}
|
||||
|
||||
let counter = 0;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{thisQueryFilter.criteria?.map((criteria, i) =>
|
||||
{
|
||||
const {criteriaIsValid} = validateCriteria(criteria, null);
|
||||
if (criteriaIsValid)
|
||||
{
|
||||
counter++;
|
||||
return (
|
||||
<span key={i} style={{marginBottom: "0.125rem"}} onMouseOver={() => handleMouseOverElement(`queryPreview-${i}`)} onMouseOut={() => handleMouseOutElement()}>
|
||||
{counter > 1 ? <span style={{marginLeft: "0.25rem", marginRight: "0.25rem"}}>{thisQueryFilter.booleanOperator} </span> : <span />}
|
||||
{FilterUtils.criteriaToHumanString(tableMetaData, criteria, true)}
|
||||
{isEditable && !isQueryTooComplex && (
|
||||
mouseOverElement == `queryPreview-${i}` && <span className={`advancedQueryPreviewX-${counter - 1}`}>
|
||||
<XIcon position="forAdvancedQueryPreview" onClick={() => removeCriteriaByIndexCallback(i)} /></span>
|
||||
)}
|
||||
{counter > 1 && i == thisQueryFilter.criteria?.length - 1 && thisQueryFilter.subFilters?.length > 0 ? <span style={{marginLeft: "0.25rem", marginRight: "0.25rem"}}>{thisQueryFilter.booleanOperator} </span> : <span />}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (<span />);
|
||||
}
|
||||
})}
|
||||
|
||||
{thisQueryFilter.subFilters?.length > 0 && (thisQueryFilter.subFilters.map((filter: QQueryFilter, j) =>
|
||||
{
|
||||
return (
|
||||
<React.Fragment key={j}>
|
||||
{j > 0 ? <span style={{marginLeft: "0.25rem", marginRight: "0.25rem"}}>{thisQueryFilter.booleanOperator} </span> : <span></span>}
|
||||
<span style={{display: "flex", marginRight: "0.20rem"}}>(</span>
|
||||
{queryToAdvancedString(filter)}
|
||||
<span style={{display: "flex", marginRight: "0.20rem"}}>)</span>
|
||||
</React.Fragment>
|
||||
);
|
||||
}))}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
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 (
|
||||
<Box whiteSpace="nowrap" display="flex" flexShrink={1} flexGrow={1} alignItems="center">
|
||||
{
|
||||
<Box
|
||||
className="advancedQueryString"
|
||||
display="inline-block"
|
||||
width="100%"
|
||||
sx={{fontSize: "1rem", background: "#FFFFFF"}}
|
||||
minHeight={"2.375rem"}
|
||||
p={"0.5rem"}
|
||||
pb={"0.125rem"}
|
||||
{...moreSX}
|
||||
>
|
||||
<Box display="flex" flexWrap="wrap" fontSize="0.875rem">
|
||||
{queryToAdvancedString(queryFilter)}
|
||||
</Box>
|
||||
</Box>
|
||||
}
|
||||
</Box>
|
||||
)
|
||||
}
|
@ -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 (<span></span>);
|
||||
}
|
||||
|
||||
let counter = 0;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{thisQueryFilter.criteria?.map((criteria, i) =>
|
||||
{
|
||||
const {criteriaIsValid} = validateCriteria(criteria, null);
|
||||
if (criteriaIsValid)
|
||||
{
|
||||
counter++;
|
||||
return (
|
||||
<span key={i} style={{marginBottom: "0.125rem"}} onMouseOver={() => handleMouseOverElement(`queryPreview-${i}`)} onMouseOut={() => handleMouseOutElement()}>
|
||||
{counter > 1 ? <span style={{marginLeft: "0.25rem", marginRight: "0.25rem"}}>{thisQueryFilter.booleanOperator} </span> : <span />}
|
||||
{FilterUtils.criteriaToHumanString(tableMetaData, criteria, true)}
|
||||
{!isQueryTooComplex && (
|
||||
mouseOverElement == `queryPreview-${i}` && <span className={`advancedQueryPreviewX-${counter - 1}`}>
|
||||
<XIcon position="forAdvancedQueryPreview" onClick={() => removeCriteriaByIndex(i)} /></span>
|
||||
)}
|
||||
{counter > 1 && i == thisQueryFilter.criteria?.length - 1 && thisQueryFilter.subFilters?.length > 0 ? <span style={{marginLeft: "0.25rem", marginRight: "0.25rem"}}>{thisQueryFilter.booleanOperator} </span> : <span />}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (<span />);
|
||||
}
|
||||
})}
|
||||
|
||||
{thisQueryFilter.subFilters?.length > 0 && (thisQueryFilter.subFilters.map((filter: QQueryFilter, j) =>
|
||||
{
|
||||
return (
|
||||
<React.Fragment key={j}>
|
||||
{j > 0 ? <span style={{marginLeft: "0.25rem", marginRight: "0.25rem"}}>{thisQueryFilter.booleanOperator} </span> : <span></span>}
|
||||
<span style={{display: "flex", marginRight: "0.20rem"}}>(</span>
|
||||
{queryToAdvancedString(filter)}
|
||||
<span style={{display: "flex", marginRight: "0.20rem"}}>)</span>
|
||||
</React.Fragment>
|
||||
);
|
||||
}))}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** event handler for toggling between modes - basic & advanced.
|
||||
*******************************************************************************/
|
||||
@ -807,26 +757,7 @@ const BasicAndAdvancedQueryControls = forwardRef((props: BasicAndAdvancedQueryCo
|
||||
{sortMenuComponent}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box whiteSpace="nowrap" display="flex" flexShrink={1} flexGrow={1} alignItems="center">
|
||||
{
|
||||
<Box
|
||||
className="advancedQueryString"
|
||||
display="inline-block"
|
||||
borderTop={`1px solid ${borderGray}`}
|
||||
borderRadius="0 0 0.75rem 0.75rem"
|
||||
width="100%"
|
||||
sx={{fontSize: "1rem", background: "#FFFFFF"}}
|
||||
minHeight={"2.375rem"}
|
||||
p={"0.5rem"}
|
||||
pb={"0.125rem"}
|
||||
boxShadow={"inset 0px 0px 4px 2px #EFEFED"}
|
||||
>
|
||||
<Box display="flex" flexWrap="wrap" fontSize="0.875rem">
|
||||
{queryToAdvancedString(queryFilter)}
|
||||
</Box>
|
||||
</Box>
|
||||
}
|
||||
</Box>
|
||||
<AdvancedQueryPreview tableMetaData={tableMetaData} queryFilter={queryFilter} isEditable={true} isQueryTooComplex={isQueryTooComplex} removeCriteriaByIndexCallback={removeCriteriaByIndex} />
|
||||
</Box>
|
||||
}
|
||||
</Box>
|
||||
|
Reference in New Issue
Block a user