Add Duplicate!

This commit is contained in:
2023-06-21 12:14:39 -05:00
parent 22caabb952
commit 45063ac416
3 changed files with 73 additions and 30 deletions

View File

@ -54,6 +54,7 @@ interface Props
closeModalHandler?: (event: object, reason: string) => void;
defaultValues: { [key: string]: string };
disabledFields: { [key: string]: boolean } | string[];
isDuplicate?: boolean;
}
EntityForm.defaultProps = {
@ -63,6 +64,7 @@ EntityForm.defaultProps = {
closeModalHandler: null,
defaultValues: {},
disabledFields: {},
isDuplicate: false
};
function EntityForm(props: Props): JSX.Element
@ -173,24 +175,30 @@ function EntityForm(props: Props): JSX.Element
fieldArray.push(fieldMetaData);
});
/////////////////////////////////////////////////////////////////////////////////
// if doing an edit, fetch the record and pre-populate the form values from it //
/////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
// if doing an edit or duplicate, 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)
{
record = await qController.get(tableName, props.id);
setRecord(record);
setFormTitle(`Edit ${tableMetaData?.label}: ${record?.recordLabel}`);
const titleVerb = props.isDuplicate ? "Duplicate" : "Edit";
setFormTitle(`${titleVerb} ${tableMetaData?.label}: ${record?.recordLabel}`);
if (!props.isModal)
{
setPageHeader(`Edit ${tableMetaData?.label}: ${record?.recordLabel}`);
setPageHeader(`${titleVerb} ${tableMetaData?.label}: ${record?.recordLabel}`);
}
tableMetaData.fields.forEach((fieldMetaData, key) =>
{
if (props.isDuplicate && fieldMetaData.name == tableMetaData.primaryKeyField)
{
return;
}
initialValues[key] = record.values.get(key);
});
@ -215,15 +223,6 @@ function EntityForm(props: Props): JSX.Element
setPageHeader(`Creating New ${tableMetaData?.label}`);
}
if (!tableMetaData.capabilities.has(Capability.TABLE_INSERT))
{
setNotAllowedError("Records may not be created in this table");
}
else if (!tableMetaData.insertPermission)
{
setNotAllowedError(`You do not have permission to create ${tableMetaData.label} records`);
}
////////////////////////////////////////////////////////////////////////////////////////////////
// if default values were supplied for a new record, then populate initialValues, for formik. //
////////////////////////////////////////////////////////////////////////////////////////////////
@ -254,6 +253,32 @@ function EntityForm(props: Props): JSX.Element
}
}
//////////////////////////////////////
// check capabilities & permissions //
//////////////////////////////////////
if (props.isDuplicate || !props.id)
{
if (!tableMetaData.capabilities.has(Capability.TABLE_INSERT))
{
setNotAllowedError("Records may not be created in this table");
}
else if (!tableMetaData.insertPermission)
{
setNotAllowedError(`You do not have permission to create ${tableMetaData.label} records`);
}
}
else
{
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`);
}
}
/////////////////////////////////////////////////////////////////////
// make sure all initialValues are properly formatted for the form //
/////////////////////////////////////////////////////////////////////
@ -316,11 +341,11 @@ function EntityForm(props: Props): JSX.Element
const fieldName = section.fieldNames[j];
const field = tableMetaData.fields.get(fieldName);
////////////////////////////////////////////////////////////////////////////////////////////
// if id !== null - means we're on the edit screen -- show all fields on the edit screen. //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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 || field.isEditable)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if ((props.id !== null && !props.isDuplicate) || field.isEditable)
{
sectionDynamicFormFields.push(dynamicFormFields[fieldName]);
}
@ -368,7 +393,12 @@ 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)
if (props.id !== null && props.isDuplicate)
{
const path = `${location.pathname.replace(/\/duplicate$/, "")}`;
navigate(path, {replace: true});
}
else if (props.id !== null)
{
const path = `${location.pathname.replace(/\/edit$/, "")}`;
navigate(path, {replace: true});
@ -428,8 +458,9 @@ function EntityForm(props: Props): JSX.Element
}
}
if (props.id !== null)
if (props.id !== null && !props.isDuplicate)
{
// todo - audit that it's a dupe
await qController
.update(tableName, props.id, values)
.then((record) =>
@ -473,7 +504,9 @@ function EntityForm(props: Props): JSX.Element
}
else
{
const path = location.pathname.replace(/create$/, record.values.get(tableMetaData.primaryKeyField));
const path = props.isDuplicate ?
location.pathname.replace(new RegExp(`/${props.id}/duplicate$`), "/" + record.values.get(tableMetaData.primaryKeyField))
: location.pathname.replace(/create$/, record.values.get(tableMetaData.primaryKeyField));
navigate(path, {state: {createSuccess: true}});
}
})
@ -481,8 +514,9 @@ function EntityForm(props: Props): JSX.Element
{
if(error.message.toLowerCase().startsWith("warning"))
{
const path = location.pathname.replace(/create$/, record.values.get(tableMetaData.primaryKeyField));
navigate(path);
const path = props.isDuplicate ?
location.pathname.replace(new RegExp(`/${props.id}/duplicate$`), "/" + record.values.get(tableMetaData.primaryKeyField))
: location.pathname.replace(/create$/, record.values.get(tableMetaData.primaryKeyField));
navigate(path, {state: {createSuccess: true, warning: error.message}});
}
else

View File

@ -29,9 +29,15 @@ import BaseLayout from "qqq/layouts/BaseLayout";
interface Props
{
table?: QTableMetaData;
isDuplicate?: boolean
}
function EntityEdit({table}: Props): JSX.Element
EntityEdit.defaultProps = {
table: null,
isDuplicate: false
};
function EntityEdit({table, isDuplicate}: Props): JSX.Element
{
const {id} = useParams();
@ -43,7 +49,7 @@ function EntityEdit({table}: Props): JSX.Element
<Box mb={3}>
<Grid container spacing={3}>
<Grid item xs={12}>
<EntityForm table={table} id={id} />
<EntityForm table={table} id={id} isDuplicate={isDuplicate} />
</Grid>
</Grid>
</Box>
@ -54,8 +60,4 @@ function EntityEdit({table}: Props): JSX.Element
);
}
EntityEdit.defaultProps = {
table: null,
};
export default EntityEdit;

View File

@ -534,6 +534,13 @@ function RecordView({table, launchProcess}: Props): JSX.Element
Create New
</MenuItem>
}
{
table.capabilities.has(Capability.TABLE_INSERT) && table.insertPermission &&
<MenuItem onClick={() => navigate("duplicate")}>
<ListItemIcon><Icon>copy</Icon></ListItemIcon>
Create Duplicate
</MenuItem>
}
{
table.capabilities.has(Capability.TABLE_UPDATE) && table.editPermission &&
<MenuItem onClick={() => navigate("edit")}>