mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 05:10:45 +00:00
CTLE-421: fixed a warning
This commit is contained in:
@ -6,7 +6,7 @@
|
|||||||
"@auth0/auth0-react": "1.10.2",
|
"@auth0/auth0-react": "1.10.2",
|
||||||
"@emotion/react": "11.7.1",
|
"@emotion/react": "11.7.1",
|
||||||
"@emotion/styled": "11.6.0",
|
"@emotion/styled": "11.6.0",
|
||||||
"@kingsrook/qqq-frontend-core": "1.0.57",
|
"@kingsrook/qqq-frontend-core": "1.0.61",
|
||||||
"@mui/icons-material": "5.4.1",
|
"@mui/icons-material": "5.4.1",
|
||||||
"@mui/material": "5.11.1",
|
"@mui/material": "5.11.1",
|
||||||
"@mui/styles": "5.11.1",
|
"@mui/styles": "5.11.1",
|
||||||
|
@ -26,9 +26,8 @@ import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QT
|
|||||||
import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableSection";
|
import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableSection";
|
||||||
import {QPossibleValue} from "@kingsrook/qqq-frontend-core/lib/model/QPossibleValue";
|
import {QPossibleValue} from "@kingsrook/qqq-frontend-core/lib/model/QPossibleValue";
|
||||||
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||||
import {Alert} from "@mui/material";
|
import {Alert, Box} from "@mui/material";
|
||||||
import Avatar from "@mui/material/Avatar";
|
import Avatar from "@mui/material/Avatar";
|
||||||
import Box from "@mui/material/Box";
|
|
||||||
import Card from "@mui/material/Card";
|
import Card from "@mui/material/Card";
|
||||||
import Grid from "@mui/material/Grid";
|
import Grid from "@mui/material/Grid";
|
||||||
import Icon from "@mui/material/Icon";
|
import Icon from "@mui/material/Icon";
|
||||||
@ -80,6 +79,7 @@ function EntityForm(props: Props): JSX.Element
|
|||||||
const [nonT1Sections, setNonT1Sections] = useState([] as QTableSection[]);
|
const [nonT1Sections, setNonT1Sections] = useState([] as QTableSection[]);
|
||||||
|
|
||||||
const [alertContent, setAlertContent] = useState("");
|
const [alertContent, setAlertContent] = useState("");
|
||||||
|
const [warningContent, setWarningContent] = useState("");
|
||||||
|
|
||||||
const [asyncLoadInited, setAsyncLoadInited] = useState(false);
|
const [asyncLoadInited, setAsyncLoadInited] = useState(false);
|
||||||
const [formValues, setFormValues] = useState({} as { [key: string]: string });
|
const [formValues, setFormValues] = useState({} as { [key: string]: string });
|
||||||
@ -424,7 +424,16 @@ function EntityForm(props: Props): JSX.Element
|
|||||||
{
|
{
|
||||||
console.log("Caught:");
|
console.log("Caught:");
|
||||||
console.log(error);
|
console.log(error);
|
||||||
setAlertContent(error.message);
|
|
||||||
|
if(error.message.toLowerCase().startsWith("warning"))
|
||||||
|
{
|
||||||
|
const path = `${location.pathname.replace(/\/edit$/, "")}?updateSuccess=true&warning=${encodeURIComponent(error.message)}`;
|
||||||
|
navigate(path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setAlertContent(error.message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -445,7 +454,15 @@ function EntityForm(props: Props): JSX.Element
|
|||||||
})
|
})
|
||||||
.catch((error) =>
|
.catch((error) =>
|
||||||
{
|
{
|
||||||
setAlertContent(error.message);
|
if(error.message.toLowerCase().startsWith("warning"))
|
||||||
|
{
|
||||||
|
const path = `${location.pathname.replace(/create$/, record.values.get(tableMetaData.primaryKeyField))}?createSuccess=true&warning=${encodeURIComponent(error.message)}`;
|
||||||
|
navigate(path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setAlertContent(error.message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@ -485,6 +502,11 @@ function EntityForm(props: Props): JSX.Element
|
|||||||
<Alert severity="error">{alertContent}</Alert>
|
<Alert severity="error">{alertContent}</Alert>
|
||||||
</Box>
|
</Box>
|
||||||
) : ("")}
|
) : ("")}
|
||||||
|
{warningContent ? (
|
||||||
|
<Box mb={3}>
|
||||||
|
<Alert severity="warning">{warningContent}</Alert>
|
||||||
|
</Box>
|
||||||
|
) : ("")}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid container spacing={3}>
|
<Grid container spacing={3}>
|
||||||
|
@ -27,8 +27,7 @@ import {QJobComplete} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJo
|
|||||||
import {QJobError} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobError";
|
import {QJobError} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobError";
|
||||||
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||||
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
|
import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter";
|
||||||
import {Alert, Collapse, TablePagination} from "@mui/material";
|
import {Alert, Box, Collapse, TablePagination} from "@mui/material";
|
||||||
import Box from "@mui/material/Box";
|
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import Card from "@mui/material/Card";
|
import Card from "@mui/material/Card";
|
||||||
import Dialog from "@mui/material/Dialog";
|
import Dialog from "@mui/material/Dialog";
|
||||||
|
@ -26,9 +26,8 @@ import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/
|
|||||||
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
||||||
import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableSection";
|
import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableSection";
|
||||||
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||||
import {Alert, Typography} from "@mui/material";
|
import {Alert, Box, Typography} from "@mui/material";
|
||||||
import Avatar from "@mui/material/Avatar";
|
import Avatar from "@mui/material/Avatar";
|
||||||
import Box from "@mui/material/Box";
|
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import Card from "@mui/material/Card";
|
import Card from "@mui/material/Card";
|
||||||
import Dialog from "@mui/material/Dialog";
|
import Dialog from "@mui/material/Dialog";
|
||||||
@ -43,7 +42,7 @@ import ListItemIcon from "@mui/material/ListItemIcon";
|
|||||||
import Menu from "@mui/material/Menu";
|
import Menu from "@mui/material/Menu";
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
import Modal from "@mui/material/Modal";
|
import Modal from "@mui/material/Modal";
|
||||||
import React, {useContext, useEffect, useReducer, useState} from "react";
|
import React, {useContext, useEffect, useState} from "react";
|
||||||
import {useLocation, useNavigate, useParams, useSearchParams} from "react-router-dom";
|
import {useLocation, useNavigate, useParams, useSearchParams} from "react-router-dom";
|
||||||
import QContext from "QContext";
|
import QContext from "QContext";
|
||||||
import AuditBody from "qqq/components/audits/AuditBody";
|
import AuditBody from "qqq/components/audits/AuditBody";
|
||||||
@ -86,6 +85,7 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
|||||||
|
|
||||||
const [asyncLoadInited, setAsyncLoadInited] = useState(false);
|
const [asyncLoadInited, setAsyncLoadInited] = useState(false);
|
||||||
const [sectionFieldElements, setSectionFieldElements] = useState(null as Map<string, JSX.Element[]>);
|
const [sectionFieldElements, setSectionFieldElements] = useState(null as Map<string, JSX.Element[]>);
|
||||||
|
const [adornmentFieldsMap, setAdornmentFieldsMap] = useState(new Map<string, boolean>);
|
||||||
const [deleteConfirmationOpen, setDeleteConfirmationOpen] = useState(false);
|
const [deleteConfirmationOpen, setDeleteConfirmationOpen] = useState(false);
|
||||||
const [tableMetaData, setTableMetaData] = useState(null);
|
const [tableMetaData, setTableMetaData] = useState(null);
|
||||||
const [metaData, setMetaData] = useState(null as QInstance);
|
const [metaData, setMetaData] = useState(null as QInstance);
|
||||||
@ -99,10 +99,11 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
|||||||
const [actionsMenu, setActionsMenu] = useState(null);
|
const [actionsMenu, setActionsMenu] = useState(null);
|
||||||
const [notFoundMessage, setNotFoundMessage] = useState(null);
|
const [notFoundMessage, setNotFoundMessage] = useState(null);
|
||||||
const [successMessage, setSuccessMessage] = useState(null as string);
|
const [successMessage, setSuccessMessage] = useState(null as string);
|
||||||
|
const [warningMessage, setWarningMessage] = useState(null as string);
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const {setPageHeader} = useContext(QContext);
|
const {setPageHeader} = useContext(QContext);
|
||||||
const [activeModalProcess, setActiveModalProcess] = useState(null as QProcessMetaData);
|
const [activeModalProcess, setActiveModalProcess] = useState(null as QProcessMetaData);
|
||||||
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
const [reloadCounter, setReloadCounter] = useState(0);
|
||||||
|
|
||||||
const [launchingProcess, setLaunchingProcess] = useState(launchProcess);
|
const [launchingProcess, setLaunchingProcess] = useState(launchProcess);
|
||||||
const [showEditChildForm, setShowEditChildForm] = useState(null as any);
|
const [showEditChildForm, setShowEditChildForm] = useState(null as any);
|
||||||
@ -368,8 +369,8 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
|||||||
<Box key={section.name} display="flex" flexDirection="column" py={1} pr={2}>
|
<Box key={section.name} display="flex" flexDirection="column" py={1} pr={2}>
|
||||||
{
|
{
|
||||||
section.fieldNames.map((fieldName: string) => (
|
section.fieldNames.map((fieldName: string) => (
|
||||||
<Box key={fieldName} flexDirection="row" pr={2}>
|
<Box display="flex" key={fieldName} flexDirection="row" pb={2} pr={2}>
|
||||||
<Typography variant="button" textTransform="none" fontWeight="bold" pr={1} color="rgb(52, 71, 103)">
|
<Typography sx={{display: "flex"}} variant="button" textTransform="none" fontWeight="bold" pr={1} color="rgb(52, 71, 103)">
|
||||||
{tableMetaData.fields.get(fieldName).label}:
|
{tableMetaData.fields.get(fieldName).label}:
|
||||||
<div style={{display: "inline-block", width: 0}}> </div>
|
<div style={{display: "inline-block", width: 0}}> </div>
|
||||||
</Typography>
|
</Typography>
|
||||||
@ -426,8 +427,10 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
|||||||
{
|
{
|
||||||
setSuccessMessage(`${tableMetaData.label} successfully ${searchParams.get("createSuccess") ? "created" : "updated"}`);
|
setSuccessMessage(`${tableMetaData.label} successfully ${searchParams.get("createSuccess") ? "created" : "updated"}`);
|
||||||
}
|
}
|
||||||
|
if (searchParams.get("warning"))
|
||||||
forceUpdate();
|
{
|
||||||
|
setWarningMessage(searchParams.get("warning"));
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,6 +458,13 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
|||||||
})();
|
})();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function handleRevealIconClick(fieldName: string)
|
||||||
|
{
|
||||||
|
adornmentFieldsMap.set(fieldName, !adornmentFieldsMap.get(fieldName));
|
||||||
|
setAdornmentFieldsMap(adornmentFieldsMap);
|
||||||
|
setReloadCounter(reloadCounter + 1);
|
||||||
|
}
|
||||||
|
|
||||||
function processClicked(process: QProcessMetaData)
|
function processClicked(process: QProcessMetaData)
|
||||||
{
|
{
|
||||||
openModalProcess(process);
|
openModalProcess(process);
|
||||||
@ -646,6 +656,16 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
|||||||
</Alert>
|
</Alert>
|
||||||
: ("")
|
: ("")
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
warningMessage ?
|
||||||
|
<Alert color="warning" sx={{mb: 3}} onClose={() =>
|
||||||
|
{
|
||||||
|
setWarningMessage(null);
|
||||||
|
}}>
|
||||||
|
{warningMessage}
|
||||||
|
</Alert>
|
||||||
|
: ("")
|
||||||
|
}
|
||||||
|
|
||||||
<Grid container spacing={3}>
|
<Grid container spacing={3}>
|
||||||
<Grid item xs={12} lg={3}>
|
<Grid item xs={12} lg={3}>
|
||||||
|
@ -386,3 +386,9 @@ input[type="search"]::-webkit-search-results-decoration { display: none; }
|
|||||||
{
|
{
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.MuiGrid-root > .MuiBox-root > .material-icons-round,
|
||||||
|
.MuiBox-root > .MuiBox-root > .material-icons-round
|
||||||
|
{
|
||||||
|
font-size: 2rem !important;
|
||||||
|
}
|
||||||
|
@ -25,10 +25,11 @@ import {QFieldType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QField
|
|||||||
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
||||||
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||||
import "datejs"; // https://github.com/datejs/Datejs
|
import "datejs"; // https://github.com/datejs/Datejs
|
||||||
import {Box, Chip, Icon} from "@mui/material";
|
import {Box, Chip, ClickAwayListener, Icon} from "@mui/material";
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
|
import Tooltip from "@mui/material/Tooltip";
|
||||||
import parse from "html-react-parser";
|
import parse from "html-react-parser";
|
||||||
import React, {Fragment, useState} from "react";
|
import React, {Fragment, useReducer, useState} from "react";
|
||||||
import AceEditor from "react-ace";
|
import AceEditor from "react-ace";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import Client from "qqq/utils/qqq/Client";
|
import Client from "qqq/utils/qqq/Client";
|
||||||
@ -77,6 +78,7 @@ class ValueUtils
|
|||||||
return ValueUtils.getValueForDisplay(field, rawValue, displayValue, usage);
|
return ValueUtils.getValueForDisplay(field, rawValue, displayValue, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** When you have a field and a value (either just a raw value, or a raw and
|
** When you have a field and a value (either just a raw value, or a raw and
|
||||||
** display value), call this method to get a string Element to display.
|
** display value), call this method to get a string Element to display.
|
||||||
@ -130,6 +132,11 @@ class ValueUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (field.hasAdornment(AdornmentType.REVEAL))
|
||||||
|
{
|
||||||
|
return (<RevealComponent fieldName={field.name} value={displayValue} usage={usage} />);
|
||||||
|
}
|
||||||
|
|
||||||
if (field.hasAdornment(AdornmentType.RENDER_HTML))
|
if (field.hasAdornment(AdornmentType.RENDER_HTML))
|
||||||
{
|
{
|
||||||
return (rawValue ? parse(rawValue) : "");
|
return (rawValue ? parse(rawValue) : "");
|
||||||
@ -468,6 +475,68 @@ function CodeViewer({name, mode, code}: {name: string; mode: string; code: strin
|
|||||||
</>);
|
</>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// little private component here, for rendering an AceEditor with some buttons/controls/state //
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
function RevealComponent({fieldName, value, usage}: {fieldName: string, value: string, usage: string;}): JSX.Element
|
||||||
|
{
|
||||||
|
const [adornmentFieldsMap, setAdornmentFieldsMap] = useState(new Map<string, boolean>);
|
||||||
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
||||||
|
const [tooltipOpen, setToolTipOpen] = useState(false);
|
||||||
|
const [displayValue, setDisplayValue] = useState(value.replace(/./g, "*"));
|
||||||
|
|
||||||
|
const handleTooltipClose = () =>
|
||||||
|
{
|
||||||
|
setToolTipOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTooltipOpen = () =>
|
||||||
|
{
|
||||||
|
setToolTipOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRevealIconClick = (fieldName: string) =>
|
||||||
|
{
|
||||||
|
const displayValue = (adornmentFieldsMap.get(fieldName)) ? value.replace(/./g, "*") : value;
|
||||||
|
setDisplayValue(displayValue);
|
||||||
|
adornmentFieldsMap.set(fieldName, !adornmentFieldsMap.get(fieldName));
|
||||||
|
setAdornmentFieldsMap(adornmentFieldsMap);
|
||||||
|
forceUpdate();
|
||||||
|
};
|
||||||
|
|
||||||
|
const copyToClipboard = (value: string) =>
|
||||||
|
{
|
||||||
|
navigator.clipboard.writeText(value);
|
||||||
|
setToolTipOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
usage === "view" && adornmentFieldsMap.get(fieldName) === true ? (
|
||||||
|
<Box>
|
||||||
|
<Icon onClick={() => handleRevealIconClick(fieldName)} sx={{cursor: "pointer", fontSize: "15px !important", position: "relative", top: "3px", marginRight: "5px"}}>visibility_on</Icon>
|
||||||
|
{displayValue}
|
||||||
|
<ClickAwayListener onClickAway={handleTooltipClose}>
|
||||||
|
<Tooltip
|
||||||
|
PopperProps={{
|
||||||
|
disablePortal: true,
|
||||||
|
}}
|
||||||
|
onClose={handleTooltipClose}
|
||||||
|
open={tooltipOpen}
|
||||||
|
disableFocusListener
|
||||||
|
disableHoverListener
|
||||||
|
disableTouchListener
|
||||||
|
title="Copied To Clipboard"
|
||||||
|
>
|
||||||
|
<Icon onClick={() => copyToClipboard(value)} sx={{cursor: "pointer", fontSize: "15px !important", position: "relative", top: "3px", marginLeft: "5px"}}>copy</Icon>
|
||||||
|
</Tooltip>
|
||||||
|
</ClickAwayListener>
|
||||||
|
</Box>
|
||||||
|
):(
|
||||||
|
<Box><Icon onClick={() => handleRevealIconClick(fieldName)} sx={{cursor: "pointer", fontSize: "15px !important", position: "relative", top: "3px", marginRight: "5px"}}>visibility_off</Icon>{displayValue}</Box>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default ValueUtils;
|
export default ValueUtils;
|
||||||
|
Reference in New Issue
Block a user