mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 05:10:45 +00:00
Adding generic run records process
This commit is contained in:
19
src/App.tsx
19
src/App.tsx
@ -332,6 +332,25 @@ export default function App()
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const runRecordScriptProcess = metaData.processes.get("runRecordScript")
|
||||||
|
if(runRecordScriptProcess)
|
||||||
|
{
|
||||||
|
const process = runRecordScriptProcess;
|
||||||
|
routeList.push({
|
||||||
|
name: process.label,
|
||||||
|
key: process.name,
|
||||||
|
route: `${path}/${process.name}`,
|
||||||
|
component: <RecordQuery table={table} launchProcess={process} />,
|
||||||
|
});
|
||||||
|
|
||||||
|
routeList.push({
|
||||||
|
name: process.label,
|
||||||
|
key: `${app.name}/${process.name}`,
|
||||||
|
route: `${path}/:id/${process.name}`,
|
||||||
|
component: <RecordView table={table} launchProcess={process} />,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const reportsForTable = ProcessUtils.getReportsForTable(metaData, table.name, true);
|
const reportsForTable = ProcessUtils.getReportsForTable(metaData, table.name, true);
|
||||||
reportsForTable.forEach((report) =>
|
reportsForTable.forEach((report) =>
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,7 @@ import {QFrontendComponent} from "@kingsrook/qqq-frontend-core/lib/model/metaDat
|
|||||||
import {QFrontendStepMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFrontendStepMetaData";
|
import {QFrontendStepMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QFrontendStepMetaData";
|
||||||
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
import {QInstance} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QInstance";
|
||||||
import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
|
import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QProcessMetaData";
|
||||||
|
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 {QJobComplete} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobComplete";
|
import {QJobComplete} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobComplete";
|
||||||
import {QJobError} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobError";
|
import {QJobError} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobError";
|
||||||
@ -68,6 +69,7 @@ import ValueUtils from "qqq/utils/qqq/ValueUtils";
|
|||||||
interface Props
|
interface Props
|
||||||
{
|
{
|
||||||
process?: QProcessMetaData;
|
process?: QProcessMetaData;
|
||||||
|
table?: QTableMetaData;
|
||||||
defaultProcessValues?: any;
|
defaultProcessValues?: any;
|
||||||
isModal?: boolean;
|
isModal?: boolean;
|
||||||
isWidget?: boolean;
|
isWidget?: boolean;
|
||||||
@ -82,7 +84,7 @@ const INITIAL_RETRY_MILLIS = 1_500;
|
|||||||
const RETRY_MAX_MILLIS = 12_000;
|
const RETRY_MAX_MILLIS = 12_000;
|
||||||
const BACKOFF_AMOUNT = 1.5;
|
const BACKOFF_AMOUNT = 1.5;
|
||||||
|
|
||||||
function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport, recordIds, closeModalHandler, forceReInit, overrideLabel}: Props): JSX.Element
|
function ProcessRun({process, table, defaultProcessValues, isModal, isWidget, isReport, recordIds, closeModalHandler, forceReInit, overrideLabel}: Props): JSX.Element
|
||||||
{
|
{
|
||||||
const processNameParam = useParams().processName;
|
const processNameParam = useParams().processName;
|
||||||
const processName = process === null ? processNameParam : process.name;
|
const processName = process === null ? processNameParam : process.name;
|
||||||
@ -102,7 +104,7 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport,
|
|||||||
const [needInitialLoad, setNeedInitialLoad] = useState(true);
|
const [needInitialLoad, setNeedInitialLoad] = useState(true);
|
||||||
const [lastForcedReInit, setLastForcedReInit] = useState(null as number);
|
const [lastForcedReInit, setLastForcedReInit] = useState(null as number);
|
||||||
const [processMetaData, setProcessMetaData] = useState(null);
|
const [processMetaData, setProcessMetaData] = useState(null);
|
||||||
const [tableMetaData, setTableMetaData] = useState(null);
|
const [tableMetaData, setTableMetaData] = useState(table);
|
||||||
const [tableSections, setTableSections] = useState(null as QTableSection[]);
|
const [tableSections, setTableSections] = useState(null as QTableSection[]);
|
||||||
const [qInstance, setQInstance] = useState(null as QInstance);
|
const [qInstance, setQInstance] = useState(null as QInstance);
|
||||||
const [processValues, setProcessValues] = useState({} as any);
|
const [processValues, setProcessValues] = useState({} as any);
|
||||||
@ -728,7 +730,17 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport,
|
|||||||
const formData = DynamicFormUtils.getFormData(fullFieldList);
|
const formData = DynamicFormUtils.getFormData(fullFieldList);
|
||||||
|
|
||||||
const possibleValueDisplayValues = new Map<string, string>();
|
const possibleValueDisplayValues = new Map<string, string>();
|
||||||
DynamicFormUtils.addPossibleValueProps(formData.dynamicFormFields, fullFieldList, tableMetaData?.name, processName, possibleValueDisplayValues);
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ok - so - the addPossibleValueProps method wants to take either a tableName or a processName //
|
||||||
|
// param - if it gets a tableName, then it'll point the PVS to the table - which is what we want //
|
||||||
|
// (at this time, at least) only for the BULK_EDIT process (expected to change in future...) //
|
||||||
|
// so, only pass a tableName into that method if this looks like a bulk edit (based on that component... //
|
||||||
|
// else, pass a processName and no table name. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
const tableNameForPVProps = doesStepHaveComponent(activeStep, QComponentType.BULK_EDIT_FORM) ? tableMetaData.name : null;
|
||||||
|
const processNameForPVProps = tableNameForPVProps ? null : processName;
|
||||||
|
DynamicFormUtils.addPossibleValueProps(formData.dynamicFormFields, fullFieldList, tableNameForPVProps, processNameForPVProps, possibleValueDisplayValues);
|
||||||
|
|
||||||
dynamicFormFields = formData.dynamicFormFields;
|
dynamicFormFields = formData.dynamicFormFields;
|
||||||
formValidations = formData.formValidations;
|
formValidations = formData.formValidations;
|
||||||
@ -764,6 +776,12 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport,
|
|||||||
formValidations[fieldName] = validation;
|
formValidations[fieldName] = validation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if(tableMetaData)
|
||||||
|
{
|
||||||
|
console.log("Adding table name field... ?", tableMetaData.name);
|
||||||
|
addField("tableName", {type: "hidden", omitFromQDynamicForm: true}, tableMetaData.name, null);
|
||||||
|
}
|
||||||
|
|
||||||
if (doesStepHaveComponent(activeStep, QComponentType.VALIDATION_REVIEW_SCREEN))
|
if (doesStepHaveComponent(activeStep, QComponentType.VALIDATION_REVIEW_SCREEN))
|
||||||
{
|
{
|
||||||
addField("doFullValidation", {type: "radio"}, "true", null);
|
addField("doFullValidation", {type: "radio"}, "true", null);
|
||||||
@ -1072,7 +1090,7 @@ function ProcessRun({process, defaultProcessValues, isModal, isWidget, isReport,
|
|||||||
const processMetaData = await Client.getInstance().loadProcessMetaData(processName);
|
const processMetaData = await Client.getInstance().loadProcessMetaData(processName);
|
||||||
setProcessMetaData(processMetaData);
|
setProcessMetaData(processMetaData);
|
||||||
setSteps(processMetaData.frontendSteps);
|
setSteps(processMetaData.frontendSteps);
|
||||||
if (processMetaData.tableName)
|
if (processMetaData.tableName && !tableMetaData)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -202,12 +202,20 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
if (pathParts[pathParts.length - 2] === tableName)
|
if (pathParts[pathParts.length - 2] === tableName)
|
||||||
{
|
{
|
||||||
const processName = pathParts[pathParts.length - 1];
|
const processName = pathParts[pathParts.length - 1];
|
||||||
const processList = allTableProcesses.filter(p => p.name.endsWith(processName));
|
const processList = allTableProcesses.filter(p => p.name == processName);
|
||||||
if (processList.length > 0)
|
if (processList.length > 0)
|
||||||
{
|
{
|
||||||
setActiveModalProcess(processList[0]);
|
setActiveModalProcess(processList[0]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if(metaData?.processes.has(processName))
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// check for generic processes - should this be a specific attribute on the process? //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
setActiveModalProcess(metaData?.processes.get(processName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
console.log(`Couldn't find process named ${processName}`);
|
console.log(`Couldn't find process named ${processName}`);
|
||||||
@ -1127,6 +1135,53 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const runRecordScriptProcess = metaData?.processes.get("runRecordScript");
|
||||||
|
|
||||||
|
const pushDividerIfNeeded = (menuItems: JSX.Element[]) =>
|
||||||
|
{
|
||||||
|
console.log("Type: " + menuItems[menuItems.length - 1]);
|
||||||
|
if(menuItems.length > 0)
|
||||||
|
{
|
||||||
|
menuItems.push(<Divider />);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const menuItems: JSX.Element[] = [];
|
||||||
|
if(table.capabilities.has(Capability.TABLE_INSERT) && table.insertPermission)
|
||||||
|
{
|
||||||
|
menuItems.push(<MenuItem onClick={bulkLoadClicked}><ListItemIcon><Icon>library_add</Icon></ListItemIcon>Bulk Load</MenuItem>)
|
||||||
|
}
|
||||||
|
if(table.capabilities.has(Capability.TABLE_UPDATE) && table.editPermission)
|
||||||
|
{
|
||||||
|
menuItems.push(<MenuItem onClick={bulkEditClicked}><ListItemIcon><Icon>edit</Icon></ListItemIcon>Bulk Edit</MenuItem>)
|
||||||
|
}
|
||||||
|
if(table.capabilities.has(Capability.TABLE_DELETE) && table.deletePermission)
|
||||||
|
{
|
||||||
|
menuItems.push(<MenuItem onClick={bulkDeleteClicked}><ListItemIcon><Icon>delete</Icon></ListItemIcon>Bulk Delete</MenuItem>)
|
||||||
|
}
|
||||||
|
|
||||||
|
const runRecordScriptProcess = metaData?.processes.get("runRecordScript");
|
||||||
|
if(runRecordScriptProcess)
|
||||||
|
{
|
||||||
|
const process = runRecordScriptProcess;
|
||||||
|
menuItems.push(<MenuItem key={process.name} onClick={() => processClicked(process)}><ListItemIcon><Icon>{process.iconName ?? "arrow_forward"}</Icon></ListItemIcon>{process.label}</MenuItem>);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tableProcesses && tableProcesses.length)
|
||||||
|
{
|
||||||
|
pushDividerIfNeeded(menuItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
tableProcesses.map((process) =>
|
||||||
|
{
|
||||||
|
menuItems.push(<MenuItem key={process.name} onClick={() => processClicked(process)}><ListItemIcon><Icon>{process.iconName ?? "arrow_forward"}</Icon></ListItemIcon>{process.label}</MenuItem>);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(menuItems.length === 0)
|
||||||
|
{
|
||||||
|
menuItems.push(<MenuItem disabled><ListItemIcon><Icon>block</Icon></ListItemIcon><i>No actions available</i></MenuItem>)
|
||||||
|
}
|
||||||
|
|
||||||
const renderActionsMenu = (
|
const renderActionsMenu = (
|
||||||
<Menu
|
<Menu
|
||||||
anchorEl={actionsMenu}
|
anchorEl={actionsMenu}
|
||||||
@ -1142,41 +1197,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
onClose={closeActionsMenu}
|
onClose={closeActionsMenu}
|
||||||
keepMounted
|
keepMounted
|
||||||
>
|
>
|
||||||
{
|
{menuItems}
|
||||||
table.capabilities.has(Capability.TABLE_INSERT) && table.insertPermission &&
|
|
||||||
<MenuItem onClick={bulkLoadClicked}>
|
|
||||||
<ListItemIcon><Icon>library_add</Icon></ListItemIcon>
|
|
||||||
Bulk Load
|
|
||||||
</MenuItem>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
table.capabilities.has(Capability.TABLE_UPDATE) && table.editPermission &&
|
|
||||||
<MenuItem onClick={bulkEditClicked}>
|
|
||||||
<ListItemIcon><Icon>edit</Icon></ListItemIcon>
|
|
||||||
Bulk Edit
|
|
||||||
</MenuItem>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
table.capabilities.has(Capability.TABLE_DELETE) && table.deletePermission &&
|
|
||||||
<MenuItem onClick={bulkDeleteClicked}>
|
|
||||||
<ListItemIcon><Icon>delete</Icon></ListItemIcon>
|
|
||||||
Bulk Delete
|
|
||||||
</MenuItem>
|
|
||||||
}
|
|
||||||
{((table.capabilities.has(Capability.TABLE_INSERT) && table.insertPermission) || (table.capabilities.has(Capability.TABLE_UPDATE) && table.editPermission) || (table.capabilities.has(Capability.TABLE_DELETE) && table.deletePermission)) && tableProcesses.length > 0 && <Divider />}
|
|
||||||
{tableProcesses.map((process) => (
|
|
||||||
<MenuItem key={process.name} onClick={() => processClicked(process)}>
|
|
||||||
<ListItemIcon><Icon>{process.iconName ?? "arrow_forward"}</Icon></ListItemIcon>
|
|
||||||
{process.label}
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
{
|
|
||||||
tableProcesses.length == 0 && !(table.capabilities.has(Capability.TABLE_INSERT) && table.insertPermission) && !(table.capabilities.has(Capability.TABLE_UPDATE) && table.editPermission) && !(table.capabilities.has(Capability.TABLE_DELETE) && table.deletePermission) &&
|
|
||||||
<MenuItem disabled>
|
|
||||||
<ListItemIcon><Icon>block</Icon></ListItemIcon>
|
|
||||||
<i>No actions available</i>
|
|
||||||
</MenuItem>
|
|
||||||
}
|
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1326,10 +1347,10 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{
|
{
|
||||||
activeModalProcess &&
|
activeModalProcess && tableMetaData &&
|
||||||
<Modal open={activeModalProcess !== null} onClose={(event, reason) => closeModalProcess(event, reason)}>
|
<Modal open={activeModalProcess !== null} onClose={(event, reason) => closeModalProcess(event, reason)}>
|
||||||
<div className="modalProcess">
|
<div className="modalProcess">
|
||||||
<ProcessRun process={activeModalProcess} isModal={true} recordIds={recordIdsForProcess} closeModalHandler={closeModalProcess} />
|
<ProcessRun process={activeModalProcess} isModal={true} table={tableMetaData} recordIds={recordIdsForProcess} closeModalHandler={closeModalProcess} />
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user