mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 13:20:43 +00:00
CTLE-214: initial checkin of 'dot menu'
This commit is contained in:
@ -23,9 +23,8 @@ import {InputAdornment, InputLabel} from "@mui/material";
|
||||
import Box from "@mui/material/Box";
|
||||
import Switch from "@mui/material/Switch";
|
||||
import {ErrorMessage, Field, useFormikContext} from "formik";
|
||||
import React, {useContext, useState} from "react";
|
||||
import React, {useState} from "react";
|
||||
import AceEditor from "react-ace";
|
||||
import QContext from "QContext";
|
||||
import BooleanFieldSwitch from "qqq/components/forms/BooleanFieldSwitch";
|
||||
import MDInput from "qqq/components/legacy/MDInput";
|
||||
import MDTypography from "qqq/components/legacy/MDTypography";
|
||||
@ -53,7 +52,6 @@ function QDynamicFormField({
|
||||
{
|
||||
const [switchChecked, setSwitchChecked] = useState(false);
|
||||
const [isDisabled, setIsDisabled] = useState(!isEditable || bulkEditMode);
|
||||
const {setAllowShortcuts} = useContext(QContext);
|
||||
|
||||
const {setFieldValue} = useFormikContext();
|
||||
|
||||
@ -127,14 +125,6 @@ function QDynamicFormField({
|
||||
field = (
|
||||
<>
|
||||
<Field {...rest} onWheel={handleOnWheel} name={name} type={type} as={MDInput} variant="standard" label={label} InputLabelProps={inputLabelProps} InputProps={inputProps} fullWidth disabled={isDisabled}
|
||||
onBlur={(e: any) =>
|
||||
{
|
||||
setAllowShortcuts(true);
|
||||
}}
|
||||
onFocus={(e: any) =>
|
||||
{
|
||||
setAllowShortcuts(false);
|
||||
}}
|
||||
onKeyPress={(e: any) =>
|
||||
{
|
||||
if (e.key === "Enter")
|
||||
|
@ -22,8 +22,6 @@
|
||||
import {AdornmentType} from "@kingsrook/qqq-frontend-core/lib/model/metaData/AdornmentType";
|
||||
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
||||
import {QPossibleValue} from "@kingsrook/qqq-frontend-core/lib/model/QPossibleValue";
|
||||
import CheckBoxIcon from "@mui/icons-material/CheckBox";
|
||||
import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank";
|
||||
import {Checkbox, Chip, CircularProgress, FilterOptionsState, Icon} from "@mui/material";
|
||||
import Autocomplete from "@mui/material/Autocomplete";
|
||||
import Box from "@mui/material/Box";
|
||||
|
@ -26,8 +26,9 @@ import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QT
|
||||
import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableSection";
|
||||
import {QPossibleValue} from "@kingsrook/qqq-frontend-core/lib/model/QPossibleValue";
|
||||
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||
import {Alert, Box} from "@mui/material";
|
||||
import {Alert} from "@mui/material";
|
||||
import Avatar from "@mui/material/Avatar";
|
||||
import Box from "@mui/material/Box";
|
||||
import Card from "@mui/material/Card";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import Icon from "@mui/material/Icon";
|
||||
@ -54,7 +55,7 @@ interface Props
|
||||
closeModalHandler?: (event: object, reason: string) => void;
|
||||
defaultValues: { [key: string]: string };
|
||||
disabledFields: { [key: string]: boolean } | string[];
|
||||
isDuplicate?: boolean;
|
||||
isCopy?: boolean;
|
||||
}
|
||||
|
||||
EntityForm.defaultProps = {
|
||||
@ -64,7 +65,7 @@ EntityForm.defaultProps = {
|
||||
closeModalHandler: null,
|
||||
defaultValues: {},
|
||||
disabledFields: {},
|
||||
isDuplicate: false
|
||||
isCopy: false
|
||||
};
|
||||
|
||||
function EntityForm(props: Props): JSX.Element
|
||||
@ -175,9 +176,9 @@ function EntityForm(props: Props): JSX.Element
|
||||
fieldArray.push(fieldMetaData);
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if doing an edit or duplicate, fetch the record and pre-populate the form values from it //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if doing an edit or copy, fetch the record and pre-populate the form values from it //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
let record: QRecord = null;
|
||||
let defaultDisplayValues = new Map<string, string>();
|
||||
if (props.id !== null)
|
||||
@ -185,7 +186,7 @@ function EntityForm(props: Props): JSX.Element
|
||||
record = await qController.get(tableName, props.id);
|
||||
setRecord(record);
|
||||
|
||||
const titleVerb = props.isDuplicate ? "Duplicate" : "Edit";
|
||||
const titleVerb = props.isCopy ? "Copy" : "Edit";
|
||||
setFormTitle(`${titleVerb} ${tableMetaData?.label}: ${record?.recordLabel}`);
|
||||
|
||||
if (!props.isModal)
|
||||
@ -195,20 +196,26 @@ function EntityForm(props: Props): JSX.Element
|
||||
|
||||
tableMetaData.fields.forEach((fieldMetaData, key) =>
|
||||
{
|
||||
if (props.isDuplicate && fieldMetaData.name == tableMetaData.primaryKeyField)
|
||||
if (props.isCopy && fieldMetaData.name == tableMetaData.primaryKeyField)
|
||||
{
|
||||
return;
|
||||
}
|
||||
initialValues[key] = record.values.get(key);
|
||||
});
|
||||
|
||||
if (!tableMetaData.capabilities.has(Capability.TABLE_UPDATE))
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// these checks are only for updating records, if copying, it is actually an insert, which is checked after this block //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(! props.isCopy)
|
||||
{
|
||||
setNotAllowedError("Records may not be edited in this table");
|
||||
}
|
||||
else if (!tableMetaData.editPermission)
|
||||
{
|
||||
setNotAllowedError(`You do not have permission to edit ${tableMetaData.label} records`);
|
||||
if (!tableMetaData.capabilities.has(Capability.TABLE_UPDATE))
|
||||
{
|
||||
setNotAllowedError("Records may not be edited in this table");
|
||||
}
|
||||
else if (!tableMetaData.editPermission)
|
||||
{
|
||||
setNotAllowedError(`You do not have permission to edit ${tableMetaData.label} records`);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -256,7 +263,7 @@ function EntityForm(props: Props): JSX.Element
|
||||
//////////////////////////////////////
|
||||
// check capabilities & permissions //
|
||||
//////////////////////////////////////
|
||||
if (props.isDuplicate || !props.id)
|
||||
if (props.isCopy || !props.id)
|
||||
{
|
||||
if (!tableMetaData.capabilities.has(Capability.TABLE_INSERT))
|
||||
{
|
||||
@ -341,11 +348,11 @@ function EntityForm(props: Props): JSX.Element
|
||||
const fieldName = section.fieldNames[j];
|
||||
const field = tableMetaData.fields.get(fieldName);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if id !== null (and we're not duplicating) - means we're on the edit screen -- show all fields on the edit screen. //
|
||||
// || (or) we're on the insert screen in which case, only show editable fields. //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if ((props.id !== null && !props.isDuplicate) || field.isEditable)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if id !== null (and we're not copying) - means we're on the edit screen -- show all fields on the edit screen. //
|
||||
// || (or) we're on the insert screen in which case, only show editable fields. //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if ((props.id !== null && !props.isCopy) || field.isEditable)
|
||||
{
|
||||
sectionDynamicFormFields.push(dynamicFormFields[fieldName]);
|
||||
}
|
||||
@ -393,9 +400,9 @@ function EntityForm(props: Props): JSX.Element
|
||||
// but if the user used the anchors on the page, this doesn't effectively cancel... //
|
||||
// what we have here pushed a new history entry (I think?), so could be better //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
if (props.id !== null && props.isDuplicate)
|
||||
if (props.id !== null && props.isCopy)
|
||||
{
|
||||
const path = `${location.pathname.replace(/\/duplicate$/, "")}`;
|
||||
const path = `${location.pathname.replace(/\/copy$/, "")}`;
|
||||
navigate(path, {replace: true});
|
||||
}
|
||||
else if (props.id !== null)
|
||||
@ -458,7 +465,7 @@ function EntityForm(props: Props): JSX.Element
|
||||
}
|
||||
}
|
||||
|
||||
if (props.id !== null && !props.isDuplicate)
|
||||
if (props.id !== null && !props.isCopy)
|
||||
{
|
||||
// todo - audit that it's a dupe
|
||||
await qController
|
||||
@ -504,8 +511,8 @@ function EntityForm(props: Props): JSX.Element
|
||||
}
|
||||
else
|
||||
{
|
||||
const path = props.isDuplicate ?
|
||||
location.pathname.replace(new RegExp(`/${props.id}/duplicate$`), "/" + record.values.get(tableMetaData.primaryKeyField))
|
||||
const path = props.isCopy ?
|
||||
location.pathname.replace(new RegExp(`/${props.id}/copy$`), "/" + record.values.get(tableMetaData.primaryKeyField))
|
||||
: location.pathname.replace(/create$/, record.values.get(tableMetaData.primaryKeyField));
|
||||
navigate(path, {state: {createSuccess: true}});
|
||||
}
|
||||
@ -514,8 +521,8 @@ function EntityForm(props: Props): JSX.Element
|
||||
{
|
||||
if(error.message.toLowerCase().startsWith("warning"))
|
||||
{
|
||||
const path = props.isDuplicate ?
|
||||
location.pathname.replace(new RegExp(`/${props.id}/duplicate$`), "/" + record.values.get(tableMetaData.primaryKeyField))
|
||||
const path = props.isCopy ?
|
||||
location.pathname.replace(new RegExp(`/${props.id}/copy$`), "/" + record.values.get(tableMetaData.primaryKeyField))
|
||||
: location.pathname.replace(/create$/, record.values.get(tableMetaData.primaryKeyField));
|
||||
navigate(path, {state: {createSuccess: true, warning: error.message}});
|
||||
}
|
||||
|
@ -30,9 +30,8 @@ import ListItemIcon from "@mui/material/ListItemIcon";
|
||||
import Menu from "@mui/material/Menu";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Toolbar from "@mui/material/Toolbar";
|
||||
import React, {useContext, useEffect, useState} from "react";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {useLocation, useNavigate} from "react-router-dom";
|
||||
import QContext from "QContext";
|
||||
import QBreadcrumbs, {routeToLabel} from "qqq/components/horseshoe/Breadcrumbs";
|
||||
import {navbar, navbarContainer, navbarIconButton, navbarRow,} from "qqq/components/horseshoe/Styles";
|
||||
import {setTransparentNavbar, useMaterialUIController,} from "qqq/context";
|
||||
@ -63,7 +62,6 @@ function NavBar({absolute, light, isMini}: Props): JSX.Element
|
||||
const [autocompleteValue, setAutocompleteValue] = useState<any>(null);
|
||||
const route = useLocation().pathname.split("/").slice(1);
|
||||
const navigate = useNavigate();
|
||||
const {setAllowShortcuts} = useContext(QContext);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
@ -122,15 +120,9 @@ function NavBar({absolute, light, isMini}: Props): JSX.Element
|
||||
|
||||
function handleHistoryOnOpen()
|
||||
{
|
||||
setAllowShortcuts(false);
|
||||
buildHistoryEntries();
|
||||
}
|
||||
|
||||
function handleHistoryOnClose()
|
||||
{
|
||||
setAllowShortcuts(true);
|
||||
}
|
||||
|
||||
const handleOpenMenu = (event: any) => setOpenMenu(event.currentTarget);
|
||||
const handleCloseMenu = () => setOpenMenu(false);
|
||||
|
||||
@ -165,7 +157,6 @@ function NavBar({absolute, light, isMini}: Props): JSX.Element
|
||||
blurOnSelect
|
||||
style={{width: "200px"}}
|
||||
onOpen={handleHistoryOnOpen}
|
||||
onClose={handleHistoryOnClose}
|
||||
onChange={handleAutocompleteOnChange}
|
||||
PopperComponent={CustomPopper}
|
||||
isOptionEqualToValue={(option, value) => option.id === value.id}
|
||||
|
Reference in New Issue
Block a user